Bug 382367, Add support for enabling and disabling individual plugins, r+sr=jst

This commit is contained in:
flamingice@sourmilk.net 2007-07-03 14:42:35 -07:00
Родитель b125d74ea1
Коммит c062ff619a
5 изменённых файлов: 221 добавлений и 58 удалений

Просмотреть файл

@ -79,6 +79,7 @@ XPIDLSRCS = \
nsIClassicPluginFactory.idl \
nsIWindowlessPlugInstPeer.idl \
nsIScriptablePlugin.idl \
nsIPluginTag.idl \
nsIPluginTagInfo.idl \
nsIPluginTagInfo2.idl \
nsIJRILiveConnectPIPeer.idl \

Просмотреть файл

@ -40,6 +40,7 @@
#include "nsIPluginInstanceOwner.idl"
#include "nsIStreamListener.idl"
#include "nsIStringStream.idl"
#include "nsIPluginTag.idl"
%{C++
#include "nsplugindefs.h"
@ -58,46 +59,49 @@ interface nsIChannel;
[ptr] native PRLibraryPtr(PRLibrary);
[ref] native nsIStreamListenerRef(nsIStreamListener *);
[uuid(ABB36800-EA77-4172-AD14-603A02DB2B53)]
[scriptable, uuid(2af1c32d-38dd-4f72-b0ab-24697d836e61)]
interface nsIPluginHost : nsIFactory
{
void init();
[noscript] void init();
void destroy();
[noscript] void destroy();
void loadPlugins();
[noscript] void loadPlugins();
void getPluginFactory(in string aMimeType, out nsIPlugin aPlugin);
[noscript] nsIPlugin getPluginFactory(in string aMimeType);
void instantiateEmbeddedPlugin(in string aMimeType, in nsIURI aURL, in nsIPluginInstanceOwner aOwner);
[noscript] void instantiateEmbeddedPlugin(in string aMimeType, in nsIURI aURL, in nsIPluginInstanceOwner aOwner);
void instantiateFullPagePlugin(in string aMimeType, in nsIURI aURI, in nsIStreamListenerRef aStreamListener, in nsIPluginInstanceOwner aOwner);
[noscript] void instantiateFullPagePlugin(in string aMimeType, in nsIURI aURI, in nsIStreamListenerRef aStreamListener, in nsIPluginInstanceOwner aOwner);
/**
* Instantiate an embedded plugin for an existing channel. The caller is
* responsible for opening the channel. It may or may not be already opened
* when this function is called.
*/
nsIStreamListener instantiatePluginForChannel(in nsIChannel aChannel, in nsIPluginInstanceOwner aOwner);
[noscript] nsIStreamListener instantiatePluginForChannel(in nsIChannel aChannel, in nsIPluginInstanceOwner aOwner);
void setUpPluginInstance(in string aMimeType, in nsIURI aURL, in nsIPluginInstanceOwner aOwner);
[noscript] void setUpPluginInstance(in string aMimeType, in nsIURI aURL, in nsIPluginInstanceOwner aOwner);
// The return code is NS_OK if the plugin is enabled,
// NS_ERROR_PLUGIN_DISABLED if the plugin is explicitly disabled, and
// NS_ERROR_FAILURE if there is no plugin for this type.
void isPluginEnabledForType(in string aMimeType);
[noscript] void isPluginEnabledForType(in string aMimeType);
// The return code is NS_OK if the plugin is enabled and NS_ERROR_FAILURE if
// the plugin is explicitly disabled or there is no plugin.
void isPluginEnabledForExtension(in string aExtension, in constCharStarRef aMimeType);
[noscript] void isPluginEnabledForExtension(in string aExtension, in constCharStarRef aMimeType);
readonly attribute unsigned long pluginCount;
[noscript] readonly attribute unsigned long pluginCount;
[noscript] void getPlugins(in unsigned long aPluginCount, out /*array*/ nsIDOMPlugin aPluginArray);
void stopPluginInstance(in nsIPluginInstance aInstance);
void getPluginTags(out unsigned long aPluginCount,
[retval, array, size_is(aPluginCount)] out nsIPluginTag aResults);
void handleBadPlugin(in PRLibraryPtr aLibrary, in nsIPluginInstance instance);
[noscript] void stopPluginInstance(in nsIPluginInstance aInstance);
[noscript] void handleBadPlugin(in PRLibraryPtr aLibrary, in nsIPluginInstance instance);
};
%{C++

Просмотреть файл

@ -0,0 +1,48 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Wu <flamingice@sourmilk.net> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(42f9c725-e13d-47d5-bf1d-f9b0a9ee5cf7)]
interface nsIPluginTag : nsISupports
{
readonly attribute ACString description;
readonly attribute ACString filename;
readonly attribute ACString name;
attribute boolean disabled;
};

Просмотреть файл

@ -942,11 +942,63 @@ nsPluginTag::~nsPluginTag()
}
NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
void nsPluginTag::SetHost(nsPluginHostImpl * aHost)
{
mPluginHost = aHost;
}
NS_IMETHODIMP
nsPluginTag::GetDescription(nsACString& aDescription)
{
aDescription.Truncate();
if (mDescription)
aDescription.Assign(nsDependentCString(mDescription));
return NS_OK;
}
NS_IMETHODIMP
nsPluginTag::GetFilename(nsACString& aFileName)
{
aFileName.Truncate();
if (mFileName)
aFileName.Assign(nsDependentCString(mFileName));
return NS_OK;
}
NS_IMETHODIMP
nsPluginTag::GetName(nsACString& aName)
{
aName.Truncate();
if (mName)
aName.Assign(nsDependentCString(mName));
return NS_OK;
}
NS_IMETHODIMP
nsPluginTag::GetDisabled(PRBool* aDisabled)
{
*aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
return NS_OK;
}
NS_IMETHODIMP
nsPluginTag::SetDisabled(PRBool aDisabled)
{
if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
return NS_OK;
/* TODO: stop plugin if it's currently running */
if (aDisabled)
UnMark(NS_PLUGIN_FLAG_ENABLED);
else
Mark(NS_PLUGIN_FLAG_ENABLED);
mPluginHost->UpdatePluginInfo();
return NS_OK;
}
//----------------------------------------------------------------------
// helper struct for asynchronous handeling of plugin unloading
class nsPluginUnloadEvent : public nsRunnable {
@ -2711,10 +2763,10 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
mActivePluginList.removeAllStopped();
// shutdown plugins and kill the list if there are no running plugins
nsPluginTag * prev = nsnull;
nsPluginTag * next = nsnull;
nsRefPtr<nsPluginTag> prev;
nsRefPtr<nsPluginTag> next;
for(nsPluginTag * p = mPlugins; p != nsnull;) {
for(nsRefPtr<nsPluginTag> p = mPlugins; p != nsnull;) {
next = p->mNext;
// XXX only remove our plugin from the list if it's not running and not
@ -2728,7 +2780,7 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
else
prev->mNext = next;
delete p;
p->mNext = nsnull;
p = next;
continue;
}
@ -3214,7 +3266,7 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
while (nsnull != mPlugins)
{
nsPluginTag *temp = mPlugins->mNext;
nsRefPtr<nsPluginTag> temp = mPlugins->mNext;
// while walking through the list of the plugins see if we still have anything
// to shutdown some plugins may have never created an instance but still expect
@ -3222,17 +3274,12 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
// with current logic, no need to do anything special as nsIPlugin::Shutdown
// will be performed in the destructor
delete mPlugins;
mPlugins->mNext = nsnull;
mPlugins = temp;
}
// Delete any remaining cached plugins list
while (mCachedPlugins)
{
nsPluginTag *next = mCachedPlugins->mNext;
delete mCachedPlugins;
mCachedPlugins = next;
}
mCachedPlugins = nsnull;
// Lets remove any of the temporary files that we created.
if (sPluginTempDir) {
@ -4354,18 +4401,47 @@ nsPluginHostImpl::GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray)
LoadPlugins();
nsPluginTag* plugin = mPlugins;
for (PRUint32 i = 0; i < aPluginCount && plugin != nsnull;
i++, plugin = plugin->mNext) {
for (PRUint32 i = 0; i < aPluginCount && plugin; plugin = plugin->mNext) {
if (plugin->HasFlag(NS_PLUGIN_FLAG_ENABLED)) {
nsIDOMPlugin* domPlugin = new DOMPluginImpl(plugin);
NS_IF_ADDREF(domPlugin);
aPluginArray[i] = domPlugin;
aPluginArray[i++] = domPlugin;
}
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsPluginHostImpl::GetPluginTags(PRUint32* aPluginCount, nsIPluginTag*** aResults)
{
LoadPlugins();
PRUint32 count = 0;
nsRefPtr<nsPluginTag> plugin = mPlugins;
while (plugin != nsnull) {
count++;
plugin = plugin->mNext;
}
*aResults = NS_STATIC_CAST(nsIPluginTag**,
nsMemory::Alloc(count * sizeof(**aResults)));
if (!*aResults)
return NS_ERROR_OUT_OF_MEMORY;
*aPluginCount = count;
plugin = mPlugins;
PRUint32 i;
for (i = 0; i < count; i++) {
(*aResults)[i] = plugin;
NS_ADDREF((*aResults)[i]);
plugin = plugin->mNext;
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsPluginTag*
@ -4728,11 +4804,11 @@ static PRBool isUnwantedPlugin(nsPluginTag * tag)
////////////////////////////////////////////////////////////////////////
PRBool nsPluginHostImpl::IsUnwantedJavaPlugin(nsPluginTag * tag)
{
PRBool javaUnwanted = !mJavaEnabled;
#ifndef OJI
javaUnwanted = PR_TRUE;
return IsJavaPluginTag(tag);
#else
return PR_FALSE;
#endif /* OJI */
return javaUnwanted && IsJavaPluginTag(tag);
}
PRBool nsPluginHostImpl::IsJavaPluginTag(nsPluginTag * tag)
@ -4958,13 +5034,16 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir,
PRInt64 fileModTime = pfd->mModTime;
// Look for it in our cache
nsPluginTag *pluginTag = RemoveCachedPluginsInfo(NS_ConvertUTF16toUTF8(pfd->mFilename).get());
nsRefPtr<nsPluginTag> pluginTag;
RemoveCachedPluginsInfo(NS_ConvertUTF16toUTF8(pfd->mFilename).get(),
getter_AddRefs(pluginTag));
PRBool pluginEnabled = PR_TRUE;
if (pluginTag) {
// If plugin changed, delete cachedPluginTag and don't use cache
if (LL_NE(fileModTime, pluginTag->mLastModifiedTime)) {
// Plugins has changed. Don't use cached plugin info.
delete pluginTag;
pluginEnabled = pluginTag->HasFlag(NS_PLUGIN_FLAG_ENABLED);
pluginTag = nsnull;
// plugin file changed, flag this fact
@ -5041,6 +5120,8 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir,
pluginTag->mLibrary = pluginLibrary;
pluginTag->mLastModifiedTime = fileModTime;
if (!pluginEnabled || (IsJavaPluginTag(pluginTag) && !mJavaEnabled))
pluginTag->UnMark(NS_PLUGIN_FLAG_ENABLED);
// if this is unwanted plugin we are checkin for, or this is a duplicate plugin,
// add it to our cache info list so we can cache the unwantedness of this plugin
@ -5089,7 +5170,7 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir,
// we don't need it, delete it;
// but don't delete unwanted plugins since they are cached
// in the cache info list and will be deleted later
delete pluginTag;
pluginTag = nsnull;
}
}
return NS_OK;
@ -5331,8 +5412,9 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
ScanForRealInComponentsFolder(compManager);
// reverse our list of plugins
nsPluginTag *next,*prev = nsnull;
for (nsPluginTag *cur = mPlugins; cur; cur = next) {
nsRefPtr<nsPluginTag> next;
nsRefPtr<nsPluginTag> prev;
for (nsRefPtr<nsPluginTag> cur = mPlugins; cur; cur = next) {
next = cur->mNext;
cur->mNext = prev;
prev = cur;
@ -5348,11 +5430,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
void nsPluginHostImpl::ClearCachedPluginInfoList()
{
while (mCachedPlugins) {
nsPluginTag *next = mCachedPlugins->mNext;
delete mCachedPlugins;
mCachedPlugins = next;
}
mCachedPlugins = nsnull;
}
////////////////////////////////////////////////////////////////////////
@ -5373,6 +5451,16 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager)
return NS_OK;
}
nsresult
nsPluginHostImpl::UpdatePluginInfo()
{
ReadPluginInfo();
WritePluginInfo();
ClearCachedPluginInfoList();
return NS_OK;
}
nsresult
nsPluginHostImpl::WritePluginInfo()
{
@ -5634,7 +5722,7 @@ nsPluginHostImpl::ReadPluginInfo()
return rv;
}
nsPluginTag* tag = new nsPluginTag(name,
nsRefPtr<nsPluginTag> tag = new nsPluginTag(name,
description,
filename,
(*fullpath ? fullpath : 0), // we have to pass 0 prt if it's empty str
@ -5652,6 +5740,12 @@ nsPluginHostImpl::ReadPluginInfo()
// Mark plugin as loaded from cache
tag->Mark(tagflag | NS_PLUGIN_FLAG_FROMCACHE);
if (IsJavaPluginTag(tag)) {
if (mJavaEnabled)
tag->Mark(NS_PLUGIN_FLAG_ENABLED);
else
tag->UnMark(NS_PLUGIN_FLAG_ENABLED);
}
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName));
tag->mNext = mCachedPlugins;
@ -5661,11 +5755,12 @@ nsPluginHostImpl::ReadPluginInfo()
return NS_OK;
}
nsPluginTag *
nsPluginHostImpl::RemoveCachedPluginsInfo(const char *filename)
void
nsPluginHostImpl::RemoveCachedPluginsInfo(const char *filename, nsPluginTag **result)
{
nsPluginTag **link = &mCachedPlugins;
for (nsPluginTag *tag = *link; tag; link = &tag->mNext, tag = *link)
nsRefPtr<nsPluginTag> prev;
nsRefPtr<nsPluginTag> tag = mCachedPlugins;
while (tag)
{
// compare filename or else the mFullPath if it exists. Mac seems to use
// mFullPath for fullpath and mFileName for just the leafname of fullpath.
@ -5675,11 +5770,18 @@ nsPluginHostImpl::RemoveCachedPluginsInfo(const char *filename)
(tag->mFullPath && !PL_strcmp(tag->mFullPath, filename)))
{
// Found it. Remove it from our list
*link = tag->mNext;
return tag;
if (prev)
prev->mNext = tag->mNext;
else
mCachedPlugins = tag->mNext;
tag->mNext = nsnull;
*result = tag;
NS_ADDREF(*result);
break;
}
prev = tag;
tag = tag->mNext;
}
return nsnull;
}
nsresult
@ -6736,7 +6838,7 @@ nsPluginHostImpl::ScanForRealInComponentsFolder(nsIComponentManager * aCompManag
// finally, create our "plugin tag" and add it to the list
if (info.fMimeTypeArray) {
nsPluginTag *pluginTag = new nsPluginTag(&info);
nsRefPtr<nsPluginTag> pluginTag = new nsPluginTag(&info);
if (pluginTag) {
NS_ASSERTION(!IsUnwantedJavaPlugin(pluginTag),
"RealPlayer plugin is unwanted Java plugin?");

Просмотреть файл

@ -48,6 +48,7 @@
#include "prlink.h"
#include "nsIPlugin.h"
#include "nsIPluginTag.h"
#include "nsIPluginTagInfo2.h"
#include "nsIPluginInstancePeer2.h"
@ -84,9 +85,12 @@ class nsPluginHostImpl;
* instantiating plugins and reflecting plugin information
* into JavaScript.
*/
class nsPluginTag
class nsPluginTag : public nsIPluginTag
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGINTAG
nsPluginTag(nsPluginTag* aPluginTag);
nsPluginTag(nsPluginInfo* aPluginInfo);
@ -132,7 +136,7 @@ public:
void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
nsRegisterType aType = ePluginRegister);
nsPluginTag *mNext;
nsRefPtr<nsPluginTag> mNext;
nsPluginHostImpl *mPluginHost;
char *mName;
char *mDescription;
@ -156,7 +160,7 @@ struct nsActivePlugin
nsActivePlugin* mNext;
char* mURL;
nsIPluginInstancePeer* mPeer;
nsPluginTag* mPluginTag;
nsRefPtr<nsPluginTag> mPluginTag;
nsIPluginInstance* mInstance;
PRTime mllStopTime;
PRPackedBool mStopped;
@ -315,6 +319,9 @@ public:
static nsresult GetPluginTempDir(nsIFile **aDir);
// Writes updated plugins settings to disk
nsresult UpdatePluginInfo();
private:
NS_IMETHOD
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
@ -380,7 +387,8 @@ private:
// Given a filename, returns the plugins info from our cache
// and removes it from the cache.
nsPluginTag* RemoveCachedPluginsInfo(const char *filename);
void RemoveCachedPluginsInfo(const char *filename,
nsPluginTag **result);
//checks if the list already have the same plugin as given
nsPluginTag* HaveSamePlugin(nsPluginTag * aPluginTag);
@ -390,7 +398,7 @@ private:
PRBool IsDuplicatePlugin(nsPluginTag * aPluginTag);
// checks whether the given plugin is an unwanted Java plugin
// (e.g. Java is disabled, or no OJI support is compiled in)
// (e.g. no OJI support is compiled in)
PRBool IsUnwantedJavaPlugin(nsPluginTag * aPluginTag);
// checks whether aTag is a "java" plugin tag (a tag for a plugin
@ -418,8 +426,8 @@ private:
nsresult AddPrefObserver();
char *mPluginPath;
nsPluginTag *mPlugins;
nsPluginTag *mCachedPlugins;
nsRefPtr<nsPluginTag> mPlugins;
nsRefPtr<nsPluginTag> mCachedPlugins;
PRPackedBool mPluginsLoaded;
PRPackedBool mDontShowBadPluginMessage;
PRPackedBool mIsDestroyed;