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