mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Get rid of nsPluginInstanceTagList. Make this code easier to deal with and less error-prone. b=535643 r=jst
This commit is contained in:
parent
8c4dcf819d
commit
e348c30e79
@ -1041,7 +1041,10 @@ _geturl(NPP npp, const char* relativeURL, const char* target)
|
||||
(strncmp(relativeURL, "ftp:", 4) != 0)) {
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
|
||||
|
||||
const char *name = nsPluginHost::GetPluginName(inst);
|
||||
|
||||
const char *name;
|
||||
nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
|
||||
host->GetPluginName(inst, &name);
|
||||
|
||||
if (name && strstr(name, "Adobe") && strstr(name, "Acrobat")) {
|
||||
return NPERR_NO_ERROR;
|
||||
|
@ -151,6 +151,7 @@
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentErrors.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "windows.h"
|
||||
@ -161,6 +162,8 @@
|
||||
#include <gdk/gdkx.h> // for GDK_DISPLAY()
|
||||
#endif
|
||||
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
// Null out a strong ref to a linked list iteratively to avoid
|
||||
// exhausting the stack (bug 486349).
|
||||
#define NS_ITERATIVE_UNREF_LIST(type_, list_, mNext_) \
|
||||
@ -226,8 +229,6 @@ PRLogModuleInfo* nsPluginLogging::gPluginLog = nsnull;
|
||||
|
||||
#define MAGIC_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
static nsPluginInstanceTagList *gActivePluginList;
|
||||
|
||||
#ifdef CALL_SAFETY_ON
|
||||
PRBool gSkipPluginSafeCalls = PR_FALSE;
|
||||
#endif
|
||||
@ -453,8 +454,7 @@ public:
|
||||
|
||||
nsresult InitializeEmbedded(nsIURI *aURL,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIPluginInstanceOwner *aOwner = nsnull,
|
||||
nsIPluginHost *aHost = nsnull);
|
||||
nsIPluginInstanceOwner *aOwner = nsnull);
|
||||
|
||||
nsresult InitializeFullPage(nsIPluginInstance *aInstance);
|
||||
|
||||
@ -489,7 +489,6 @@ private:
|
||||
char *mMIMEType;
|
||||
PRUint32 mLength;
|
||||
PRInt32 mStreamType;
|
||||
nsIPluginHost *mHost;
|
||||
|
||||
// local cached file, we save the content into local cache if browser cache is not available,
|
||||
// or plugin asks stream as file and it expects file extension until bug 90558 got fixed
|
||||
@ -822,7 +821,6 @@ nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
|
||||
mOwner = nsnull;
|
||||
mInstance = nsnull;
|
||||
mPStreamListener = nsnull;
|
||||
mHost = nsnull;
|
||||
mStreamType = NP_NORMAL;
|
||||
mStartBinding = PR_FALSE;
|
||||
mAbort = PR_FALSE;
|
||||
@ -848,7 +846,6 @@ nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
||||
NS_IF_RELEASE(mOwner);
|
||||
NS_IF_RELEASE(mInstance);
|
||||
NS_IF_RELEASE(mPStreamListener);
|
||||
NS_IF_RELEASE(mHost);
|
||||
|
||||
// close FD of mFileCacheOutputStream if it's still open
|
||||
// or we won't be able to remove the cache file
|
||||
@ -929,12 +926,11 @@ nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
||||
/* Called by NewEmbeddedPluginStream() - if this is called, we weren't
|
||||
* able to load the plugin, so we need to load it later once we figure
|
||||
* out the mimetype. In order to load it later, we need the plugin
|
||||
* host and instance owner.
|
||||
* instance owner.
|
||||
*/
|
||||
nsresult nsPluginStreamListenerPeer::InitializeEmbedded(nsIURI *aURL,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIPluginInstanceOwner *aOwner,
|
||||
nsIPluginHost *aHost)
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
#ifdef PLUGIN_LOGGING
|
||||
nsCAutoString urlSpec;
|
||||
@ -956,9 +952,6 @@ nsresult nsPluginStreamListenerPeer::InitializeEmbedded(nsIURI *aURL,
|
||||
} else {
|
||||
mOwner = aOwner;
|
||||
NS_IF_ADDREF(mOwner);
|
||||
|
||||
mHost = aHost;
|
||||
NS_IF_ADDREF(mHost);
|
||||
}
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
@ -1011,33 +1004,33 @@ nsresult
|
||||
nsPluginStreamListenerPeer::SetupPluginCacheFile(nsIChannel* channel)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// lets try to reused a file if we already have in the local plugin cache
|
||||
// we loop through all of active plugins
|
||||
// and call |nsPluginStreamInfo::UseExistingPluginCacheFile()| on opened stream
|
||||
// will return RP_TRUE if file exisrs
|
||||
// and some conditions are matched, in this case that file will be use
|
||||
// in |::OnFileAvailable()| calls w/o rewriting the file again.
|
||||
// The file will be deleted in |nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer|
|
||||
|
||||
PRBool useExistingCacheFile = PR_FALSE;
|
||||
nsPluginInstanceTag *pActivePlugins = gActivePluginList->mFirst;
|
||||
while (pActivePlugins && pActivePlugins->mStreams && !useExistingCacheFile) {
|
||||
// most recent streams are at the end of list
|
||||
PRInt32 cnt;
|
||||
pActivePlugins->mStreams->Count((PRUint32*)&cnt);
|
||||
while (--cnt >= 0 && !useExistingCacheFile) {
|
||||
nsPluginStreamListenerPeer *lp =
|
||||
reinterpret_cast<nsPluginStreamListenerPeer *>(pActivePlugins->mStreams->ElementAt(cnt));
|
||||
if (lp) {
|
||||
if (lp->mLocalCachedFile &&
|
||||
lp->mPluginStreamInfo &&
|
||||
(useExistingCacheFile =
|
||||
lp->mPluginStreamInfo->UseExistingPluginCacheFile(mPluginStreamInfo))) {
|
||||
NS_ADDREF(mLocalCachedFile = lp->mLocalCachedFile);
|
||||
|
||||
nsRefPtr<nsPluginHost> pluginHost = dont_AddRef(nsPluginHost::GetInst());
|
||||
nsTArray< nsAutoPtr<nsPluginInstanceTag> > *instanceTags = pluginHost->InstanceTagArray();
|
||||
for (PRUint32 i = 0; i < instanceTags->Length(); i++) {
|
||||
nsPluginInstanceTag *instanceTag = (*instanceTags)[i];
|
||||
if (instanceTag->mStreams) {
|
||||
// most recent streams are at the end of list
|
||||
PRInt32 cnt;
|
||||
instanceTag->mStreams->Count((PRUint32*)&cnt);
|
||||
while (--cnt >= 0) {
|
||||
nsPluginStreamListenerPeer *lp =
|
||||
reinterpret_cast<nsPluginStreamListenerPeer*>(instanceTag->mStreams->ElementAt(cnt));
|
||||
if (lp && lp->mLocalCachedFile && lp->mPluginStreamInfo) {
|
||||
useExistingCacheFile = lp->mPluginStreamInfo->UseExistingPluginCacheFile(mPluginStreamInfo);
|
||||
if (useExistingCacheFile) {
|
||||
mLocalCachedFile = lp->mLocalCachedFile;
|
||||
NS_ADDREF(mLocalCachedFile);
|
||||
break;
|
||||
}
|
||||
NS_RELEASE(lp);
|
||||
}
|
||||
NS_RELEASE(lp);
|
||||
}
|
||||
if (useExistingCacheFile)
|
||||
break;
|
||||
}
|
||||
pActivePlugins = pActivePlugins->mNext;
|
||||
}
|
||||
|
||||
if (!useExistingCacheFile) {
|
||||
@ -1088,15 +1081,15 @@ nsPluginStreamListenerPeer::SetupPluginCacheFile(nsIChannel* channel)
|
||||
// add this listenerPeer to list of stream peers for this instance
|
||||
// it'll delay release of listenerPeer until nsPluginInstanceTag::~nsPluginInstanceTag
|
||||
// and the temp file is going to stay alive until then
|
||||
pActivePlugins = gActivePluginList->find(mInstance);
|
||||
if (pActivePlugins) {
|
||||
if (!pActivePlugins->mStreams &&
|
||||
(NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(pActivePlugins->mStreams))))) {
|
||||
nsPluginInstanceTag *instanceTag = pluginHost->FindInstanceTag(mInstance);
|
||||
if (instanceTag) {
|
||||
if (!instanceTag->mStreams &&
|
||||
(NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(instanceTag->mStreams))))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsISupports* supports = static_cast<nsISupports*>((static_cast<nsIStreamListener*>(this)));
|
||||
pActivePlugins->mStreams->AppendElement(supports);
|
||||
instanceTag->mStreams->AppendElement(supports);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -1225,14 +1218,16 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
if (!mInstance && mOwner && !aContentType.IsEmpty()) {
|
||||
mOwner->GetInstance(mInstance);
|
||||
mOwner->GetWindow(window);
|
||||
if (!mInstance && mHost && window) {
|
||||
if (!mInstance && window) {
|
||||
nsRefPtr<nsPluginHost> pluginHost = dont_AddRef(nsPluginHost::GetInst());
|
||||
|
||||
// determine if we need to try embedded again. FullPage takes a different code path
|
||||
PRInt32 mode;
|
||||
mOwner->GetMode(&mode);
|
||||
if (mode == NP_EMBED)
|
||||
rv = mHost->InstantiateEmbeddedPlugin(aContentType.get(), aURL, mOwner);
|
||||
rv = pluginHost->InstantiateEmbeddedPlugin(aContentType.get(), aURL, mOwner);
|
||||
else
|
||||
rv = mHost->SetUpPluginInstance(aContentType.get(), aURL, mOwner);
|
||||
rv = pluginHost->SetUpPluginInstance(aContentType.get(), aURL, mOwner);
|
||||
|
||||
if (NS_OK == rv) {
|
||||
// GetInstance() adds a ref
|
||||
@ -1685,8 +1680,6 @@ nsPluginHost::nsPluginHost()
|
||||
// No need to initialize members to nsnull, PR_FALSE etc because this class
|
||||
// has a zeroing operator new.
|
||||
{
|
||||
gActivePluginList = &mPluginInstanceTagList;
|
||||
|
||||
// check to see if pref is set at startup to let plugins take over in
|
||||
// full page mode for certain image mime types that we handle internally
|
||||
mPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
@ -1771,32 +1764,17 @@ nsPluginHost::GetInst()
|
||||
return sInst;
|
||||
}
|
||||
|
||||
// static
|
||||
const char *
|
||||
nsPluginHost::GetPluginName(nsIPluginInstance *aPluginInstance)
|
||||
{
|
||||
nsPluginInstanceTag *plugin =
|
||||
gActivePluginList ? gActivePluginList->find(aPluginInstance) : nsnull;
|
||||
|
||||
if (plugin && plugin->mPluginTag)
|
||||
return plugin->mPluginTag->mName.get();
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool nsPluginHost::IsRunningPlugin(nsPluginTag * plugin)
|
||||
{
|
||||
if (!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
// we can check for mLibrary to be non-zero and then ask nsIPluginInstance
|
||||
// in nsPluginInstanceTagList to see if plugin with matching mime type is not stopped
|
||||
if (!plugin->mLibrary)
|
||||
return PR_FALSE;
|
||||
|
||||
for (int i = 0; i < plugin->mVariants; i++) {
|
||||
nsPluginInstanceTag * p = mPluginInstanceTagList.find(plugin->mMimeTypeArray[i]);
|
||||
if (p && p->mInstance->IsRunning())
|
||||
nsPluginInstanceTag *instanceTag = FindInstanceTag(plugin->mMimeTypeArray[i]);
|
||||
if (instanceTag && instanceTag->mInstance->IsRunning())
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -1807,7 +1785,7 @@ nsresult nsPluginHost::ReloadPlugins(PRBool reloadPages)
|
||||
{
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsPluginHost::ReloadPlugins Begin reloadPages=%d, active_instance_count=%d\n",
|
||||
reloadPages, mPluginInstanceTagList.mCount));
|
||||
reloadPages, mInstanceTags.Length()));
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -1832,18 +1810,14 @@ nsresult nsPluginHost::ReloadPlugins(PRBool reloadPages)
|
||||
return NS_ERROR_PLUGINS_PLUGINSNOTCHANGED;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> instsToReload;
|
||||
|
||||
if (reloadPages) {
|
||||
NS_NewISupportsArray(getter_AddRefs(instsToReload));
|
||||
|
||||
// Then stop any running plugin instances but hold on to the documents in the array
|
||||
// We are going to need to restart the instances in these documents later
|
||||
mPluginInstanceTagList.stopRunning(instsToReload, nsnull);
|
||||
StopRunningInstances(instsToReload, nsnull);
|
||||
}
|
||||
|
||||
// clean active plugin list
|
||||
mPluginInstanceTagList.removeAllStopped();
|
||||
|
||||
// shutdown plugins and kill the list if there are no running plugins
|
||||
nsRefPtr<nsPluginTag> prev;
|
||||
nsRefPtr<nsPluginTag> next;
|
||||
@ -1892,7 +1866,7 @@ nsresult nsPluginHost::ReloadPlugins(PRBool reloadPages)
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsPluginHost::ReloadPlugins End active_instance_count=%d\n",
|
||||
mPluginInstanceTagList.mCount));
|
||||
mInstanceTags.Length()));
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -2214,10 +2188,7 @@ NS_IMETHODIMP nsPluginHost::Destroy()
|
||||
|
||||
// we should call nsIPluginInstance::Stop and nsIPluginInstance::SetWindow
|
||||
// for those plugins who want it
|
||||
mPluginInstanceTagList.stopRunning(nsnull, nsnull);
|
||||
|
||||
// at this point nsIPlugin::Shutdown calls will be performed if needed
|
||||
mPluginInstanceTagList.shutdown();
|
||||
StopRunningInstances(nsnull, nsnull);
|
||||
|
||||
nsPluginTag *pluginTag;
|
||||
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
||||
@ -2259,6 +2230,29 @@ void nsPluginHost::UnloadUnusedLibraries()
|
||||
mUnusedLibraries.Clear();
|
||||
}
|
||||
|
||||
void nsPluginHost::OnPluginInstanceDestroyed(nsPluginTag* aPluginTag)
|
||||
{
|
||||
PRBool hasInstance = PR_FALSE;
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
if (mInstanceTags[i]->mPluginTag == aPluginTag) {
|
||||
hasInstance = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasInstance) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
PRBool unloadPluginsASAP = PR_FALSE;
|
||||
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
||||
if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
|
||||
aPluginTag->TryUnloadPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHost::GetPluginTempDir(nsIFile **aDir)
|
||||
{
|
||||
@ -2607,7 +2601,7 @@ nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
|
||||
|
||||
aURL->GetAsciiSpec(url);
|
||||
|
||||
nsPluginInstanceTag *instanceTag = mPluginInstanceTagList.findStopped(url.get());
|
||||
nsPluginInstanceTag *instanceTag = FindStoppedInstanceTag(url.get());
|
||||
|
||||
if (instanceTag && !instanceTag->mInstance->IsRunning()) {
|
||||
NPWindow* window = nsnull;
|
||||
@ -2651,12 +2645,11 @@ nsresult nsPluginHost::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
NS_ASSERTION(pluginTag, "Plugin tag not found");
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * plugin = new nsPluginInstanceTag(pluginTag, aInstance, url.get(), aDefaultPlugin);
|
||||
|
||||
if (!plugin)
|
||||
nsPluginInstanceTag *instanceTag = new nsPluginInstanceTag(pluginTag, aInstance, url.get(), aDefaultPlugin);
|
||||
if (!instanceTag)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mPluginInstanceTagList.add(plugin);
|
||||
mInstanceTags.AppendElement(instanceTag);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3918,8 +3911,7 @@ nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
|
||||
|
||||
nsCOMPtr<nsISupportsArray> instsToReload;
|
||||
NS_NewISupportsArray(getter_AddRefs(instsToReload));
|
||||
mPluginInstanceTagList.stopRunning(instsToReload, aPluginTag);
|
||||
mPluginInstanceTagList.removeAllStopped();
|
||||
StopRunningInstances(instsToReload, aPluginTag);
|
||||
|
||||
PRUint32 c;
|
||||
if (instsToReload && NS_SUCCEEDED(instsToReload->Count(&c)) && c > 0) {
|
||||
@ -4547,40 +4539,72 @@ nsPluginHost::StopPluginInstance(nsIPluginInstance* aInstance)
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsPluginHost::StopPluginInstance called instance=%p\n",aInstance));
|
||||
|
||||
nsPluginInstanceTag * plugin = mPluginInstanceTagList.find(aInstance);
|
||||
aInstance->Stop();
|
||||
|
||||
if (plugin) {
|
||||
nsPluginInstanceTag * instanceTag = FindInstanceTag(aInstance);
|
||||
if (instanceTag) {
|
||||
// if the plugin does not want to be 'cached' just remove it
|
||||
PRBool doCache = PR_TRUE;
|
||||
aInstance->ShouldCache(&doCache);
|
||||
if (!doCache) {
|
||||
PRLibrary * library = nsnull;
|
||||
if (plugin->mPluginTag)
|
||||
library = plugin->mPluginTag->mLibrary;
|
||||
|
||||
mPluginInstanceTagList.remove(plugin);
|
||||
} else {
|
||||
// if it is allowed to be cached simply stop it, but first we should check
|
||||
// if we haven't exceeded the maximum allowed number of cached instances
|
||||
|
||||
if (doCache) {
|
||||
// try to get the max cached plugins from a pref or use default
|
||||
PRUint32 max_num;
|
||||
PRUint32 cachedPluginLimit;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mPrefService)
|
||||
rv = mPrefService->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS, (int*)&max_num);
|
||||
rv = mPrefService->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS, (int*)&cachedPluginLimit);
|
||||
if (NS_FAILED(rv))
|
||||
max_num = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
|
||||
|
||||
if (mPluginInstanceTagList.getStoppedCount() >= max_num) {
|
||||
nsPluginInstanceTag * oldest = mPluginInstanceTagList.findOldestStopped();
|
||||
if (oldest != nsnull)
|
||||
mPluginInstanceTagList.remove(oldest);
|
||||
cachedPluginLimit = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
|
||||
|
||||
if (StoppedInstanceTagCount() >= cachedPluginLimit) {
|
||||
nsPluginInstanceTag * oldestInstanceTag = FindOldestStoppedInstanceTag();
|
||||
if (oldestInstanceTag) {
|
||||
nsPluginTag* pluginTag = oldestInstanceTag->mPluginTag;
|
||||
mInstanceTags.RemoveElement(oldestInstanceTag);
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nsPluginTag* pluginTag = instanceTag->mPluginTag;
|
||||
mInstanceTags.RemoveElement(instanceTag);
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag*
|
||||
nsPluginHost::FindOldestStoppedInstanceTag()
|
||||
{
|
||||
nsPluginInstanceTag *oldestInstanceTag = nsnull;
|
||||
TimeStamp oldestTime = TimeStamp::Now();
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
nsPluginInstanceTag *instanceTag = mInstanceTags[i];
|
||||
if (instanceTag->mInstance->IsRunning())
|
||||
continue;
|
||||
|
||||
TimeStamp time = instanceTag->mInstance->LastStopTime();
|
||||
if (time < oldestTime) {
|
||||
oldestTime = time;
|
||||
oldestInstanceTag = instanceTag;
|
||||
}
|
||||
}
|
||||
|
||||
return oldestInstanceTag;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsPluginHost::StoppedInstanceTagCount()
|
||||
{
|
||||
PRUint32 stoppedCount = 0;
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
nsPluginInstanceTag *instanceTag = mInstanceTags[i];
|
||||
if (!instanceTag->mInstance->IsRunning())
|
||||
stoppedCount++;
|
||||
}
|
||||
return stoppedCount;
|
||||
}
|
||||
|
||||
nsresult nsPluginHost::NewEmbeddedPluginStreamListener(nsIURI* aURL,
|
||||
nsIPluginInstanceOwner *aOwner,
|
||||
nsIPluginInstance* aInstance,
|
||||
@ -4603,7 +4627,7 @@ nsresult nsPluginHost::NewEmbeddedPluginStreamListener(nsIURI* aURL,
|
||||
if (aInstance != nsnull)
|
||||
rv = listener->InitializeEmbedded(aURL, aInstance);
|
||||
else if (aOwner != nsnull)
|
||||
rv = listener->InitializeEmbedded(aURL, nsnull, aOwner, this);
|
||||
rv = listener->InitializeEmbedded(aURL, nsnull, aOwner);
|
||||
else
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
if (NS_SUCCEEDED(rv))
|
||||
@ -4663,7 +4687,7 @@ nsresult nsPluginHost::NewFullPagePluginStream(nsIStreamListener *&aStreamListen
|
||||
NS_ADDREF(listener);
|
||||
|
||||
// add peer to list of stream peers for this instance
|
||||
nsPluginInstanceTag * p = mPluginInstanceTagList.find(aInstance);
|
||||
nsPluginInstanceTag * p = FindInstanceTag(aInstance);
|
||||
if (p) {
|
||||
if (!p->mStreams && (NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(p->mStreams)))))
|
||||
return rv;
|
||||
@ -4685,8 +4709,8 @@ NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
|
||||
}
|
||||
if (!nsCRT::strcmp(NS_PRIVATE_BROWSING_SWITCH_TOPIC, aTopic)) {
|
||||
// inform all active plugins of changed private mode state
|
||||
for (nsPluginInstanceTag* ap = mPluginInstanceTagList.mFirst; ap; ap = ap->mNext) {
|
||||
nsNPAPIPluginInstance* pi = static_cast<nsNPAPIPluginInstance*>(ap->mInstance);
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
nsNPAPIPluginInstance* pi = static_cast<nsNPAPIPluginInstance*>(mInstanceTags[i]->mInstance);
|
||||
pi->PrivateModeStateChanged();
|
||||
}
|
||||
}
|
||||
@ -4748,7 +4772,7 @@ nsPluginHost::HandleBadPlugin(PRLibrary* aLibrary, nsIPluginInstance *aInstance)
|
||||
|
||||
// add plugin name to the message
|
||||
nsCString pluginname;
|
||||
nsPluginInstanceTag * p = mPluginInstanceTagList.find(aInstance);
|
||||
nsPluginInstanceTag * p = FindInstanceTag(aInstance);
|
||||
if (p) {
|
||||
nsPluginTag * tag = p->mPluginTag;
|
||||
if (tag) {
|
||||
@ -5074,7 +5098,12 @@ NS_IMETHODIMP
|
||||
nsPluginHost::GetPluginName(nsIPluginInstance *aPluginInstance,
|
||||
const char** aPluginName)
|
||||
{
|
||||
*aPluginName = GetPluginName(aPluginInstance);
|
||||
nsPluginInstanceTag *instanceTag = FindInstanceTag(aPluginInstance);
|
||||
if (!instanceTag || !instanceTag->mPluginTag)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aPluginName = instanceTag->mPluginTag->mName.get();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -5084,13 +5113,12 @@ nsPluginHost::GetPluginTagForInstance(nsIPluginInstance *aPluginInstance,
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPluginInstance);
|
||||
NS_ENSURE_ARG_POINTER(aPluginTag);
|
||||
|
||||
nsPluginInstanceTag *plugin =
|
||||
gActivePluginList ? gActivePluginList->find(aPluginInstance) : nsnull;
|
||||
|
||||
NS_ENSURE_TRUE(plugin && plugin->mPluginTag, NS_ERROR_FAILURE);
|
||||
nsPluginInstanceTag *instanceTag = FindInstanceTag(aPluginInstance);
|
||||
|
||||
NS_ENSURE_TRUE(instanceTag && instanceTag->mPluginTag, NS_ERROR_FAILURE);
|
||||
|
||||
*aPluginTag = plugin->mPluginTag;
|
||||
*aPluginTag = instanceTag->mPluginTag;
|
||||
NS_ADDREF(*aPluginTag);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -5177,32 +5205,30 @@ NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
|
||||
void
|
||||
nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin)
|
||||
{
|
||||
nsPluginTag* plugin = FindTagForPlugin(aPlugin);
|
||||
if (!plugin) {
|
||||
nsPluginTag* pluginTag = FindTagForPlugin(aPlugin);
|
||||
if (!pluginTag) {
|
||||
NS_WARNING("nsPluginTag not found in nsPluginHost::PluginCrashed");
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalidate each nsPluginInstanceTag for the crashed plugin
|
||||
|
||||
nsPluginInstanceTag** pinstancetag = &mPluginInstanceTagList.mFirst;
|
||||
while (*pinstancetag) {
|
||||
nsPluginInstanceTag* instancetag = *pinstancetag;
|
||||
if (instancetag->mPluginTag == plugin) {
|
||||
for (PRUint32 i = mInstanceTags.Length(); i > 0; i--) {
|
||||
nsPluginInstanceTag* instanceTag = mInstanceTags[i - 1];
|
||||
if (instanceTag->mPluginTag == pluginTag) {
|
||||
// notify the content node (nsIObjectLoadingContent) that the plugin has crashed
|
||||
nsCOMPtr<nsIDOMElement> domElement;
|
||||
instancetag->mInstance->GetDOMElement(getter_AddRefs(domElement));
|
||||
instanceTag->mInstance->GetDOMElement(getter_AddRefs(domElement));
|
||||
nsCOMPtr<nsIObjectLoadingContent> objectContent(do_QueryInterface(domElement));
|
||||
if (objectContent) {
|
||||
objectContent->PluginCrashed();
|
||||
}
|
||||
|
||||
instanceTag->mInstance->Stop();
|
||||
|
||||
instancetag->mInstance->Stop();
|
||||
*pinstancetag = (*pinstancetag)->mNext;
|
||||
delete instancetag;
|
||||
}
|
||||
else {
|
||||
pinstancetag = &(*pinstancetag)->mNext;
|
||||
nsPluginTag* pluginTag = instanceTag->mPluginTag;
|
||||
mInstanceTags.RemoveElement(instanceTag);
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5210,10 +5236,95 @@ nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin)
|
||||
// out nsPluginTag.mEntryPoint. The next time we try to create an
|
||||
// instance of this plugin we reload it (launch a new plugin process).
|
||||
|
||||
plugin->mEntryPoint = nsnull;
|
||||
pluginTag->mEntryPoint = nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsPluginInstanceTag*
|
||||
nsPluginHost::FindInstanceTag(nsIPluginInstance *instance)
|
||||
{
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
nsPluginInstanceTag *instanceTag = mInstanceTags[i];
|
||||
if (instanceTag->mInstance == instance)
|
||||
return instanceTag;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag*
|
||||
nsPluginHost::FindInstanceTag(const char *mimetype)
|
||||
{
|
||||
PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
|
||||
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
nsPluginInstanceTag* instanceTag = mInstanceTags[i];
|
||||
// give it some special treatment for the default plugin first
|
||||
// because we cannot tell the default plugin by asking instance for a mime type
|
||||
if (defaultplugin && instanceTag->mDefaultPlugin)
|
||||
return instanceTag;
|
||||
|
||||
if (!instanceTag->mInstance)
|
||||
continue;
|
||||
|
||||
const char* mt;
|
||||
nsresult rv = instanceTag->mInstance->GetMIMEType(&mt);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (PL_strcasecmp(mt, mimetype) == 0)
|
||||
return instanceTag;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag*
|
||||
nsPluginHost::FindStoppedInstanceTag(const char * url)
|
||||
{
|
||||
for (PRUint32 i = 0; i < mInstanceTags.Length(); i++) {
|
||||
nsPluginInstanceTag *instanceTag = mInstanceTags[i];
|
||||
if (!PL_strcmp(url, instanceTag->mURL) && !instanceTag->mInstance->IsRunning())
|
||||
return instanceTag;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginHost::StopRunningInstances(nsISupportsArray* aReloadDocs, nsPluginTag* aPluginTag)
|
||||
{
|
||||
for (PRInt32 i = mInstanceTags.Length(); i > 0; i--) {
|
||||
nsPluginInstanceTag *instanceTag = mInstanceTags[i - 1];
|
||||
nsNPAPIPluginInstance* instance = instanceTag->mInstance;
|
||||
if (instance->IsRunning() && (!aPluginTag || aPluginTag == instanceTag->mPluginTag)) {
|
||||
instance->SetWindow(nsnull);
|
||||
instance->Stop();
|
||||
|
||||
// If we've been passed an array to return, lets collect all our documents,
|
||||
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
||||
// to kickstart our instances.
|
||||
if (aReloadDocs) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
instance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
owner->GetDocument(getter_AddRefs(doc));
|
||||
if (doc && aReloadDocs->IndexOf(doc) == -1) // don't allow for duplicates
|
||||
aReloadDocs->AppendElement(doc);
|
||||
}
|
||||
}
|
||||
|
||||
nsPluginTag* pluginTag = instanceTag->mPluginTag;
|
||||
mInstanceTags.RemoveElement(instanceTag);
|
||||
OnPluginInstanceDestroyed(pluginTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray< nsAutoPtr<nsPluginInstanceTag> >*
|
||||
nsPluginHost::InstanceTagArray()
|
||||
{
|
||||
return &mInstanceTags;
|
||||
}
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
@ -5455,10 +5566,7 @@ public:
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("Doing delayed destroy of instance %p\n", instance.get()));
|
||||
|
||||
instance->Stop();
|
||||
|
||||
nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
||||
|
||||
if (host)
|
||||
host->StopPluginInstance(instance);
|
||||
|
||||
|
@ -81,7 +81,6 @@ public:
|
||||
virtual ~nsPluginHost();
|
||||
|
||||
static nsPluginHost* GetInst();
|
||||
static const char *GetPluginName(nsIPluginInstance *aPluginInstance);
|
||||
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
@ -164,6 +163,16 @@ public:
|
||||
void PluginCrashed(nsNPAPIPlugin* plugin);
|
||||
#endif
|
||||
|
||||
nsPluginInstanceTag *FindInstanceTag(nsIPluginInstance *instance);
|
||||
nsPluginInstanceTag *FindInstanceTag(const char *mimetype);
|
||||
nsPluginInstanceTag *FindStoppedInstanceTag(const char * url);
|
||||
nsPluginInstanceTag *FindOldestStoppedInstanceTag();
|
||||
PRUint32 StoppedInstanceTagCount();
|
||||
|
||||
void StopRunningInstances(nsISupportsArray* aReloadDocs, nsPluginTag* aPluginTag);
|
||||
|
||||
nsTArray< nsAutoPtr<nsPluginInstanceTag> > *InstanceTagArray();
|
||||
|
||||
private:
|
||||
nsresult
|
||||
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
|
||||
@ -243,7 +252,9 @@ private:
|
||||
|
||||
// calls PostPluginUnloadEvent for each library in mUnusedLibraries
|
||||
void UnloadUnusedLibraries();
|
||||
|
||||
|
||||
void OnPluginInstanceDestroyed(nsPluginTag* aPluginTag);
|
||||
|
||||
nsRefPtr<nsPluginTag> mPlugins;
|
||||
nsRefPtr<nsPluginTag> mCachedPlugins;
|
||||
PRPackedBool mPluginsLoaded;
|
||||
@ -262,7 +273,8 @@ private:
|
||||
// set by pref plugin.disable
|
||||
PRPackedBool mPluginsDisabled;
|
||||
|
||||
nsPluginInstanceTagList mPluginInstanceTagList;
|
||||
nsTArray< nsAutoPtr<nsPluginInstanceTag> > mInstanceTags;
|
||||
|
||||
nsTArray<PRLibrary*> mUnusedLibraries;
|
||||
|
||||
nsCOMPtr<nsIFile> mPluginRegFile;
|
||||
|
@ -571,7 +571,6 @@ nsPluginInstanceTag::nsPluginInstanceTag(nsPluginTag* aPluginTag,
|
||||
NS_ADDREF(aInstance);
|
||||
mInstance = static_cast<nsNPAPIPluginInstance*>(aInstance);
|
||||
|
||||
mNext = nsnull;
|
||||
mPluginTag = aPluginTag;
|
||||
|
||||
mURL = PL_strdup(url);
|
||||
@ -593,231 +592,3 @@ nsPluginInstanceTag::~nsPluginInstanceTag()
|
||||
|
||||
PL_strfree(mURL);
|
||||
}
|
||||
|
||||
/* nsPluginInstanceTagList */
|
||||
|
||||
nsPluginInstanceTagList::nsPluginInstanceTagList()
|
||||
{
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
mCount = 0;
|
||||
}
|
||||
|
||||
nsPluginInstanceTagList::~nsPluginInstanceTagList()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void nsPluginInstanceTagList::shutdown()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * plugin = mFirst; plugin != nsnull;) {
|
||||
nsPluginInstanceTag * next = plugin->mNext;
|
||||
remove(plugin);
|
||||
plugin = next;
|
||||
}
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
}
|
||||
|
||||
PRInt32 nsPluginInstanceTagList::add(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!mFirst) {
|
||||
mFirst = plugin;
|
||||
mLast = plugin;
|
||||
mFirst->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
mLast->mNext = plugin;
|
||||
mLast = plugin;
|
||||
}
|
||||
mLast->mNext = nsnull;
|
||||
mCount++;
|
||||
return mCount;
|
||||
}
|
||||
|
||||
PRBool nsPluginInstanceTagList::IsLastInstance(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!plugin->mPluginTag)
|
||||
return PR_FALSE;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if ((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsPluginInstanceTagList::remove(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!mFirst)
|
||||
return PR_FALSE;
|
||||
|
||||
nsPluginInstanceTag * prev = nsnull;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p == plugin) {
|
||||
PRBool lastInstance = IsLastInstance(p);
|
||||
|
||||
if (p == mFirst)
|
||||
mFirst = p->mNext;
|
||||
else
|
||||
prev->mNext = p->mNext;
|
||||
|
||||
if (prev && !prev->mNext)
|
||||
mLast = prev;
|
||||
|
||||
if (lastInstance) {
|
||||
nsRefPtr<nsPluginTag> pluginTag = p->mPluginTag;
|
||||
|
||||
delete p;
|
||||
|
||||
if (pluginTag) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool unloadPluginsASAP = PR_FALSE;
|
||||
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
||||
if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
|
||||
pluginTag->TryUnloadPlugin();
|
||||
} else {
|
||||
NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown");
|
||||
}
|
||||
} else {
|
||||
delete p;
|
||||
}
|
||||
|
||||
mCount--;
|
||||
return PR_TRUE;
|
||||
}
|
||||
prev = p;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// This method terminates all running instances of plugins and collects their
|
||||
// documents to be returned through an array. This method is used
|
||||
// when we are shutting down or when a plugins.refresh(1) happens.
|
||||
// If aPluginTag is given, then only that plugin is terminated
|
||||
void nsPluginInstanceTagList::stopRunning(nsISupportsArray* aReloadDocs,
|
||||
nsPluginTag* aPluginTag)
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mInstance->IsRunning() && (!aPluginTag || aPluginTag == p->mPluginTag)) {
|
||||
p->mInstance->SetWindow(nsnull);
|
||||
p->mInstance->Stop();
|
||||
|
||||
// If we've been passed an array to return, lets collect all our documents,
|
||||
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
||||
// to kickstart our instances.
|
||||
if (aReloadDocs) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
p->mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
owner->GetDocument(getter_AddRefs(doc));
|
||||
if (doc && aReloadDocs->IndexOf(doc) == -1) // don't allow for duplicates
|
||||
aReloadDocs->AppendElement(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginInstanceTagList::removeAllStopped()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
nsPluginInstanceTag * next = nsnull;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull;) {
|
||||
next = p->mNext;
|
||||
|
||||
if (!p->mInstance->IsRunning())
|
||||
remove(p);
|
||||
|
||||
p = next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::find(nsIPluginInstance* instance)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mInstance == instance)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::find(const char * mimetype)
|
||||
{
|
||||
PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
// give it some special treatment for the default plugin first
|
||||
// because we cannot tell the default plugin by asking instance for a mime type
|
||||
if (defaultplugin && p->mDefaultPlugin)
|
||||
return p;
|
||||
|
||||
if (!p->mInstance)
|
||||
continue;
|
||||
|
||||
const char* mt;
|
||||
nsresult rv = p->mInstance->GetMIMEType(&mt);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (PL_strcasecmp(mt, mimetype) == 0)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findStopped(const char * url)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!PL_strcmp(url, p->mURL) && !p->mInstance->IsRunning())
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRUint32 nsPluginInstanceTagList::getStoppedCount()
|
||||
{
|
||||
PRUint32 stoppedCount = 0;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mInstance->IsRunning())
|
||||
stoppedCount++;
|
||||
}
|
||||
return stoppedCount;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findOldestStopped()
|
||||
{
|
||||
nsPluginInstanceTag * res = nsnull;
|
||||
TimeStamp oldestTime = TimeStamp::Now();
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mInstance->IsRunning())
|
||||
continue;
|
||||
|
||||
TimeStamp time = p->mInstance->LastStopTime();
|
||||
if (time < oldestTime) {
|
||||
oldestTime = time;
|
||||
res = p;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -125,11 +125,10 @@ private:
|
||||
|
||||
struct nsPluginInstanceTag
|
||||
{
|
||||
nsPluginInstanceTag* mNext;
|
||||
char* mURL;
|
||||
nsRefPtr<nsPluginTag> mPluginTag;
|
||||
nsNPAPIPluginInstance* mInstance; // this must always be valid
|
||||
PRPackedBool mDefaultPlugin;
|
||||
PRBool mDefaultPlugin;
|
||||
// Array holding all opened stream listeners for this entry
|
||||
nsCOMPtr <nsISupportsArray> mStreams;
|
||||
|
||||
@ -140,27 +139,4 @@ struct nsPluginInstanceTag
|
||||
~nsPluginInstanceTag();
|
||||
};
|
||||
|
||||
class nsPluginInstanceTagList
|
||||
{
|
||||
public:
|
||||
nsPluginInstanceTag *mFirst;
|
||||
nsPluginInstanceTag *mLast;
|
||||
PRInt32 mCount;
|
||||
|
||||
nsPluginInstanceTagList();
|
||||
~nsPluginInstanceTagList();
|
||||
|
||||
void shutdown();
|
||||
PRBool add(nsPluginInstanceTag *plugin);
|
||||
PRBool remove(nsPluginInstanceTag *plugin);
|
||||
nsPluginInstanceTag *find(nsIPluginInstance *instance);
|
||||
nsPluginInstanceTag *find(const char *mimetype);
|
||||
nsPluginInstanceTag *findStopped(const char *url);
|
||||
PRUint32 getStoppedCount();
|
||||
nsPluginInstanceTag *findOldestStopped();
|
||||
void removeAllStopped();
|
||||
void stopRunning(nsISupportsArray *aReloadDocs, nsPluginTag *aPluginTag);
|
||||
PRBool IsLastInstance(nsPluginInstanceTag *plugin);
|
||||
};
|
||||
|
||||
#endif // nsPluginTags_h_
|
||||
|
Loading…
Reference in New Issue
Block a user