Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / modules / plugin / base / src / nsPluginHostImpl.h
blobe7686b34030d0389135a1cfbf57d0a89a5e3d875
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsPluginHostImpl_h__
39 #define nsPluginHostImpl_h__
41 #include "nsIPluginManager.h"
42 #include "nsIPluginManager2.h"
43 #include "nsIPluginHost.h"
44 #include "nsIObserver.h"
45 #include "nsPIPluginHost.h"
46 #include "nsCRT.h"
47 #include "nsCOMPtr.h"
48 #include "prlink.h"
49 #include "prclist.h"
50 #include "npapi.h"
51 #include "nsNPAPIPluginInstance.h"
53 #include "nsIPlugin.h"
54 #include "nsIPluginTag.h"
55 #include "nsIPluginTagInfo2.h"
56 #include "nsIPluginInstancePeer2.h"
58 #include "nsIFileUtilities.h"
59 #include "nsICookieStorage.h"
60 #include "nsPluginsDir.h"
61 #include "nsVoidArray.h"
62 #include "nsPluginDirServiceProvider.h"
63 #include "nsAutoPtr.h"
64 #include "nsWeakPtr.h"
65 #include "nsIPrompt.h"
66 #include "nsISupportsArray.h"
67 #include "nsPluginNativeWindow.h"
68 #include "nsIPrefBranch.h"
69 #include "nsWeakReference.h"
70 #include "nsThreadUtils.h"
71 #include "nsTArray.h"
72 #include "nsIFactory.h"
74 class nsNPAPIPlugin;
75 class nsIComponentManager;
76 class nsIFile;
77 class nsIChannel;
78 class nsIRegistry;
79 class nsPluginHostImpl;
81 #define NS_PLUGIN_FLAG_ENABLED 0x0001 // is this plugin enabled?
82 #define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 // is this a pre-xpcom plugin?
83 #define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
84 #define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugin
85 #define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin
87 /**
88 * A linked-list of plugin information that is used for
89 * instantiating plugins and reflecting plugin information
90 * into JavaScript.
92 class nsPluginTag : public nsIPluginTag
94 public:
95 NS_DECL_ISUPPORTS
96 NS_DECL_NSIPLUGINTAG
98 nsPluginTag(nsPluginTag* aPluginTag);
99 nsPluginTag(nsPluginInfo* aPluginInfo);
101 nsPluginTag(const char* aName,
102 const char* aDescription,
103 const char* aFileName,
104 const char* aFullPath,
105 const char* aVersion,
106 const char* const* aMimeTypes,
107 const char* const* aMimeDescriptions,
108 const char* const* aExtensions,
109 PRInt32 aVariants,
110 PRInt64 aLastModifiedTime = 0,
111 PRBool aCanUnload = PR_TRUE,
112 PRBool aArgsAreUTF8 = PR_FALSE);
114 ~nsPluginTag();
116 void SetHost(nsPluginHostImpl * aHost);
117 void TryUnloadPlugin(PRBool aForceShutdown = PR_FALSE);
118 void Mark(PRUint32 mask) {
119 PRBool wasEnabled = IsEnabled();
120 mFlags |= mask;
121 // Update entries in the category manager if necessary.
122 if (mPluginHost && wasEnabled != IsEnabled()) {
123 if (wasEnabled)
124 RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
125 else
126 RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
129 void UnMark(PRUint32 mask) {
130 PRBool wasEnabled = IsEnabled();
131 mFlags &= ~mask;
132 // Update entries in the category manager if necessary.
133 if (mPluginHost && wasEnabled != IsEnabled()) {
134 if (wasEnabled)
135 RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
136 else
137 RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
140 PRBool HasFlag(PRUint32 flag) { return (mFlags & flag) != 0; }
141 PRUint32 Flags() { return mFlags; }
142 PRBool Equals(nsPluginTag* aPluginTag);
143 PRBool IsEnabled() { return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED); }
145 enum nsRegisterType {
146 ePluginRegister,
147 ePluginUnregister
149 void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
150 nsRegisterType aType = ePluginRegister);
152 nsRefPtr<nsPluginTag> mNext;
153 nsPluginHostImpl *mPluginHost;
154 nsCString mName; // UTF-8
155 nsCString mDescription; // UTF-8
156 PRInt32 mVariants;
157 char **mMimeTypeArray;
158 nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
159 char **mExtensionsArray;
160 PRLibrary *mLibrary;
161 nsIPlugin *mEntryPoint;
162 PRPackedBool mCanUnloadLibrary;
163 PRPackedBool mXPConnected;
164 PRPackedBool mIsJavaPlugin;
165 PRPackedBool mIsNPRuntimeEnabledJavaPlugin;
166 nsCString mFileName; // UTF-8
167 nsCString mFullPath; // UTF-8
168 nsCString mVersion; // UTF-8
169 PRInt64 mLastModifiedTime;
170 private:
171 PRUint32 mFlags;
173 nsresult EnsureMembersAreUTF8();
176 struct nsActivePlugin
178 nsActivePlugin* mNext;
179 char* mURL;
180 nsIPluginInstancePeer* mPeer;
181 nsRefPtr<nsPluginTag> mPluginTag;
182 nsIPluginInstance* mInstance;
183 PRTime mllStopTime;
184 PRPackedBool mStopped;
185 PRPackedBool mDefaultPlugin;
186 PRPackedBool mXPConnected;
187 // Array holding all opened stream listeners for this entry
188 nsCOMPtr <nsISupportsArray> mStreams;
190 nsActivePlugin(nsPluginTag* aPluginTag,
191 nsIPluginInstance* aInstance,
192 const char * url,
193 PRBool aDefaultPlugin,
194 nsIPluginInstancePeer *peer);
195 ~nsActivePlugin();
197 void setStopped(PRBool stopped);
200 class nsActivePluginList
202 public:
203 nsActivePlugin * mFirst;
204 nsActivePlugin * mLast;
205 PRInt32 mCount;
207 nsActivePluginList();
208 ~nsActivePluginList();
210 void shut();
211 PRBool add(nsActivePlugin * plugin);
212 PRBool remove(nsActivePlugin * plugin);
213 nsActivePlugin * find(nsIPluginInstance* instance);
214 nsActivePlugin * find(const char * mimetype);
215 nsActivePlugin * findStopped(const char * url);
216 PRUint32 getStoppedCount();
217 nsActivePlugin * findOldestStopped();
218 void removeAllStopped();
219 void stopRunning(nsISupportsArray* aReloadDocs, nsPluginTag* aPluginTag);
220 PRBool IsLastInstance(nsActivePlugin * plugin);
223 class nsPluginHostImpl : public nsIPluginManager2,
224 public nsIPluginHost,
225 public nsIFileUtilities,
226 public nsICookieStorage,
227 public nsIObserver,
228 public nsPIPluginHost,
229 public nsSupportsWeakReference
231 public:
232 nsPluginHostImpl();
233 virtual ~nsPluginHostImpl();
235 static nsPluginHostImpl* GetInst();
237 NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
239 NS_DECL_ISUPPORTS
241 static const char *GetPluginName(nsIPluginInstance *aPluginInstance);
243 //nsIPluginManager interface - the main interface nsIPlugin communicates to
245 NS_IMETHOD
246 GetValue(nsPluginManagerVariable variable, void *value);
248 NS_IMETHOD
249 ReloadPlugins(PRBool reloadPages);
251 NS_IMETHOD
252 UserAgent(const char* *resultingAgentString);
254 NS_IMETHOD
255 GetURL(nsISupports* pluginInst,
256 const char* url,
257 const char* target = NULL,
258 nsIPluginStreamListener* streamListener = NULL,
259 const char* altHost = NULL,
260 const char* referrer = NULL,
261 PRBool forceJSEnabled = PR_FALSE);
263 NS_IMETHOD
264 GetURLWithHeaders(nsISupports* pluginInst,
265 const char* url,
266 const char* target = NULL,
267 nsIPluginStreamListener* streamListener = NULL,
268 const char* altHost = NULL,
269 const char* referrer = NULL,
270 PRBool forceJSEnabled = PR_FALSE,
271 PRUint32 getHeadersLength = 0,
272 const char* getHeaders = NULL);
274 NS_IMETHOD
275 PostURL(nsISupports* pluginInst,
276 const char* url,
277 PRUint32 postDataLen,
278 const char* postData,
279 PRBool isFile = PR_FALSE,
280 const char* target = NULL,
281 nsIPluginStreamListener* streamListener = NULL,
282 const char* altHost = NULL,
283 const char* referrer = NULL,
284 PRBool forceJSEnabled = PR_FALSE,
285 PRUint32 postHeadersLength = 0,
286 const char* postHeaders = NULL);
288 NS_IMETHOD
289 RegisterPlugin(REFNSIID aCID,
290 const char* aPluginName,
291 const char* aDescription,
292 const char** aMimeTypes,
293 const char** aMimeDescriptions,
294 const char** aFileExtensions,
295 PRInt32 aCount);
297 NS_IMETHOD
298 UnregisterPlugin(REFNSIID aCID);
300 //nsIPluginHost interface - used to communicate to the nsPluginInstanceOwner
302 NS_DECL_NSIPLUGINHOST
303 NS_DECL_NSIPLUGINMANAGER2
305 NS_IMETHOD
306 ProcessNextEvent(PRBool *bEventHandled);
308 // XXX not currently used?
309 NS_DECL_NSIFACTORY
310 NS_DECL_NSIFILEUTILITIES
311 NS_DECL_NSICOOKIESTORAGE
312 NS_DECL_NSIOBSERVER
313 NS_DECL_NSPIPLUGINHOST
315 /* Called by GetURL and PostURL */
317 NS_IMETHOD
318 NewPluginURLStream(const nsString& aURL,
319 nsIPluginInstance *aInstance,
320 nsIPluginStreamListener *aListener,
321 const char *aPostData = nsnull,
322 PRBool isFile = PR_FALSE,
323 PRUint32 aPostDataLen = 0,
324 const char *aHeadersData = nsnull,
325 PRUint32 aHeadersDataLen = 0);
327 nsresult
328 DoURLLoadSecurityCheck(nsIPluginInstance *aInstance,
329 const char* aURL);
331 NS_IMETHOD
332 AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
333 nsIChannel *aGenericChannel);
335 NS_IMETHOD
336 AddUnusedLibrary(PRLibrary * aLibrary);
338 static nsresult GetPluginTempDir(nsIFile **aDir);
340 // Writes updated plugins settings to disk and unloads the plugin
341 // if it is now disabled
342 nsresult UpdatePluginInfo(nsPluginTag* aPluginTag);
344 // checks whether aTag is a "java" plugin tag (a tag for a plugin
345 // that does Java)
346 static PRBool IsJavaMIMEType(const char *aType);
348 private:
349 NS_IMETHOD
350 TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
352 nsresult
353 LoadXPCOMPlugins(nsIComponentManager* aComponentManager);
355 nsresult
356 NewEmbeddedPluginStreamListener(nsIURI* aURL, nsIPluginInstanceOwner *aOwner,
357 nsIPluginInstance* aInstance,
358 nsIStreamListener** aListener);
360 nsresult
361 NewEmbeddedPluginStream(nsIURI* aURL, nsIPluginInstanceOwner *aOwner, nsIPluginInstance* aInstance);
363 nsresult
364 NewFullPagePluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance);
366 // Return an nsPluginTag for this type, if any. If aCheckEnabled is
367 // true, only enabled plugins will be returned.
368 nsPluginTag*
369 FindPluginForType(const char* aMimeType, PRBool aCheckEnabled);
371 nsPluginTag*
372 FindPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
374 nsresult
375 FindStoppedPluginForURL(nsIURI* aURL, nsIPluginInstanceOwner *aOwner);
377 nsresult
378 SetUpDefaultPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
380 nsresult
381 AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
382 nsIPluginInstance* aInstance,
383 nsIURI* aURL, PRBool aDefaultPlugin,
384 nsIPluginInstancePeer *peer);
386 nsresult
387 FindPlugins(PRBool aCreatePluginList, PRBool * aPluginsChanged);
389 nsresult
390 ScanPluginsDirectory(nsIFile * pluginsDir,
391 nsIComponentManager * compManager,
392 PRBool aCreatePluginList,
393 PRBool * aPluginsChanged,
394 PRBool checkForUnwantedPlugins = PR_FALSE);
396 nsresult
397 ScanPluginsDirectoryList(nsISimpleEnumerator * dirEnum,
398 nsIComponentManager * compManager,
399 PRBool aCreatePluginList,
400 PRBool * aPluginsChanged,
401 PRBool checkForUnwantedPlugins = PR_FALSE);
403 PRBool IsRunningPlugin(nsPluginTag * plugin);
405 // Stores all plugins info into the registry
406 nsresult WritePluginInfo();
408 // Loads all cached plugins info into mCachedPlugins
409 nsresult ReadPluginInfo();
411 // Given a filename, returns the plugins info from our cache
412 // and removes it from the cache.
413 void RemoveCachedPluginsInfo(const char *filename,
414 nsPluginTag **result);
416 //checks if the list already have the same plugin as given
417 nsPluginTag* HaveSamePlugin(nsPluginTag * aPluginTag);
419 // checks if given plugin is a duplicate of what we already have
420 // in the plugin list but found in some different place
421 PRBool IsDuplicatePlugin(nsPluginTag * aPluginTag);
423 nsresult EnsurePrivateDirServiceProvider();
425 nsresult GetPrompt(nsIPluginInstanceOwner *aOwner, nsIPrompt **aPrompt);
427 // one-off hack to include nppl3260.dll from the components folder
428 nsresult ScanForRealInComponentsFolder(nsIComponentManager * aCompManager);
430 // calls PostPluginUnloadEvent for each library in mUnusedLibraries
431 void UnloadUnusedLibraries();
433 // Add our pref observer
434 nsresult AddPrefObserver();
436 char *mPluginPath;
437 nsRefPtr<nsPluginTag> mPlugins;
438 nsRefPtr<nsPluginTag> mCachedPlugins;
439 PRPackedBool mPluginsLoaded;
440 PRPackedBool mDontShowBadPluginMessage;
441 PRPackedBool mIsDestroyed;
443 // set by pref plugin.override_internal_types
444 PRPackedBool mOverrideInternalTypes;
446 // set by pref plugin.allow_alien_star_handler
447 PRPackedBool mAllowAlienStarHandler;
449 // set by pref plugin.default_plugin_disabled
450 PRPackedBool mDefaultPluginDisabled;
452 // Whether java is enabled
453 PRPackedBool mJavaEnabled;
455 nsActivePluginList mActivePluginList;
456 nsVoidArray mUnusedLibraries;
458 nsCOMPtr<nsIFile> mPluginRegFile;
459 nsCOMPtr<nsIPrefBranch> mPrefService;
460 #ifdef XP_WIN
461 nsRefPtr<nsPluginDirServiceProvider> mPrivateDirServiceProvider;
462 #endif /* XP_WIN */
464 nsWeakPtr mCurrentDocument; // weak reference, we use it to id document only
466 static nsIFile *sPluginTempDir;
468 // We need to hold a global ptr to ourselves because we register for
469 // two different CIDs for some reason...
470 static nsPluginHostImpl* sInst;
473 class NS_STACK_CLASS PluginDestructionGuard : protected PRCList
475 public:
476 PluginDestructionGuard(nsIPluginInstance *aInstance)
477 : mInstance(aInstance)
479 Init();
482 PluginDestructionGuard(NPP npp)
483 : mInstance(npp ? static_cast<nsNPAPIPluginInstance*>(npp->ndata) : nsnull)
485 Init();
488 ~PluginDestructionGuard();
490 static PRBool DelayDestroy(nsIPluginInstance *aInstance);
492 protected:
493 void Init()
495 NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
497 mDelayedDestroy = PR_FALSE;
499 PR_INIT_CLIST(this);
500 PR_INSERT_BEFORE(this, &sListHead);
503 nsCOMPtr<nsIPluginInstance> mInstance;
504 PRBool mDelayedDestroy;
506 static PRCList sListHead;
509 #endif