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
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.
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"
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"
72 #include "nsIFactory.h"
75 class nsIComponentManager
;
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
88 * A linked-list of plugin information that is used for
89 * instantiating plugins and reflecting plugin information
92 class nsPluginTag
: public 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
,
110 PRInt64 aLastModifiedTime
= 0,
111 PRBool aCanUnload
= PR_TRUE
,
112 PRBool aArgsAreUTF8
= PR_FALSE
);
116 void SetHost(nsPluginHostImpl
* aHost
);
117 void TryUnloadPlugin(PRBool aForceShutdown
= PR_FALSE
);
118 void Mark(PRUint32 mask
) {
119 PRBool wasEnabled
= IsEnabled();
121 // Update entries in the category manager if necessary.
122 if (mPluginHost
&& wasEnabled
!= IsEnabled()) {
124 RegisterWithCategoryManager(PR_FALSE
, nsPluginTag::ePluginUnregister
);
126 RegisterWithCategoryManager(PR_FALSE
, nsPluginTag::ePluginRegister
);
129 void UnMark(PRUint32 mask
) {
130 PRBool wasEnabled
= IsEnabled();
132 // Update entries in the category manager if necessary.
133 if (mPluginHost
&& wasEnabled
!= IsEnabled()) {
135 RegisterWithCategoryManager(PR_FALSE
, nsPluginTag::ePluginUnregister
);
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
{
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
157 char **mMimeTypeArray
;
158 nsTArray
<nsCString
> mMimeDescriptionArray
; // UTF-8
159 char **mExtensionsArray
;
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
;
173 nsresult
EnsureMembersAreUTF8();
176 struct nsActivePlugin
178 nsActivePlugin
* mNext
;
180 nsIPluginInstancePeer
* mPeer
;
181 nsRefPtr
<nsPluginTag
> mPluginTag
;
182 nsIPluginInstance
* mInstance
;
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
,
193 PRBool aDefaultPlugin
,
194 nsIPluginInstancePeer
*peer
);
197 void setStopped(PRBool stopped
);
200 class nsActivePluginList
203 nsActivePlugin
* mFirst
;
204 nsActivePlugin
* mLast
;
207 nsActivePluginList();
208 ~nsActivePluginList();
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
,
228 public nsPIPluginHost
,
229 public nsSupportsWeakReference
233 virtual ~nsPluginHostImpl();
235 static nsPluginHostImpl
* GetInst();
237 NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
241 static const char *GetPluginName(nsIPluginInstance
*aPluginInstance
);
243 //nsIPluginManager interface - the main interface nsIPlugin communicates to
246 GetValue(nsPluginManagerVariable variable
, void *value
);
249 ReloadPlugins(PRBool reloadPages
);
252 UserAgent(const char* *resultingAgentString
);
255 GetURL(nsISupports
* pluginInst
,
257 const char* target
= NULL
,
258 nsIPluginStreamListener
* streamListener
= NULL
,
259 const char* altHost
= NULL
,
260 const char* referrer
= NULL
,
261 PRBool forceJSEnabled
= PR_FALSE
);
264 GetURLWithHeaders(nsISupports
* pluginInst
,
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
);
275 PostURL(nsISupports
* pluginInst
,
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
);
289 RegisterPlugin(REFNSIID aCID
,
290 const char* aPluginName
,
291 const char* aDescription
,
292 const char** aMimeTypes
,
293 const char** aMimeDescriptions
,
294 const char** aFileExtensions
,
298 UnregisterPlugin(REFNSIID aCID
);
300 //nsIPluginHost interface - used to communicate to the nsPluginInstanceOwner
302 NS_DECL_NSIPLUGINHOST
303 NS_DECL_NSIPLUGINMANAGER2
306 ProcessNextEvent(PRBool
*bEventHandled
);
308 // XXX not currently used?
310 NS_DECL_NSIFILEUTILITIES
311 NS_DECL_NSICOOKIESTORAGE
313 NS_DECL_NSPIPLUGINHOST
315 /* Called by GetURL and PostURL */
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);
328 DoURLLoadSecurityCheck(nsIPluginInstance
*aInstance
,
332 AddHeadersToChannel(const char *aHeadersData
, PRUint32 aHeadersDataLen
,
333 nsIChannel
*aGenericChannel
);
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
346 static PRBool
IsJavaMIMEType(const char *aType
);
350 TrySetUpPluginInstance(const char *aMimeType
, nsIURI
*aURL
, nsIPluginInstanceOwner
*aOwner
);
353 LoadXPCOMPlugins(nsIComponentManager
* aComponentManager
);
356 NewEmbeddedPluginStreamListener(nsIURI
* aURL
, nsIPluginInstanceOwner
*aOwner
,
357 nsIPluginInstance
* aInstance
,
358 nsIStreamListener
** aListener
);
361 NewEmbeddedPluginStream(nsIURI
* aURL
, nsIPluginInstanceOwner
*aOwner
, nsIPluginInstance
* aInstance
);
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.
369 FindPluginForType(const char* aMimeType
, PRBool aCheckEnabled
);
372 FindPluginEnabledForExtension(const char* aExtension
, const char* &aMimeType
);
375 FindStoppedPluginForURL(nsIURI
* aURL
, nsIPluginInstanceOwner
*aOwner
);
378 SetUpDefaultPluginInstance(const char *aMimeType
, nsIURI
*aURL
, nsIPluginInstanceOwner
*aOwner
);
381 AddInstanceToActiveList(nsCOMPtr
<nsIPlugin
> aPlugin
,
382 nsIPluginInstance
* aInstance
,
383 nsIURI
* aURL
, PRBool aDefaultPlugin
,
384 nsIPluginInstancePeer
*peer
);
387 FindPlugins(PRBool aCreatePluginList
, PRBool
* aPluginsChanged
);
390 ScanPluginsDirectory(nsIFile
* pluginsDir
,
391 nsIComponentManager
* compManager
,
392 PRBool aCreatePluginList
,
393 PRBool
* aPluginsChanged
,
394 PRBool checkForUnwantedPlugins
= PR_FALSE
);
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();
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
;
461 nsRefPtr
<nsPluginDirServiceProvider
> mPrivateDirServiceProvider
;
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
476 PluginDestructionGuard(nsIPluginInstance
*aInstance
)
477 : mInstance(aInstance
)
482 PluginDestructionGuard(NPP npp
)
483 : mInstance(npp
? static_cast<nsNPAPIPluginInstance
*>(npp
->ndata
) : nsnull
)
488 ~PluginDestructionGuard();
490 static PRBool
DelayDestroy(nsIPluginInstance
*aInstance
);
495 NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
497 mDelayedDestroy
= PR_FALSE
;
500 PR_INSERT_BEFORE(this, &sListHead
);
503 nsCOMPtr
<nsIPluginInstance
> mInstance
;
504 PRBool mDelayedDestroy
;
506 static PRCList sListHead
;