summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/plugin_instance.h
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue/plugins/plugin_instance.h')
-rw-r--r--webkit/glue/plugins/plugin_instance.h360
1 files changed, 360 insertions, 0 deletions
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
new file mode 100644
index 0000000..36bf601
--- /dev/null
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -0,0 +1,360 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO: Need to deal with NPAPI's NPSavedData.
+// I haven't seen plugins use it yet.
+
+#ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__
+#define WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__
+
+#include <map>
+#include <set>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "gfx/native_widget_types.h"
+#include "gfx/point.h"
+#include "gfx/rect.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/npapi/bindings/npapi.h"
+#include "third_party/npapi/bindings/nphostapi.h"
+
+class MessageLoop;
+
+namespace webkit_glue {
+class WebPlugin;
+class WebPluginResourceClient;
+}
+
+namespace NPAPI
+{
+class PluginLib;
+class PluginHost;
+class PluginStream;
+class PluginStreamUrl;
+class PluginDataStream;
+#if defined(OS_MACOSX)
+class ScopedCurrentPluginEvent;
+#endif
+
+// A PluginInstance is an active, running instance of a Plugin.
+// A single plugin may have many PluginInstances.
+class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
+ public:
+ // Create a new instance of a plugin. The PluginInstance
+ // will hold a reference to the plugin.
+ PluginInstance(PluginLib *plugin, const std::string &mime_type);
+
+ // Activates the instance by calling NPP_New.
+ // This should be called after our instance is all
+ // setup from the host side and we are ready to receive
+ // requests from the plugin. We must not call any
+ // functions on the plugin instance until start has
+ // been called.
+ //
+ // url: The instance URL.
+ // param_names: the list of names of attributes passed via the
+ // element.
+ // param_values: the list of values corresponding to param_names
+ // param_count: number of attributes
+ // load_manually: if true indicates that the plugin data would be passed
+ // from webkit. if false indicates that the plugin should
+ // download the data.
+ // This also controls whether the plugin is instantiated as
+ // a full page plugin (NP_FULL) or embedded (NP_EMBED)
+ //
+ bool Start(const GURL& url,
+ char** const param_names,
+ char** const param_values,
+ int param_count,
+ bool load_manually);
+
+ // NPAPI's instance identifier for this instance
+ NPP npp() { return npp_; }
+
+ // Get/Set for the instance's window handle.
+ gfx::PluginWindowHandle window_handle() const { return window_handle_; }
+ void set_window_handle(gfx::PluginWindowHandle value) {
+ window_handle_ = value;
+ }
+
+ // Get/Set whether this instance is in Windowless mode.
+ // Default is false.
+ bool windowless() { return windowless_; }
+ void set_windowless(bool value) { windowless_ = value; }
+
+ // Get/Set whether this instance is transparent.
+ // This only applies to windowless plugins. Transparent
+ // plugins require that webkit paint the background.
+ // Default is true.
+ bool transparent() { return transparent_; }
+ void set_transparent(bool value) { transparent_ = value; }
+
+ // Get/Set the WebPlugin associated with this instance
+ webkit_glue::WebPlugin* webplugin() { return webplugin_; }
+ void set_web_plugin(webkit_glue::WebPlugin* webplugin) {
+ webplugin_ = webplugin;
+ }
+
+ // Get the mimeType for this plugin stream
+ const std::string &mime_type() { return mime_type_; }
+
+ NPAPI::PluginLib* plugin_lib() { return plugin_; }
+
+#if defined(OS_MACOSX)
+ // Get/Set the Mac NPAPI drawing and event models
+ NPDrawingModel drawing_model() { return drawing_model_; }
+ void set_drawing_model(NPDrawingModel value) { drawing_model_ = value; }
+ NPEventModel event_model() { return event_model_; }
+ void set_event_model(NPEventModel value) { event_model_ = value; }
+ // Updates the instance's tracking of the location of the plugin location
+ // relative to the upper left of the screen.
+ void set_plugin_origin(const gfx::Point& origin) { plugin_origin_ = origin; }
+ // Updates the instance's tracking of the frame of the containing window
+ // relative to the upper left of the screen.
+ void set_window_frame(const gfx::Rect& frame) {
+ containing_window_frame_ = frame;
+ }
+#endif
+
+ // Creates a stream for sending an URL. If notify_id is non-zero, it will
+ // send a notification to the plugin when the stream is complete; otherwise it
+ // will not. Set object_url to true if the load is for the object tag's url,
+ // or false if it's for a url that the plugin fetched through
+ // NPN_GetUrl[Notify].
+ PluginStreamUrl* CreateStream(unsigned long resource_id,
+ const GURL& url,
+ const std::string& mime_type,
+ int notify_id);
+
+ // For each instance, we track all streams. When the
+ // instance closes, all remaining streams are also
+ // closed. All streams associated with this instance
+ // should call AddStream so that they can be cleaned
+ // up when the instance shuts down.
+ void AddStream(PluginStream* stream);
+
+ // This is called when a stream is closed. We remove the stream from the
+ // list, which releases the reference maintained to the stream.
+ void RemoveStream(PluginStream* stream);
+
+ // Closes all open streams on this instance.
+ void CloseStreams();
+
+ // Returns the WebPluginResourceClient object for a stream that has become
+ // seekable.
+ webkit_glue::WebPluginResourceClient* GetRangeRequest(int id);
+
+ // Have the plugin create it's script object.
+ NPObject *GetPluginScriptableObject();
+
+ // WebViewDelegate methods that we implement. This is for handling
+ // callbacks during getURLNotify.
+ void DidFinishLoadWithReason(const GURL& url, NPReason reason, int notify_id);
+
+ // If true, send the Mozilla user agent instead of Chrome's to the plugin.
+ bool use_mozilla_user_agent() { return use_mozilla_user_agent_; }
+ void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; }
+
+ // Helper that implements NPN_PluginThreadAsyncCall semantics
+ void PluginThreadAsyncCall(void (*func)(void *),
+ void *userData);
+
+ uint32 ScheduleTimer(uint32 interval,
+ NPBool repeat,
+ void (*func)(NPP id, uint32 timer_id));
+
+ void UnscheduleTimer(uint32 timer_id);
+
+ bool ConvertPoint(double source_x, double source_y,
+ NPCoordinateSpace source_space,
+ double* dest_x, double* dest_y,
+ NPCoordinateSpace dest_space);
+
+ NPError PopUpContextMenu(NPMenu* menu);
+
+ //
+ // NPAPI methods for calling the Plugin Instance
+ //
+ NPError NPP_New(unsigned short, short, char *[], char *[]);
+ NPError NPP_SetWindow(NPWindow *);
+ NPError NPP_NewStream(NPMIMEType, NPStream *, NPBool, unsigned short *);
+ NPError NPP_DestroyStream(NPStream *, NPReason);
+ int NPP_WriteReady(NPStream *);
+ int NPP_Write(NPStream *, int, int, void *);
+ void NPP_StreamAsFile(NPStream *, const char *);
+ void NPP_URLNotify(const char *, NPReason, void *);
+ NPError NPP_GetValue(NPPVariable, void *);
+ NPError NPP_SetValue(NPNVariable, void *);
+ short NPP_HandleEvent(void*);
+ void NPP_Destroy();
+ bool NPP_Print(NPPrint* platform_print);
+
+ void SendJavaScriptStream(const GURL& url,
+ const std::string& result,
+ bool success,
+ int notify_id);
+
+ void DidReceiveManualResponse(const GURL& url,
+ const std::string& mime_type,
+ const std::string& headers,
+ uint32 expected_length,
+ uint32 last_modified);
+ void DidReceiveManualData(const char* buffer, int length);
+ void DidFinishManualLoading();
+ void DidManualLoadFail();
+
+ void PushPopupsEnabledState(bool enabled);
+ void PopPopupsEnabledState();
+
+ bool popups_allowed() const {
+ return popups_enabled_stack_.empty() ? false : popups_enabled_stack_.top();
+ }
+
+ // Initiates byte range reads for plugins.
+ void RequestRead(NPStream* stream, NPByteRange* range_list);
+
+ // Handles GetURL/GetURLNotify/PostURL/PostURLNotify requests initiated
+ // by plugins.
+ void RequestURL(const char* url,
+ const char* method,
+ const char* target,
+ const char* buf,
+ unsigned int len,
+ bool notify,
+ void* notify_data);
+
+ private:
+ friend class base::RefCountedThreadSafe<PluginInstance>;
+
+#if defined(OS_MACOSX)
+ friend class ScopedCurrentPluginEvent;
+ // Sets the event that the plugin is currently handling. The object is not
+ // owned or copied, so the caller must call this again with NULL before the
+ // event pointer becomes invalid. Clients use ScopedCurrentPluginEvent rather
+ // than calling this directly.
+ void set_currently_handled_event(NPCocoaEvent* event) {
+ currently_handled_event_ = event;
+ }
+#endif
+
+ ~PluginInstance();
+ void OnPluginThreadAsyncCall(void (*func)(void *), void *userData);
+ void OnTimerCall(void (*func)(NPP id, uint32 timer_id),
+ NPP id, uint32 timer_id);
+ bool IsValidStream(const NPStream* stream);
+ void GetNotifyData(int notify_id, bool* notify, void** notify_data);
+
+ // This is a hack to get the real player plugin to work with chrome
+ // The real player plugin dll(nppl3260) when loaded by firefox is loaded via
+ // the NS COM API which is analogous to win32 COM. So the NPAPI functions in
+ // the plugin are invoked via an interface by firefox. The plugin instance
+ // handle which is passed to every NPAPI method is owned by the real player
+ // plugin, i.e. it expects the ndata member to point to a structure which
+ // it knows about. Eventually it dereferences this structure and compares
+ // a member variable at offset 0x24(Version 6.0.11.2888) /2D (Version
+ // 6.0.11.3088) with 0 and on failing this check, takes a different code
+ // path which causes a crash. Safari and Opera work with version 6.0.11.2888
+ // by chance as their ndata structure contains a 0 at the location which real
+ // player checks:(. They crash with version 6.0.11.3088 as well. The
+ // following member just adds a 96 byte padding to our PluginInstance class
+ // which is passed in the ndata member. This magic number works correctly on
+ // Vista with UAC on or off :(.
+ // NOTE: Please dont change the ordering of the member variables
+ // New members should be added after this padding array.
+ // TODO(iyengar) : Disassemble the Realplayer ndata structure and look into
+ // the possiblity of conforming to it (http://b/issue?id=936667). We
+ // could also log a bug with Real, which would save the effort.
+ uint8 zero_padding_[96];
+ scoped_refptr<NPAPI::PluginLib> plugin_;
+ NPP npp_;
+ scoped_refptr<PluginHost> host_;
+ NPPluginFuncs* npp_functions_;
+ std::vector<scoped_refptr<PluginStream> > open_streams_;
+ gfx::PluginWindowHandle window_handle_;
+ bool windowless_;
+ bool transparent_;
+ webkit_glue::WebPlugin* webplugin_;
+ std::string mime_type_;
+ GURL get_url_;
+ intptr_t get_notify_data_;
+ bool use_mozilla_user_agent_;
+#if defined(OS_MACOSX)
+ NPDrawingModel drawing_model_;
+ NPEventModel event_model_;
+ gfx::Point plugin_origin_;
+ gfx::Rect containing_window_frame_;
+ NPCocoaEvent* currently_handled_event_; // weak
+#endif
+ MessageLoop* message_loop_;
+ scoped_refptr<PluginStreamUrl> plugin_data_stream_;
+
+ // This flag if true indicates that the plugin data would be passed from
+ // webkit. if false indicates that the plugin should download the data.
+ bool load_manually_;
+
+ // Stack indicating if popups are to be enabled for the outgoing
+ // NPN_GetURL/NPN_GetURLNotify calls.
+ std::stack<bool> popups_enabled_stack_;
+
+ // True if in CloseStreams().
+ bool in_close_streams_;
+
+ // List of files created for the current plugin instance. File names are
+ // added to the list every time the NPP_StreamAsFile function is called.
+ std::vector<FilePath> files_created_;
+
+ // Next unusued timer id.
+ uint32 next_timer_id_;
+
+ // Map of timer id to settings for timer.
+ struct TimerInfo {
+ uint32 interval;
+ bool repeat;
+ };
+ typedef std::map<uint32, TimerInfo> TimerMap;
+ TimerMap timers_;
+
+ // Tracks pending GET/POST requests so that the plugin-given data doesn't
+ // cross process boundaries to an untrusted process.
+ typedef std::map<int, void*> PendingRequestMap;
+ PendingRequestMap pending_requests_;
+ int next_notify_id_;
+
+ // Used to track pending range requests so that when WebPlugin replies to us
+ // we can match the reply to the stream.
+ typedef std::map<int, scoped_refptr<PluginStream> > PendingRangeRequestMap;
+ PendingRangeRequestMap pending_range_requests_;
+ int next_range_request_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginInstance);
+};
+
+#if defined(OS_MACOSX)
+// Helper to simplify correct usage of set_currently_handled_event.
+// Instantiating will set |instance|'s currently handled to |event| for the
+// lifetime of the object, then NULL when it goes out of scope.
+class ScopedCurrentPluginEvent {
+ public:
+ ScopedCurrentPluginEvent(PluginInstance* instance, NPCocoaEvent* event)
+ : instance_(instance) {
+ instance_->set_currently_handled_event(event);
+ }
+ ~ScopedCurrentPluginEvent() {
+ instance_->set_currently_handled_event(NULL);
+ }
+ private:
+ scoped_refptr<PluginInstance> instance_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedCurrentPluginEvent);
+};
+#endif
+
+} // namespace NPAPI
+
+#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_INSTANCE_H__