OLD | NEW |
| (Empty) |
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 // TODO: Need to deal with NPAPI's NPSavedData. | |
6 // I haven't seen plugins use it yet. | |
7 | |
8 #ifndef CONTENT_CHILD_NPAPI_PLUGIN_INSTANCE_H_ | |
9 #define CONTENT_CHILD_NPAPI_PLUGIN_INSTANCE_H_ | |
10 | |
11 #include <stdint.h> | |
12 | |
13 #include <map> | |
14 #include <stack> | |
15 #include <string> | |
16 #include <vector> | |
17 | |
18 #include "base/files/file_path.h" | |
19 #include "base/macros.h" | |
20 #include "base/memory/ref_counted.h" | |
21 #include "build/build_config.h" | |
22 #include "third_party/npapi/bindings/npapi.h" | |
23 #include "third_party/npapi/bindings/nphostapi.h" | |
24 #include "ui/gfx/geometry/point.h" | |
25 #include "ui/gfx/geometry/rect.h" | |
26 #include "ui/gfx/native_widget_types.h" | |
27 #include "url/gurl.h" | |
28 | |
29 namespace base { | |
30 class SingleThreadTaskRunner; | |
31 } | |
32 | |
33 namespace content { | |
34 | |
35 class PluginLib; | |
36 class PluginHost; | |
37 class WebPlugin; | |
38 class WebPluginResourceClient; | |
39 | |
40 #if defined(OS_MACOSX) | |
41 class ScopedCurrentPluginEvent; | |
42 #endif | |
43 | |
44 // A PluginInstance is an active, running instance of a Plugin. | |
45 // A single plugin may have many PluginInstances. | |
46 class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { | |
47 public: | |
48 // Create a new instance of a plugin. The PluginInstance | |
49 // will hold a reference to the plugin. | |
50 PluginInstance(PluginLib* plugin, const std::string &mime_type); | |
51 | |
52 // Activates the instance by calling NPP_New. | |
53 // This should be called after our instance is all | |
54 // setup from the host side and we are ready to receive | |
55 // requests from the plugin. We must not call any | |
56 // functions on the plugin instance until start has | |
57 // been called. | |
58 // | |
59 // url: The instance URL. | |
60 // param_names: the list of names of attributes passed via the | |
61 // element. | |
62 // param_values: the list of values corresponding to param_names | |
63 // param_count: number of attributes | |
64 // load_manually: if true indicates that the plugin data would be passed | |
65 // from webkit. if false indicates that the plugin should | |
66 // download the data. | |
67 // This also controls whether the plugin is instantiated as | |
68 // a full page plugin (NP_FULL) or embedded (NP_EMBED) | |
69 // | |
70 bool Start(const GURL& url, | |
71 char** const param_names, | |
72 char** const param_values, | |
73 int param_count, | |
74 bool load_manually); | |
75 | |
76 // NPAPI's instance identifier for this instance | |
77 NPP npp() { return npp_; } | |
78 | |
79 // Get/Set whether this instance is transparent. This only applies to | |
80 // windowless plugins. Transparent plugins require that webkit paint the | |
81 // background. | |
82 // Default is true for all plugins other than Flash. For Flash, we default to | |
83 // opaque since it always tells us if it's transparent during NPP_New. | |
84 bool transparent() { return transparent_; } | |
85 void set_transparent(bool value) { transparent_ = value; } | |
86 | |
87 // Get/Set the WebPlugin associated with this instance | |
88 WebPlugin* webplugin() { return webplugin_; } | |
89 void set_web_plugin(WebPlugin* webplugin) { | |
90 webplugin_ = webplugin; | |
91 } | |
92 | |
93 // Get the mimeType for this plugin stream | |
94 const std::string &mime_type() { return mime_type_; } | |
95 | |
96 PluginLib* plugin_lib() { return plugin_.get(); } | |
97 | |
98 #if defined(OS_MACOSX) | |
99 // Get/Set the Mac NPAPI drawing and event models | |
100 NPDrawingModel drawing_model() { return drawing_model_; } | |
101 void set_drawing_model(NPDrawingModel value) { drawing_model_ = value; } | |
102 NPEventModel event_model() { return event_model_; } | |
103 void set_event_model(NPEventModel value) { event_model_ = value; } | |
104 // Updates the instance's tracking of the location of the plugin location | |
105 // relative to the upper left of the screen. | |
106 void set_plugin_origin(const gfx::Point& origin) { plugin_origin_ = origin; } | |
107 // Updates the instance's tracking of the frame of the containing window | |
108 // relative to the upper left of the screen. | |
109 void set_window_frame(const gfx::Rect& frame) { | |
110 containing_window_frame_ = frame; | |
111 } | |
112 #endif | |
113 | |
114 // Returns the WebPluginResourceClient object for a stream that has become | |
115 // seekable. | |
116 WebPluginResourceClient* GetRangeRequest(int id); | |
117 | |
118 // If true, send the Mozilla user agent instead of Chrome's to the plugin. | |
119 bool use_mozilla_user_agent() { return use_mozilla_user_agent_; } | |
120 void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; } | |
121 | |
122 // If the plugin instance is backed by a texture, return its ID in the | |
123 // compositor's namespace. Otherwise return 0. Returns 0 by default. | |
124 unsigned GetBackingTextureId(); | |
125 | |
126 // Helper that implements NPN_PluginThreadAsyncCall semantics | |
127 void PluginThreadAsyncCall(void (*func)(void *), | |
128 void* userData); | |
129 | |
130 uint32_t ScheduleTimer(uint32_t interval, | |
131 NPBool repeat, | |
132 void (*func)(NPP id, uint32_t timer_id)); | |
133 | |
134 void UnscheduleTimer(uint32_t timer_id); | |
135 | |
136 bool ConvertPoint(double source_x, double source_y, | |
137 NPCoordinateSpace source_space, | |
138 double* dest_x, double* dest_y, | |
139 NPCoordinateSpace dest_space); | |
140 | |
141 NPError PopUpContextMenu(NPMenu* menu); | |
142 | |
143 // | |
144 // NPAPI methods for calling the Plugin Instance | |
145 // | |
146 NPError NPP_New(unsigned short, short, char *[], char *[]); | |
147 NPError NPP_SetWindow(NPWindow*); | |
148 NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool, unsigned short*); | |
149 NPError NPP_DestroyStream(NPStream*, NPReason); | |
150 int NPP_WriteReady(NPStream*); | |
151 int NPP_Write(NPStream*, int, int, void*); | |
152 void NPP_StreamAsFile(NPStream*, const char*); | |
153 void NPP_URLNotify(const char*, NPReason, void*); | |
154 NPError NPP_GetValue(NPPVariable, void*); | |
155 NPError NPP_SetValue(NPNVariable, void*); | |
156 short NPP_HandleEvent(void*); | |
157 void NPP_Destroy(); | |
158 bool NPP_Print(NPPrint* platform_print); | |
159 void NPP_URLRedirectNotify(const char* url, int32_t status, | |
160 void* notify_data); | |
161 | |
162 void SendJavaScriptStream(const GURL& url, | |
163 const std::string& result, | |
164 bool success); | |
165 | |
166 void PushPopupsEnabledState(bool enabled); | |
167 void PopPopupsEnabledState(); | |
168 | |
169 bool popups_allowed() const { | |
170 return popups_enabled_stack_.empty() ? false : popups_enabled_stack_.top(); | |
171 } | |
172 | |
173 private: | |
174 friend class base::RefCountedThreadSafe<PluginInstance>; | |
175 | |
176 #if defined(OS_MACOSX) | |
177 friend class ScopedCurrentPluginEvent; | |
178 // Sets the event that the plugin is currently handling. The object is not | |
179 // owned or copied, so the caller must call this again with NULL before the | |
180 // event pointer becomes invalid. Clients use ScopedCurrentPluginEvent rather | |
181 // than calling this directly. | |
182 void set_currently_handled_event(NPCocoaEvent* event) { | |
183 currently_handled_event_ = event; | |
184 } | |
185 #endif | |
186 | |
187 ~PluginInstance(); | |
188 void OnPluginThreadAsyncCall(void (*func)(void *), void* userData); | |
189 void OnTimerCall(void (*func)(NPP id, uint32_t timer_id), | |
190 NPP id, | |
191 uint32_t timer_id); | |
192 | |
193 // This is a hack to get the real player plugin to work with chrome | |
194 // The real player plugin dll(nppl3260) when loaded by firefox is loaded via | |
195 // the NS COM API which is analogous to win32 COM. So the NPAPI functions in | |
196 // the plugin are invoked via an interface by firefox. The plugin instance | |
197 // handle which is passed to every NPAPI method is owned by the real player | |
198 // plugin, i.e. it expects the ndata member to point to a structure which | |
199 // it knows about. Eventually it dereferences this structure and compares | |
200 // a member variable at offset 0x24(Version 6.0.11.2888) /2D (Version | |
201 // 6.0.11.3088) with 0 and on failing this check, takes a different code | |
202 // path which causes a crash. Safari and Opera work with version 6.0.11.2888 | |
203 // by chance as their ndata structure contains a 0 at the location which real | |
204 // player checks:(. They crash with version 6.0.11.3088 as well. The | |
205 // following member just adds a 96 byte padding to our PluginInstance class | |
206 // which is passed in the ndata member. This magic number works correctly on | |
207 // Vista with UAC on or off :(. | |
208 // NOTE: Please dont change the ordering of the member variables | |
209 // New members should be added after this padding array. | |
210 // TODO(iyengar) : Disassemble the Realplayer ndata structure and look into | |
211 // the possiblity of conforming to it (http://b/issue?id=936667). We | |
212 // could also log a bug with Real, which would save the effort. | |
213 uint8_t zero_padding_[96]; | |
214 scoped_refptr<PluginLib> plugin_; | |
215 NPP npp_; | |
216 scoped_refptr<PluginHost> host_; | |
217 NPPluginFuncs* npp_functions_; | |
218 bool transparent_; | |
219 WebPlugin* webplugin_; | |
220 std::string mime_type_; | |
221 bool use_mozilla_user_agent_; | |
222 #if defined(OS_MACOSX) | |
223 NPDrawingModel drawing_model_; | |
224 NPEventModel event_model_; | |
225 gfx::Point plugin_origin_; | |
226 gfx::Rect containing_window_frame_; | |
227 NPCocoaEvent* currently_handled_event_; // weak | |
228 #endif | |
229 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
230 | |
231 // This flag if true indicates that the plugin data would be passed from | |
232 // webkit. if false indicates that the plugin should download the data. | |
233 bool load_manually_; | |
234 | |
235 // Stack indicating if popups are to be enabled for the outgoing | |
236 // NPN_GetURL/NPN_GetURLNotify calls. | |
237 std::stack<bool> popups_enabled_stack_; | |
238 | |
239 // List of files created for the current plugin instance. File names are | |
240 // added to the list every time the NPP_StreamAsFile function is called. | |
241 std::vector<base::FilePath> files_created_; | |
242 | |
243 // Next unusued timer id. | |
244 uint32_t next_timer_id_; | |
245 | |
246 // Map of timer id to settings for timer. | |
247 struct TimerInfo { | |
248 uint32_t interval; | |
249 bool repeat; | |
250 }; | |
251 typedef std::map<uint32_t, TimerInfo> TimerMap; | |
252 TimerMap timers_; | |
253 | |
254 DISALLOW_COPY_AND_ASSIGN(PluginInstance); | |
255 }; | |
256 | |
257 #if defined(OS_MACOSX) | |
258 // Helper to simplify correct usage of set_currently_handled_event. | |
259 // Instantiating will set |instance|'s currently handled to |event| for the | |
260 // lifetime of the object, then NULL when it goes out of scope. | |
261 class ScopedCurrentPluginEvent { | |
262 public: | |
263 ScopedCurrentPluginEvent(PluginInstance* instance, NPCocoaEvent* event); | |
264 ~ScopedCurrentPluginEvent(); | |
265 | |
266 private: | |
267 scoped_refptr<PluginInstance> instance_; | |
268 DISALLOW_COPY_AND_ASSIGN(ScopedCurrentPluginEvent); | |
269 }; | |
270 #endif | |
271 | |
272 } // namespace content | |
273 | |
274 #endif // CONTENT_CHILD_NPAPI_PLUGIN_INSTANCE_H_ | |
OLD | NEW |