Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef nsNPAPIPluginInstance_h_
7 : #define nsNPAPIPluginInstance_h_
8 :
9 : #include "nsSize.h"
10 : #include "nsCOMPtr.h"
11 : #include "nsTArray.h"
12 : #include "nsPIDOMWindow.h"
13 : #include "nsITimer.h"
14 : #include "nsIPluginInstanceOwner.h"
15 : #include "nsIURI.h"
16 : #include "nsIChannel.h"
17 : #include "nsHashKeys.h"
18 : #include <prinrval.h>
19 : #include "js/TypeDecls.h"
20 : #include "nsIAudioChannelAgent.h"
21 : #ifdef MOZ_WIDGET_ANDROID
22 : #include "nsIRunnable.h"
23 : #include "GLContextTypes.h"
24 : #include "AndroidNativeWindow.h"
25 : #include "AndroidBridge.h"
26 : #include <map>
27 : class PluginEventRunnable;
28 : #endif
29 :
30 : #include "mozilla/EventForwards.h"
31 : #include "mozilla/TimeStamp.h"
32 : #include "mozilla/PluginLibrary.h"
33 : #include "mozilla/RefPtr.h"
34 : #include "mozilla/WeakPtr.h"
35 :
36 : class nsPluginStreamListenerPeer; // browser-initiated stream class
37 : class nsNPAPIPluginStreamListener; // plugin-initiated stream class
38 : class nsIPluginInstanceOwner;
39 : class nsIOutputStream;
40 : class nsPluginInstanceOwner;
41 :
42 : #if defined(OS_WIN)
43 : const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncWin;
44 : #elif defined(MOZ_X11)
45 : const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncX;
46 : #elif defined(XP_MACOSX)
47 : #ifndef NP_NO_QUICKDRAW
48 : const NPDrawingModel kDefaultDrawingModel = NPDrawingModelQuickDraw; // Not supported
49 : #else
50 : const NPDrawingModel kDefaultDrawingModel = NPDrawingModelCoreGraphics;
51 : #endif
52 : #else
53 : const NPDrawingModel kDefaultDrawingModel = static_cast<NPDrawingModel>(0);
54 : #endif
55 :
56 : /**
57 : * Used to indicate whether it's OK to reenter Gecko and repaint, flush frames,
58 : * run scripts, etc, during this plugin call.
59 : * When NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO is set, we try to avoid dangerous
60 : * Gecko activities when the plugin spins a nested event loop, on a best-effort
61 : * basis.
62 : */
63 : enum NSPluginCallReentry {
64 : NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO,
65 : NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO
66 : };
67 :
68 0 : class nsNPAPITimer
69 : {
70 : public:
71 : NPP npp;
72 : uint32_t id;
73 : nsCOMPtr<nsITimer> timer;
74 : void (*callback)(NPP npp, uint32_t timerID);
75 : bool inCallback;
76 : bool needUnschedule;
77 : };
78 :
79 : class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback
80 : , public mozilla::SupportsWeakPtr<nsNPAPIPluginInstance>
81 : {
82 : private:
83 : typedef mozilla::PluginLibrary PluginLibrary;
84 :
85 : public:
86 : typedef mozilla::gfx::DrawTarget DrawTarget;
87 :
88 0 : MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance)
89 : NS_DECL_THREADSAFE_ISUPPORTS
90 : NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
91 :
92 : nsresult Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const nsACString& aMIMEType);
93 : nsresult Start();
94 : nsresult Stop();
95 : nsresult SetWindow(NPWindow* window);
96 : nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result);
97 : nsresult Print(NPPrint* platformPrint);
98 : nsresult HandleEvent(void* event, int16_t* result,
99 : NSPluginCallReentry aSafeToReenterGecko = NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
100 : nsresult GetValueFromPlugin(NPPVariable variable, void* value);
101 : nsresult GetDrawingModel(int32_t* aModel);
102 : nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing);
103 : nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
104 : nsresult CSSZoomFactorChanged(float aCSSZoomFactor);
105 : nsresult GetJSObject(JSContext *cx, JSObject** outObject);
106 : bool ShouldCache();
107 : nsresult IsWindowless(bool* isWindowless);
108 : nsresult AsyncSetWindow(NPWindow* window);
109 : nsresult GetImageContainer(mozilla::layers::ImageContainer **aContainer);
110 : nsresult GetImageSize(nsIntSize* aSize);
111 : nsresult NotifyPainted(void);
112 : nsresult GetIsOOP(bool* aIsOOP);
113 : nsresult SetBackgroundUnknown();
114 : nsresult BeginUpdateBackground(nsIntRect* aRect, DrawTarget** aContext);
115 : nsresult EndUpdateBackground(nsIntRect* aRect);
116 : nsresult IsTransparent(bool* isTransparent);
117 : nsresult GetFormValue(nsAString& aValue);
118 : nsresult PushPopupsEnabledState(bool aEnabled);
119 : nsresult PopPopupsEnabledState();
120 : nsresult GetPluginAPIVersion(uint16_t* version);
121 : nsresult InvalidateRect(NPRect *invalidRect);
122 : nsresult InvalidateRegion(NPRegion invalidRegion);
123 : nsresult GetMIMEType(const char* *result);
124 : #if defined(XP_WIN)
125 : nsresult GetScrollCaptureContainer(mozilla::layers::ImageContainer **aContainer);
126 : #endif
127 : nsresult HandledWindowedPluginKeyEvent(
128 : const mozilla::NativeEventData& aKeyEventData,
129 : bool aIsConsumed);
130 : nsPluginInstanceOwner* GetOwner();
131 : void SetOwner(nsPluginInstanceOwner *aOwner);
132 : void DidComposite();
133 :
134 0 : bool HasAudioChannelAgent() const
135 : {
136 0 : return !!mAudioChannelAgent;
137 : }
138 :
139 : void NotifyStartedPlaying();
140 : void NotifyStoppedPlaying();
141 :
142 : nsresult SetMuted(bool aIsMuted);
143 :
144 : nsNPAPIPlugin* GetPlugin();
145 :
146 : nsresult GetNPP(NPP * aNPP);
147 :
148 : NPError SetWindowless(bool aWindowless);
149 :
150 : NPError SetTransparent(bool aTransparent);
151 :
152 : NPError SetWantsAllNetworkStreams(bool aWantsAllNetworkStreams);
153 :
154 : NPError SetUsesDOMForCursor(bool aUsesDOMForCursor);
155 : bool UsesDOMForCursor();
156 :
157 : void SetDrawingModel(NPDrawingModel aModel);
158 : void RedrawPlugin();
159 : #ifdef XP_MACOSX
160 : void SetEventModel(NPEventModel aModel);
161 :
162 : void* GetCurrentEvent() {
163 : return mCurrentPluginEvent;
164 : }
165 : #endif
166 :
167 : #ifdef MOZ_WIDGET_ANDROID
168 : void NotifyForeground(bool aForeground);
169 : void NotifyOnScreen(bool aOnScreen);
170 : void MemoryPressure();
171 : void NotifyFullScreen(bool aFullScreen);
172 : void NotifySize(nsIntSize size);
173 :
174 : nsIntSize CurrentSize() { return mCurrentSize; }
175 :
176 : bool IsOnScreen() {
177 : return mOnScreen;
178 : }
179 :
180 : uint32_t GetANPDrawingModel() { return mANPDrawingModel; }
181 : void SetANPDrawingModel(uint32_t aModel);
182 :
183 : void* GetJavaSurface();
184 :
185 : void PostEvent(void* event);
186 :
187 : // These are really mozilla::dom::ScreenOrientation, but it's
188 : // difficult to include that here
189 : uint32_t FullScreenOrientation() { return mFullScreenOrientation; }
190 : void SetFullScreenOrientation(uint32_t orientation);
191 :
192 : void SetWakeLock(bool aLock);
193 :
194 : mozilla::gl::GLContext* GLContext();
195 :
196 : // For ANPOpenGL
197 : class TextureInfo {
198 : public:
199 : TextureInfo() :
200 : mTexture(0), mWidth(0), mHeight(0), mInternalFormat(0)
201 : {
202 : }
203 :
204 : TextureInfo(GLuint aTexture, int32_t aWidth, int32_t aHeight, GLuint aInternalFormat) :
205 : mTexture(aTexture), mWidth(aWidth), mHeight(aHeight), mInternalFormat(aInternalFormat)
206 : {
207 : }
208 :
209 : GLuint mTexture;
210 : int32_t mWidth;
211 : int32_t mHeight;
212 : GLuint mInternalFormat;
213 : };
214 :
215 : // For ANPNativeWindow
216 : void* AcquireContentWindow();
217 :
218 : mozilla::java::GeckoSurface::Param AsSurface();
219 :
220 : // For ANPVideo
221 : class VideoInfo {
222 : public:
223 : VideoInfo(mozilla::java::GeckoSurface::Param aSurface)
224 : : mSurface(aSurface)
225 : , mNativeWindow(aSurface)
226 : {
227 : }
228 :
229 : ~VideoInfo()
230 : {
231 : mozilla::java::SurfaceAllocator::DisposeSurface(mSurface);
232 : }
233 :
234 : mozilla::java::GeckoSurface::GlobalRef mSurface;
235 : mozilla::gl::AndroidNativeWindow mNativeWindow;
236 : gfxRect mDimensions;
237 : };
238 :
239 : void* AcquireVideoWindow();
240 : void ReleaseVideoWindow(void* aWindow);
241 : void SetVideoDimensions(void* aWindow, gfxRect aDimensions);
242 :
243 : void GetVideos(nsTArray<VideoInfo*>& aVideos);
244 :
245 : void SetOriginPos(mozilla::gl::OriginPos aOriginPos) {
246 : mOriginPos = aOriginPos;
247 : }
248 : mozilla::gl::OriginPos OriginPos() const { return mOriginPos; }
249 :
250 : static nsNPAPIPluginInstance* GetFromNPP(NPP npp);
251 : #endif
252 :
253 : nsresult NewStreamListener(const char* aURL, void* notifyData,
254 : nsNPAPIPluginStreamListener** listener);
255 :
256 : nsNPAPIPluginInstance();
257 :
258 : // To be called when an instance becomes orphaned, when
259 : // it's plugin is no longer guaranteed to be around.
260 : void Destroy();
261 :
262 : // Indicates whether the plugin is running normally.
263 0 : bool IsRunning() {
264 0 : return RUNNING == mRunning;
265 : }
266 0 : bool HasStartedDestroying() {
267 0 : return mRunning >= DESTROYING;
268 : }
269 :
270 : // Indicates whether the plugin is running normally or being shut down
271 0 : bool CanFireNotifications() {
272 0 : return mRunning == RUNNING || mRunning == DESTROYING;
273 : }
274 :
275 : // return is only valid when the plugin is not running
276 : mozilla::TimeStamp StopTime();
277 :
278 : // cache this NPAPI plugin
279 : void SetCached(bool aCache);
280 :
281 : already_AddRefed<nsPIDOMWindowOuter> GetDOMWindow();
282 :
283 : nsresult PrivateModeStateChanged(bool aEnabled);
284 :
285 : nsresult IsPrivateBrowsing(bool *aEnabled);
286 :
287 : nsresult GetDOMElement(nsIDOMElement* *result);
288 :
289 : nsNPAPITimer* TimerWithID(uint32_t id, uint32_t* index);
290 : uint32_t ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
291 : void UnscheduleTimer(uint32_t timerID);
292 : NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
293 :
294 :
295 : nsTArray<nsNPAPIPluginStreamListener*> *StreamListeners();
296 :
297 : nsTArray<nsPluginStreamListenerPeer*> *FileCachedStreamListeners();
298 :
299 : nsresult AsyncSetWindow(NPWindow& window);
300 :
301 : void URLRedirectResponse(void* notifyData, NPBool allow);
302 :
303 : NPError InitAsyncSurface(NPSize *size, NPImageFormat format,
304 : void *initData, NPAsyncSurface *surface);
305 : NPError FinalizeAsyncSurface(NPAsyncSurface *surface);
306 : void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed);
307 :
308 : // Returns the contents scale factor of the screen the plugin is drawn on.
309 : double GetContentsScaleFactor();
310 :
311 : // Returns the css zoom factor of the document the plugin is drawn on.
312 : float GetCSSZoomFactor();
313 :
314 : nsresult GetRunID(uint32_t *aRunID);
315 :
316 89 : static bool InPluginCallUnsafeForReentry() { return gInUnsafePluginCalls > 0; }
317 0 : static void BeginPluginCall(NSPluginCallReentry aReentryState)
318 : {
319 0 : if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) {
320 0 : ++gInUnsafePluginCalls;
321 : }
322 0 : }
323 0 : static void EndPluginCall(NSPluginCallReentry aReentryState)
324 : {
325 0 : if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) {
326 0 : NS_ASSERTION(gInUnsafePluginCalls > 0, "Must be in plugin call");
327 0 : --gInUnsafePluginCalls;
328 : }
329 0 : }
330 :
331 : protected:
332 :
333 : virtual ~nsNPAPIPluginInstance();
334 :
335 : nsresult GetTagType(nsPluginTagType *result);
336 :
337 : // check if this is a Java applet and affected by bug 750480
338 : void CheckJavaC2PJSObjectQuirk(uint16_t paramCount,
339 : const char* const* names,
340 : const char* const* values);
341 :
342 : nsresult CreateAudioChannelAgentIfNeeded();
343 :
344 : // The structure used to communicate between the plugin instance and
345 : // the browser.
346 : NPP_t mNPP;
347 :
348 : NPDrawingModel mDrawingModel;
349 :
350 : #ifdef MOZ_WIDGET_ANDROID
351 : uint32_t mANPDrawingModel;
352 :
353 : friend class PluginEventRunnable;
354 :
355 : nsTArray<RefPtr<PluginEventRunnable>> mPostedEvents;
356 : void PopPostedEvent(PluginEventRunnable* r);
357 : void OnSurfaceTextureFrameAvailable();
358 :
359 : uint32_t mFullScreenOrientation;
360 : bool mWakeLocked;
361 : bool mFullScreen;
362 : mozilla::gl::OriginPos mOriginPos;
363 :
364 : mozilla::java::GeckoSurface::GlobalRef mContentSurface;
365 : mozilla::gl::AndroidNativeWindow mContentWindow;
366 : #endif
367 :
368 : enum {
369 : NOT_STARTED,
370 : RUNNING,
371 : DESTROYING,
372 : DESTROYED
373 : } mRunning;
374 :
375 : // these are used to store the windowless properties
376 : // which the browser will later query
377 : bool mWindowless;
378 : bool mTransparent;
379 : bool mCached;
380 : bool mUsesDOMForCursor;
381 :
382 : public:
383 : // True while creating the plugin, or calling NPP_SetWindow() on it.
384 : bool mInPluginInitCall;
385 :
386 : nsXPIDLCString mFakeURL;
387 :
388 : private:
389 : RefPtr<nsNPAPIPlugin> mPlugin;
390 :
391 : nsTArray<nsNPAPIPluginStreamListener*> mStreamListeners;
392 :
393 : nsTArray<nsPluginStreamListenerPeer*> mFileCachedStreamListeners;
394 :
395 : nsTArray<PopupControlState> mPopupStates;
396 :
397 : char* mMIMEType;
398 :
399 : // Weak pointer to the owner. The owner nulls this out (by calling
400 : // InvalidateOwner()) when it's no longer our owner.
401 : nsPluginInstanceOwner *mOwner;
402 :
403 : nsTArray<nsNPAPITimer*> mTimers;
404 :
405 : #ifdef XP_MACOSX
406 : // non-null during a HandleEvent call
407 : void* mCurrentPluginEvent;
408 : #endif
409 :
410 : // Timestamp for the last time this plugin was stopped.
411 : // This is only valid when the plugin is actually stopped!
412 : mozilla::TimeStamp mStopTime;
413 :
414 : #ifdef MOZ_WIDGET_ANDROID
415 : mozilla::java::GeckoSurface::LocalRef CreateSurface();
416 : std::map<void*, VideoInfo*> mVideos;
417 : bool mOnScreen;
418 :
419 : nsIntSize mCurrentSize;
420 : #endif
421 :
422 : // is this instance Java and affected by bug 750480?
423 : bool mHaveJavaC2PJSObjectQuirk;
424 :
425 : static uint32_t gInUnsafePluginCalls;
426 :
427 : // The arrays can only be released when the plugin instance is destroyed,
428 : // because the plugin, in in-process mode, might keep a reference to them.
429 : uint32_t mCachedParamLength;
430 : char **mCachedParamNames;
431 : char **mCachedParamValues;
432 :
433 : nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
434 : bool mMuted;
435 : };
436 :
437 : // On Android, we need to guard against plugin code leaking entries in the local
438 : // JNI ref table. See https://bugzilla.mozilla.org/show_bug.cgi?id=780831#c21
439 : #ifdef MOZ_WIDGET_ANDROID
440 : #define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame
441 : #else
442 : #define MAIN_THREAD_JNI_REF_GUARD
443 : #endif
444 :
445 : void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState);
446 : void NS_NotifyPluginCall(NSPluginCallReentry aReentryState);
447 :
448 : #define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \
449 : PR_BEGIN_MACRO \
450 : MAIN_THREAD_JNI_REF_GUARD; \
451 : NS_NotifyBeginPluginCall(pluginCallReentry); \
452 : ret = fun; \
453 : NS_NotifyPluginCall(pluginCallReentry); \
454 : PR_END_MACRO
455 :
456 : #define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \
457 : PR_BEGIN_MACRO \
458 : MAIN_THREAD_JNI_REF_GUARD; \
459 : NS_NotifyBeginPluginCall(pluginCallReentry); \
460 : fun; \
461 : NS_NotifyPluginCall(pluginCallReentry); \
462 : PR_END_MACRO
463 :
464 : #endif // nsNPAPIPluginInstance_h_
|