| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 // TODO: Need to deal with NPAPI's NPSavedData. | |
| 6 // I haven't seen plugins use it yet. | |
| 7 | |
| 8 #ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__ | |
| 9 #define WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__ | |
| 10 | |
| 11 #include <map> | |
| 12 #include <stack> | |
| 13 #include <string> | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "base/basictypes.h" | |
| 17 #include "base/file_path.h" | |
| 18 #include "base/ref_counted.h" | |
| 19 #include "base/scoped_ptr.h" | |
| 20 #include "gfx/native_widget_types.h" | |
| 21 #include "gfx/point.h" | |
| 22 #include "gfx/rect.h" | |
| 23 #include "googleurl/src/gurl.h" | |
| 24 #include "third_party/npapi/bindings/npapi.h" | |
| 25 #include "third_party/npapi/bindings/nphostapi.h" | |
| 26 | |
| 27 class MessageLoop; | |
| 28 | |
| 29 namespace webkit_glue { | |
| 30 class WebPlugin; | |
| 31 class WebPluginResourceClient; | |
| 32 } | |
| 33 | |
| 34 namespace NPAPI | |
| 35 { | |
| 36 class PluginLib; | |
| 37 class PluginHost; | |
| 38 class PluginStream; | |
| 39 class PluginStreamUrl; | |
| 40 class PluginDataStream; | |
| 41 #if defined(OS_MACOSX) | |
| 42 class ScopedCurrentPluginEvent; | |
| 43 #endif | |
| 44 | |
| 45 // A PluginInstance is an active, running instance of a Plugin. | |
| 46 // A single plugin may have many PluginInstances. | |
| 47 class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { | |
| 48 public: | |
| 49 // Create a new instance of a plugin. The PluginInstance | |
| 50 // will hold a reference to the plugin. | |
| 51 PluginInstance(PluginLib *plugin, const std::string &mime_type); | |
| 52 | |
| 53 // Activates the instance by calling NPP_New. | |
| 54 // This should be called after our instance is all | |
| 55 // setup from the host side and we are ready to receive | |
| 56 // requests from the plugin. We must not call any | |
| 57 // functions on the plugin instance until start has | |
| 58 // been called. | |
| 59 // | |
| 60 // url: The instance URL. | |
| 61 // param_names: the list of names of attributes passed via the | |
| 62 // element. | |
| 63 // param_values: the list of values corresponding to param_names | |
| 64 // param_count: number of attributes | |
| 65 // load_manually: if true indicates that the plugin data would be passed | |
| 66 // from webkit. if false indicates that the plugin should | |
| 67 // download the data. | |
| 68 // This also controls whether the plugin is instantiated as | |
| 69 // a full page plugin (NP_FULL) or embedded (NP_EMBED) | |
| 70 // | |
| 71 bool Start(const GURL& url, | |
| 72 char** const param_names, | |
| 73 char** const param_values, | |
| 74 int param_count, | |
| 75 bool load_manually); | |
| 76 | |
| 77 // NPAPI's instance identifier for this instance | |
| 78 NPP npp() { return npp_; } | |
| 79 | |
| 80 // Get/Set for the instance's window handle. | |
| 81 gfx::PluginWindowHandle window_handle() const { return window_handle_; } | |
| 82 void set_window_handle(gfx::PluginWindowHandle value) { | |
| 83 window_handle_ = value; | |
| 84 } | |
| 85 | |
| 86 // Get/Set whether this instance is in Windowless mode. | |
| 87 // Default is false. | |
| 88 bool windowless() { return windowless_; } | |
| 89 void set_windowless(bool value) { windowless_ = value; } | |
| 90 | |
| 91 // Get/Set whether this instance is transparent. | |
| 92 // This only applies to windowless plugins. Transparent | |
| 93 // plugins require that webkit paint the background. | |
| 94 // Default is true. | |
| 95 bool transparent() { return transparent_; } | |
| 96 void set_transparent(bool value) { transparent_ = value; } | |
| 97 | |
| 98 // Get/Set the WebPlugin associated with this instance | |
| 99 webkit_glue::WebPlugin* webplugin() { return webplugin_; } | |
| 100 void set_web_plugin(webkit_glue::WebPlugin* webplugin) { | |
| 101 webplugin_ = webplugin; | |
| 102 } | |
| 103 | |
| 104 // Get the mimeType for this plugin stream | |
| 105 const std::string &mime_type() { return mime_type_; } | |
| 106 | |
| 107 NPAPI::PluginLib* plugin_lib() { return plugin_; } | |
| 108 | |
| 109 #if defined(OS_MACOSX) | |
| 110 // Get/Set the Mac NPAPI drawing and event models | |
| 111 NPDrawingModel drawing_model() { return drawing_model_; } | |
| 112 void set_drawing_model(NPDrawingModel value) { drawing_model_ = value; } | |
| 113 NPEventModel event_model() { return event_model_; } | |
| 114 void set_event_model(NPEventModel value) { event_model_ = value; } | |
| 115 // Updates the instance's tracking of the location of the plugin location | |
| 116 // relative to the upper left of the screen. | |
| 117 void set_plugin_origin(const gfx::Point& origin) { plugin_origin_ = origin; } | |
| 118 // Updates the instance's tracking of the frame of the containing window | |
| 119 // relative to the upper left of the screen. | |
| 120 void set_window_frame(const gfx::Rect& frame) { | |
| 121 containing_window_frame_ = frame; | |
| 122 } | |
| 123 #endif | |
| 124 | |
| 125 // Creates a stream for sending an URL. If notify_id is non-zero, it will | |
| 126 // send a notification to the plugin when the stream is complete; otherwise it | |
| 127 // will not. Set object_url to true if the load is for the object tag's url, | |
| 128 // or false if it's for a url that the plugin fetched through | |
| 129 // NPN_GetUrl[Notify]. | |
| 130 PluginStreamUrl* CreateStream(unsigned long resource_id, | |
| 131 const GURL& url, | |
| 132 const std::string& mime_type, | |
| 133 int notify_id); | |
| 134 | |
| 135 // For each instance, we track all streams. When the | |
| 136 // instance closes, all remaining streams are also | |
| 137 // closed. All streams associated with this instance | |
| 138 // should call AddStream so that they can be cleaned | |
| 139 // up when the instance shuts down. | |
| 140 void AddStream(PluginStream* stream); | |
| 141 | |
| 142 // This is called when a stream is closed. We remove the stream from the | |
| 143 // list, which releases the reference maintained to the stream. | |
| 144 void RemoveStream(PluginStream* stream); | |
| 145 | |
| 146 // Closes all open streams on this instance. | |
| 147 void CloseStreams(); | |
| 148 | |
| 149 // Returns the WebPluginResourceClient object for a stream that has become | |
| 150 // seekable. | |
| 151 webkit_glue::WebPluginResourceClient* GetRangeRequest(int id); | |
| 152 | |
| 153 // Have the plugin create it's script object. | |
| 154 NPObject *GetPluginScriptableObject(); | |
| 155 | |
| 156 // WebViewDelegate methods that we implement. This is for handling | |
| 157 // callbacks during getURLNotify. | |
| 158 void DidFinishLoadWithReason(const GURL& url, NPReason reason, int notify_id); | |
| 159 | |
| 160 // If true, send the Mozilla user agent instead of Chrome's to the plugin. | |
| 161 bool use_mozilla_user_agent() { return use_mozilla_user_agent_; } | |
| 162 void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; } | |
| 163 | |
| 164 // If the plugin instance is backed by a texture, return its ID in the | |
| 165 // compositor's namespace. Otherwise return 0. Returns 0 by default. | |
| 166 virtual unsigned GetBackingTextureId(); | |
| 167 | |
| 168 // Helper that implements NPN_PluginThreadAsyncCall semantics | |
| 169 void PluginThreadAsyncCall(void (*func)(void *), | |
| 170 void *userData); | |
| 171 | |
| 172 uint32 ScheduleTimer(uint32 interval, | |
| 173 NPBool repeat, | |
| 174 void (*func)(NPP id, uint32 timer_id)); | |
| 175 | |
| 176 void UnscheduleTimer(uint32 timer_id); | |
| 177 | |
| 178 bool ConvertPoint(double source_x, double source_y, | |
| 179 NPCoordinateSpace source_space, | |
| 180 double* dest_x, double* dest_y, | |
| 181 NPCoordinateSpace dest_space); | |
| 182 | |
| 183 NPError PopUpContextMenu(NPMenu* menu); | |
| 184 | |
| 185 // | |
| 186 // NPAPI methods for calling the Plugin Instance | |
| 187 // | |
| 188 NPError NPP_New(unsigned short, short, char *[], char *[]); | |
| 189 NPError NPP_SetWindow(NPWindow *); | |
| 190 NPError NPP_NewStream(NPMIMEType, NPStream *, NPBool, unsigned short *); | |
| 191 NPError NPP_DestroyStream(NPStream *, NPReason); | |
| 192 int NPP_WriteReady(NPStream *); | |
| 193 int NPP_Write(NPStream *, int, int, void *); | |
| 194 void NPP_StreamAsFile(NPStream *, const char *); | |
| 195 void NPP_URLNotify(const char *, NPReason, void *); | |
| 196 NPError NPP_GetValue(NPPVariable, void *); | |
| 197 NPError NPP_SetValue(NPNVariable, void *); | |
| 198 short NPP_HandleEvent(void*); | |
| 199 void NPP_Destroy(); | |
| 200 bool NPP_Print(NPPrint* platform_print); | |
| 201 NPError NPP_ClearSiteData(uint64, const char*, uint64); | |
| 202 void NPP_URLRedirectNotify(const char* url, int32_t status, | |
| 203 void* notify_data); | |
| 204 | |
| 205 void SendJavaScriptStream(const GURL& url, | |
| 206 const std::string& result, | |
| 207 bool success, | |
| 208 int notify_id); | |
| 209 | |
| 210 void DidReceiveManualResponse(const GURL& url, | |
| 211 const std::string& mime_type, | |
| 212 const std::string& headers, | |
| 213 uint32 expected_length, | |
| 214 uint32 last_modified); | |
| 215 void DidReceiveManualData(const char* buffer, int length); | |
| 216 void DidFinishManualLoading(); | |
| 217 void DidManualLoadFail(); | |
| 218 | |
| 219 void PushPopupsEnabledState(bool enabled); | |
| 220 void PopPopupsEnabledState(); | |
| 221 | |
| 222 bool popups_allowed() const { | |
| 223 return popups_enabled_stack_.empty() ? false : popups_enabled_stack_.top(); | |
| 224 } | |
| 225 | |
| 226 // Initiates byte range reads for plugins. | |
| 227 void RequestRead(NPStream* stream, NPByteRange* range_list); | |
| 228 | |
| 229 // Handles GetURL/GetURLNotify/PostURL/PostURLNotify requests initiated | |
| 230 // by plugins. | |
| 231 void RequestURL(const char* url, | |
| 232 const char* method, | |
| 233 const char* target, | |
| 234 const char* buf, | |
| 235 unsigned int len, | |
| 236 bool notify, | |
| 237 void* notify_data); | |
| 238 | |
| 239 // Handles NPN_URLRedirectResponse calls issued by plugins in response to | |
| 240 // HTTP URL redirect notifications. | |
| 241 void URLRedirectResponse(bool allow, void* notify_data); | |
| 242 | |
| 243 bool handles_url_redirects() const { return handles_url_redirects_; } | |
| 244 | |
| 245 private: | |
| 246 friend class base::RefCountedThreadSafe<PluginInstance>; | |
| 247 | |
| 248 #if defined(OS_MACOSX) | |
| 249 friend class ScopedCurrentPluginEvent; | |
| 250 // Sets the event that the plugin is currently handling. The object is not | |
| 251 // owned or copied, so the caller must call this again with NULL before the | |
| 252 // event pointer becomes invalid. Clients use ScopedCurrentPluginEvent rather | |
| 253 // than calling this directly. | |
| 254 void set_currently_handled_event(NPCocoaEvent* event) { | |
| 255 currently_handled_event_ = event; | |
| 256 } | |
| 257 #endif | |
| 258 | |
| 259 ~PluginInstance(); | |
| 260 void OnPluginThreadAsyncCall(void (*func)(void *), void *userData); | |
| 261 void OnTimerCall(void (*func)(NPP id, uint32 timer_id), | |
| 262 NPP id, uint32 timer_id); | |
| 263 bool IsValidStream(const NPStream* stream); | |
| 264 void GetNotifyData(int notify_id, bool* notify, void** notify_data); | |
| 265 | |
| 266 // This is a hack to get the real player plugin to work with chrome | |
| 267 // The real player plugin dll(nppl3260) when loaded by firefox is loaded via | |
| 268 // the NS COM API which is analogous to win32 COM. So the NPAPI functions in | |
| 269 // the plugin are invoked via an interface by firefox. The plugin instance | |
| 270 // handle which is passed to every NPAPI method is owned by the real player | |
| 271 // plugin, i.e. it expects the ndata member to point to a structure which | |
| 272 // it knows about. Eventually it dereferences this structure and compares | |
| 273 // a member variable at offset 0x24(Version 6.0.11.2888) /2D (Version | |
| 274 // 6.0.11.3088) with 0 and on failing this check, takes a different code | |
| 275 // path which causes a crash. Safari and Opera work with version 6.0.11.2888 | |
| 276 // by chance as their ndata structure contains a 0 at the location which real | |
| 277 // player checks:(. They crash with version 6.0.11.3088 as well. The | |
| 278 // following member just adds a 96 byte padding to our PluginInstance class | |
| 279 // which is passed in the ndata member. This magic number works correctly on | |
| 280 // Vista with UAC on or off :(. | |
| 281 // NOTE: Please dont change the ordering of the member variables | |
| 282 // New members should be added after this padding array. | |
| 283 // TODO(iyengar) : Disassemble the Realplayer ndata structure and look into | |
| 284 // the possiblity of conforming to it (http://b/issue?id=936667). We | |
| 285 // could also log a bug with Real, which would save the effort. | |
| 286 uint8 zero_padding_[96]; | |
| 287 scoped_refptr<NPAPI::PluginLib> plugin_; | |
| 288 NPP npp_; | |
| 289 scoped_refptr<PluginHost> host_; | |
| 290 NPPluginFuncs* npp_functions_; | |
| 291 std::vector<scoped_refptr<PluginStream> > open_streams_; | |
| 292 gfx::PluginWindowHandle window_handle_; | |
| 293 bool windowless_; | |
| 294 bool transparent_; | |
| 295 webkit_glue::WebPlugin* webplugin_; | |
| 296 std::string mime_type_; | |
| 297 GURL get_url_; | |
| 298 intptr_t get_notify_data_; | |
| 299 bool use_mozilla_user_agent_; | |
| 300 #if defined(OS_MACOSX) | |
| 301 NPDrawingModel drawing_model_; | |
| 302 NPEventModel event_model_; | |
| 303 gfx::Point plugin_origin_; | |
| 304 gfx::Rect containing_window_frame_; | |
| 305 NPCocoaEvent* currently_handled_event_; // weak | |
| 306 #endif | |
| 307 MessageLoop* message_loop_; | |
| 308 scoped_refptr<PluginStreamUrl> plugin_data_stream_; | |
| 309 | |
| 310 // This flag if true indicates that the plugin data would be passed from | |
| 311 // webkit. if false indicates that the plugin should download the data. | |
| 312 bool load_manually_; | |
| 313 | |
| 314 // Stack indicating if popups are to be enabled for the outgoing | |
| 315 // NPN_GetURL/NPN_GetURLNotify calls. | |
| 316 std::stack<bool> popups_enabled_stack_; | |
| 317 | |
| 318 // True if in CloseStreams(). | |
| 319 bool in_close_streams_; | |
| 320 | |
| 321 // List of files created for the current plugin instance. File names are | |
| 322 // added to the list every time the NPP_StreamAsFile function is called. | |
| 323 std::vector<FilePath> files_created_; | |
| 324 | |
| 325 // Next unusued timer id. | |
| 326 uint32 next_timer_id_; | |
| 327 | |
| 328 // Map of timer id to settings for timer. | |
| 329 struct TimerInfo { | |
| 330 uint32 interval; | |
| 331 bool repeat; | |
| 332 }; | |
| 333 typedef std::map<uint32, TimerInfo> TimerMap; | |
| 334 TimerMap timers_; | |
| 335 | |
| 336 // Tracks pending GET/POST requests so that the plugin-given data doesn't | |
| 337 // cross process boundaries to an untrusted process. | |
| 338 typedef std::map<int, void*> PendingRequestMap; | |
| 339 PendingRequestMap pending_requests_; | |
| 340 int next_notify_id_; | |
| 341 | |
| 342 // Used to track pending range requests so that when WebPlugin replies to us | |
| 343 // we can match the reply to the stream. | |
| 344 typedef std::map<int, scoped_refptr<PluginStream> > PendingRangeRequestMap; | |
| 345 PendingRangeRequestMap pending_range_requests_; | |
| 346 int next_range_request_id_; | |
| 347 // The plugin handles the NPAPI URL redirect notification API. | |
| 348 // See here https://wiki.mozilla.org/NPAPI:HTTPRedirectHandling | |
| 349 bool handles_url_redirects_; | |
| 350 | |
| 351 DISALLOW_COPY_AND_ASSIGN(PluginInstance); | |
| 352 }; | |
| 353 | |
| 354 #if defined(OS_MACOSX) | |
| 355 // Helper to simplify correct usage of set_currently_handled_event. | |
| 356 // Instantiating will set |instance|'s currently handled to |event| for the | |
| 357 // lifetime of the object, then NULL when it goes out of scope. | |
| 358 class ScopedCurrentPluginEvent { | |
| 359 public: | |
| 360 ScopedCurrentPluginEvent(PluginInstance* instance, NPCocoaEvent* event) | |
| 361 : instance_(instance) { | |
| 362 instance_->set_currently_handled_event(event); | |
| 363 } | |
| 364 ~ScopedCurrentPluginEvent() { | |
| 365 instance_->set_currently_handled_event(NULL); | |
| 366 } | |
| 367 private: | |
| 368 scoped_refptr<PluginInstance> instance_; | |
| 369 DISALLOW_COPY_AND_ASSIGN(ScopedCurrentPluginEvent); | |
| 370 }; | |
| 371 #endif | |
| 372 | |
| 373 } // namespace NPAPI | |
| 374 | |
| 375 #endif // WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__ | |
| OLD | NEW |