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 22 #include "mozilla/EventForwards.h" 23 #include "mozilla/TimeStamp.h" 24 #include "mozilla/PluginLibrary.h" 25 #include "mozilla/RefPtr.h" 26 #include "mozilla/WeakPtr.h" 27 28 class nsPluginStreamListenerPeer; // browser-initiated stream class 29 class nsNPAPIPluginStreamListener; // plugin-initiated stream class 30 class nsIPluginInstanceOwner; 31 class nsIOutputStream; 32 class nsPluginInstanceOwner; 33 34 #if defined(OS_WIN) 35 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncWin; 36 #elif defined(MOZ_X11) 37 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncX; 38 #elif defined(XP_MACOSX) 39 #ifndef NP_NO_QUICKDRAW 40 const NPDrawingModel kDefaultDrawingModel = 41 NPDrawingModelQuickDraw; // Not supported 42 #else 43 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelCoreGraphics; 44 #endif 45 #else 46 const NPDrawingModel kDefaultDrawingModel = static_cast<NPDrawingModel>(0); 47 #endif 48 49 /** 50 * Used to indicate whether it's OK to reenter Gecko and repaint, flush frames, 51 * run scripts, etc, during this plugin call. 52 * When NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO is set, we try to avoid dangerous 53 * Gecko activities when the plugin spins a nested event loop, on a best-effort 54 * basis. 55 */ 56 enum NSPluginCallReentry { 57 NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO, 58 NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO 59 }; 60 61 class nsNPAPITimer { 62 public: 63 NPP npp; 64 uint32_t id; 65 nsCOMPtr<nsITimer> timer; 66 void (*callback)(NPP npp, uint32_t timerID); 67 bool inCallback; 68 bool needUnschedule; 69 }; 70 71 class nsNPAPIPluginInstance final 72 : public nsIAudioChannelAgentCallback, 73 public mozilla::SupportsWeakPtr<nsNPAPIPluginInstance> { 74 private: 75 typedef mozilla::PluginLibrary PluginLibrary; 76 77 public: 78 typedef mozilla::gfx::DrawTarget DrawTarget; 79 80 MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance) 81 NS_DECL_THREADSAFE_ISUPPORTS 82 NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK 83 84 nsresult Initialize(nsNPAPIPlugin* aPlugin, nsPluginInstanceOwner* aOwner, 85 const nsACString& aMIMEType); 86 nsresult Start(); 87 nsresult Stop(); 88 nsresult SetWindow(NPWindow* window); 89 nsresult NewStreamFromPlugin(const char* type, const char* target, 90 nsIOutputStream** result); 91 nsresult Print(NPPrint* platformPrint); 92 nsresult HandleEvent(void* event, int16_t* result, 93 NSPluginCallReentry aSafeToReenterGecko = 94 NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 95 nsresult GetValueFromPlugin(NPPVariable variable, void* value); 96 nsresult GetDrawingModel(int32_t* aModel); 97 nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing); 98 nsresult ContentsScaleFactorChanged(double aContentsScaleFactor); 99 nsresult CSSZoomFactorChanged(float aCSSZoomFactor); 100 nsresult GetJSObject(JSContext* cx, JSObject** outObject); 101 bool ShouldCache(); 102 nsresult IsWindowless(bool* isWindowless); 103 nsresult AsyncSetWindow(NPWindow* window); 104 nsresult GetImageContainer(mozilla::layers::ImageContainer** aContainer); 105 nsresult GetImageSize(nsIntSize* aSize); 106 nsresult NotifyPainted(void); 107 nsresult GetIsOOP(bool* aIsOOP); 108 nsresult SetBackgroundUnknown(); 109 nsresult BeginUpdateBackground(nsIntRect* aRect, DrawTarget** aContext); 110 nsresult EndUpdateBackground(nsIntRect* aRect); 111 nsresult IsTransparent(bool* isTransparent); 112 nsresult GetFormValue(nsAString& aValue); 113 nsresult PushPopupsEnabledState(bool aEnabled); 114 nsresult PopPopupsEnabledState(); 115 nsresult GetPluginAPIVersion(uint16_t* version); 116 nsresult InvalidateRect(NPRect* invalidRect); 117 nsresult InvalidateRegion(NPRegion invalidRegion); 118 nsresult GetMIMEType(const char** result); 119 #if defined(XP_WIN) 120 nsresult GetScrollCaptureContainer( 121 mozilla::layers::ImageContainer** aContainer); 122 #endif 123 nsresult HandledWindowedPluginKeyEvent( 124 const mozilla::NativeEventData& aKeyEventData, bool aIsConsumed); 125 nsPluginInstanceOwner* GetOwner(); 126 void SetOwner(nsPluginInstanceOwner* aOwner); 127 void DidComposite(); 128 HasAudioChannelAgent()129 bool HasAudioChannelAgent() const { return !!mAudioChannelAgent; } 130 131 void NotifyStartedPlaying(); 132 void NotifyStoppedPlaying(); 133 134 nsresult SetMuted(bool aIsMuted); 135 136 nsNPAPIPlugin* GetPlugin(); 137 138 nsresult GetNPP(NPP* aNPP); 139 140 NPError SetWindowless(bool aWindowless); 141 142 NPError SetTransparent(bool aTransparent); 143 144 NPError SetWantsAllNetworkStreams(bool aWantsAllNetworkStreams); 145 146 NPError SetUsesDOMForCursor(bool aUsesDOMForCursor); 147 bool UsesDOMForCursor(); 148 149 void SetDrawingModel(NPDrawingModel aModel); 150 void RedrawPlugin(); 151 #ifdef XP_MACOSX 152 void SetEventModel(NPEventModel aModel); 153 GetCurrentEvent()154 void* GetCurrentEvent() { return mCurrentPluginEvent; } 155 #endif 156 157 nsresult NewStreamListener(const char* aURL, void* notifyData, 158 nsNPAPIPluginStreamListener** listener); 159 160 nsNPAPIPluginInstance(); 161 162 // To be called when an instance becomes orphaned, when 163 // it's plugin is no longer guaranteed to be around. 164 void Destroy(); 165 166 // Indicates whether the plugin is running normally. IsRunning()167 bool IsRunning() { return RUNNING == mRunning; } HasStartedDestroying()168 bool HasStartedDestroying() { return mRunning >= DESTROYING; } 169 170 // Indicates whether the plugin is running normally or being shut down CanFireNotifications()171 bool CanFireNotifications() { 172 return mRunning == RUNNING || mRunning == DESTROYING; 173 } 174 175 // return is only valid when the plugin is not running 176 mozilla::TimeStamp StopTime(); 177 178 // cache this NPAPI plugin 179 void SetCached(bool aCache); 180 181 already_AddRefed<nsPIDOMWindowOuter> GetDOMWindow(); 182 183 nsresult PrivateModeStateChanged(bool aEnabled); 184 185 nsresult IsPrivateBrowsing(bool* aEnabled); 186 187 nsresult GetDOMElement(nsIDOMElement** result); 188 189 nsNPAPITimer* TimerWithID(uint32_t id, uint32_t* index); 190 uint32_t ScheduleTimer(uint32_t interval, NPBool repeat, 191 void (*timerFunc)(NPP npp, uint32_t timerID)); 192 void UnscheduleTimer(uint32_t timerID); 193 NPBool ConvertPoint(double sourceX, double sourceY, 194 NPCoordinateSpace sourceSpace, double* destX, 195 double* destY, NPCoordinateSpace destSpace); 196 197 nsTArray<nsNPAPIPluginStreamListener*>* StreamListeners(); 198 199 nsTArray<nsPluginStreamListenerPeer*>* FileCachedStreamListeners(); 200 201 nsresult AsyncSetWindow(NPWindow& window); 202 203 void URLRedirectResponse(void* notifyData, NPBool allow); 204 205 NPError InitAsyncSurface(NPSize* size, NPImageFormat format, void* initData, 206 NPAsyncSurface* surface); 207 NPError FinalizeAsyncSurface(NPAsyncSurface* surface); 208 void SetCurrentAsyncSurface(NPAsyncSurface* surface, NPRect* changed); 209 210 // Returns the contents scale factor of the screen the plugin is drawn on. 211 double GetContentsScaleFactor(); 212 213 // Returns the css zoom factor of the document the plugin is drawn on. 214 float GetCSSZoomFactor(); 215 216 nsresult GetRunID(uint32_t* aRunID); 217 InPluginCallUnsafeForReentry()218 static bool InPluginCallUnsafeForReentry() { 219 return gInUnsafePluginCalls > 0; 220 } BeginPluginCall(NSPluginCallReentry aReentryState)221 static void BeginPluginCall(NSPluginCallReentry aReentryState) { 222 if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { 223 ++gInUnsafePluginCalls; 224 } 225 } EndPluginCall(NSPluginCallReentry aReentryState)226 static void EndPluginCall(NSPluginCallReentry aReentryState) { 227 if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) { 228 NS_ASSERTION(gInUnsafePluginCalls > 0, "Must be in plugin call"); 229 --gInUnsafePluginCalls; 230 } 231 } 232 233 protected: 234 virtual ~nsNPAPIPluginInstance(); 235 236 nsresult GetTagType(nsPluginTagType* result); 237 238 nsresult CreateAudioChannelAgentIfNeeded(); 239 240 // The structure used to communicate between the plugin instance and 241 // the browser. 242 NPP_t mNPP; 243 244 NPDrawingModel mDrawingModel; 245 246 enum { NOT_STARTED, RUNNING, DESTROYING, DESTROYED } mRunning; 247 248 // these are used to store the windowless properties 249 // which the browser will later query 250 bool mWindowless; 251 bool mTransparent; 252 bool mCached; 253 bool mUsesDOMForCursor; 254 255 public: 256 // True while creating the plugin, or calling NPP_SetWindow() on it. 257 bool mInPluginInitCall; 258 259 private: 260 RefPtr<nsNPAPIPlugin> mPlugin; 261 262 nsTArray<nsNPAPIPluginStreamListener*> mStreamListeners; 263 264 nsTArray<nsPluginStreamListenerPeer*> mFileCachedStreamListeners; 265 266 nsTArray<PopupControlState> mPopupStates; 267 268 char* mMIMEType; 269 270 // Weak pointer to the owner. The owner nulls this out (by calling 271 // InvalidateOwner()) when it's no longer our owner. 272 nsPluginInstanceOwner* mOwner; 273 274 nsTArray<nsNPAPITimer*> mTimers; 275 276 #ifdef XP_MACOSX 277 // non-null during a HandleEvent call 278 void* mCurrentPluginEvent; 279 #endif 280 281 // Timestamp for the last time this plugin was stopped. 282 // This is only valid when the plugin is actually stopped! 283 mozilla::TimeStamp mStopTime; 284 285 // is this instance Java and affected by bug 750480? 286 bool mHaveJavaC2PJSObjectQuirk; 287 288 static uint32_t gInUnsafePluginCalls; 289 290 // The arrays can only be released when the plugin instance is destroyed, 291 // because the plugin, in in-process mode, might keep a reference to them. 292 uint32_t mCachedParamLength; 293 char** mCachedParamNames; 294 char** mCachedParamValues; 295 296 nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent; 297 bool mMuted; 298 }; 299 300 void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState); 301 void NS_NotifyPluginCall(NSPluginCallReentry aReentryState); 302 303 #define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \ 304 PR_BEGIN_MACRO \ 305 NS_NotifyBeginPluginCall(pluginCallReentry); \ 306 ret = fun; \ 307 NS_NotifyPluginCall(pluginCallReentry); \ 308 PR_END_MACRO 309 310 #define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \ 311 PR_BEGIN_MACRO \ 312 NS_NotifyBeginPluginCall(pluginCallReentry); \ 313 fun; \ 314 NS_NotifyPluginCall(pluginCallReentry); \ 315 PR_END_MACRO 316 317 #endif // nsNPAPIPluginInstance_h_ 318