Bug 569644 - Query the plugin host directly when searching for MIME types, rather than using Gecko-Content-Viewer category manager registration, r=bz

This commit is contained in:
Benjamin Smedberg 2010-06-10 12:42:16 -04:00
Родитель 9bd490a583
Коммит 89038557e0
12 изменённых файлов: 163 добавлений и 169 удалений

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

@ -455,11 +455,6 @@ HandlerInfoWrapper.prototype = {
this._prefSvc.setCharPref(PREF_DISABLED_PLUGIN_TYPES,
disabledPluginTypes.join(","));
// Update the category manager so existing browser windows update.
this._categoryMgr.deleteCategoryEntry("Gecko-Content-Viewers",
this.type,
false);
},
enablePluginType: function() {
@ -470,14 +465,6 @@ HandlerInfoWrapper.prototype = {
this._prefSvc.setCharPref(PREF_DISABLED_PLUGIN_TYPES,
disabledPluginTypes.join(","));
// Update the category manager so existing browser windows update.
this._categoryMgr.
addCategoryEntry("Gecko-Content-Viewers",
this.type,
"@mozilla.org/content/plugin/document-loader-factory;1",
false,
true);
},

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

@ -37,6 +37,9 @@
#ifndef nsIContentUtils_h__
#define nsIContentUtils_h__
#include "nsIDocumentLoaderFactory.h"
#include "nsCOMPtr.h"
// C4EA618E-A3D9-4524-8EEA-E92F26FC44DB
#define NS_ICONTENTUTILS_IID \
{ 0xC4EA618E, 0xA3D9, 0x4524, \
@ -49,6 +52,18 @@ public:
NS_DECL_ISUPPORTS
virtual PRBool IsSafeToRunScript();
enum ContentViewerType
{
TYPE_UNSUPPORTED,
TYPE_CONTENT,
TYPE_PLUGIN,
TYPE_UNKNOWN
};
virtual already_AddRefed<nsIDocumentLoaderFactory>
FindInternalContentViewer(const char* aType,
ContentViewerType* aLoaderType = NULL);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils, NS_ICONTENTUTILS_IID)

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

@ -180,6 +180,8 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "BasicLayers.h"
#include "nsFocusManager.h"
#include "nsTextEditorState.h"
#include "nsIPluginHost.h"
#include "nsICategoryManager.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
@ -203,6 +205,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIChannelPolicy.h"
#include "nsChannelPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsContentDLF.h"
using namespace mozilla::dom;
@ -6040,3 +6043,54 @@ nsIContentUtils::IsSafeToRunScript()
return nsContentUtils::IsSafeToRunScript();
}
already_AddRefed<nsIDocumentLoaderFactory>
nsIContentUtils::FindInternalContentViewer(const char* aType,
ContentViewerType* aLoaderType)
{
if (aLoaderType) {
*aLoaderType = TYPE_UNSUPPORTED;
}
// one helper factory, please
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
if (!catMan)
return NULL;
FullPagePluginEnabledType pluginEnabled = NOT_ENABLED;
nsCOMPtr<nsIPluginHost> pluginHost =
do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
if (pluginHost) {
pluginHost->IsFullPagePluginEnabledForType(aType, &pluginEnabled);
}
nsCOMPtr<nsIDocumentLoaderFactory> docFactory;
if (OVERRIDE_BUILTIN == pluginEnabled) {
docFactory = do_GetService(PLUGIN_DLF_CONTRACTID);
if (docFactory && aLoaderType) {
*aLoaderType = TYPE_PLUGIN;
}
return docFactory.forget();
}
nsXPIDLCString contractID;
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", aType, getter_Copies(contractID));
if (NS_SUCCEEDED(rv)) {
docFactory = do_GetService(contractID);
if (docFactory && aLoaderType) {
*aLoaderType = contractID.EqualsLiteral(CONTENT_DLF_CONTRACTID) ? TYPE_CONTENT : TYPE_UNKNOWN;
}
return docFactory.forget();
}
if (AVAILABLE == pluginEnabled) {
docFactory = do_GetService(PLUGIN_DLF_CONTRACTID);
if (docFactory && aLoaderType) {
*aLoaderType = TYPE_PLUGIN;
}
return docFactory.forget();
}
return NULL;
}

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

@ -49,6 +49,7 @@
#include "nsIBrowserDOMWindow.h"
#include "nsIComponentManager.h"
#include "nsIContent.h"
#include "nsIContentUtils.h"
#include "mozilla/dom/Element.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
@ -6187,17 +6188,11 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
// too, of course.
mFiredUnloadEvent = PR_FALSE;
// one helper factory, please
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
if (!catMan)
nsCOMPtr<nsIContentUtils> cutils = do_GetService("@mozilla.org/content/contentutils;1");
if (!cutils)
return NS_ERROR_FAILURE;
nsXPIDLCString contractId;
rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html", getter_Copies(contractId));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIDocumentLoaderFactory> docFactory(do_GetService(contractId));
nsCOMPtr<nsIDocumentLoaderFactory> docFactory = cutils->FindInternalContentViewer("text/html");
if (docFactory) {
// generate (about:blank) document to load
docFactory->CreateBlankDocument(mLoadGroup, aPrincipal,
@ -7177,19 +7172,13 @@ nsDocShell::NewContentViewerObj(const char *aContentType,
{
nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request);
nsresult rv;
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
if (NS_FAILED(rv))
return rv;
nsXPIDLCString contractId;
rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", aContentType, getter_Copies(contractId));
// Create an instance of the document-loader-factory
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory;
if (NS_SUCCEEDED(rv))
docLoaderFactory = do_GetService(contractId.get());
nsCOMPtr<nsIContentUtils> cutils = do_GetService("@mozilla.org/content/contentutils;1");
if (!cutils) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
cutils->FindInternalContentViewer(aContentType);
if (!docLoaderFactory) {
return NS_ERROR_FAILURE;
}

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

@ -39,6 +39,7 @@
#include "nsIWebNavigation.h"
#include "nsString.h"
#include "nsServiceManagerUtils.h"
#include "nsIContentUtils.h"
#include "nsIDocumentLoaderFactory.h"
#include "nsIPluginHost.h"
@ -106,33 +107,32 @@ nsresult
nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType,
PRUint32* aIsSupported)
{
NS_PRECONDITION(mCategoryManager, "Must have category manager");
NS_PRECONDITION(aIsSupported, "Null out param?");
nsXPIDLCString value;
nsresult rv = mCategoryManager->GetCategoryEntry("Gecko-Content-Viewers",
aType.get(),
getter_Copies(value));
// If the category manager can't find what we're looking for
// it returns NS_ERROR_NOT_AVAILABLE, we don't want to propagate
// that to the caller since it's really not a failure
nsCOMPtr<nsIContentUtils> cutils = do_GetService("@mozilla.org/content/contentutils;1");
if (!cutils)
return NS_ERROR_FAILURE;
if (NS_FAILED(rv) && rv != NS_ERROR_NOT_AVAILABLE)
return rv;
nsIContentUtils::ContentViewerType vtype = nsIContentUtils::TYPE_UNSUPPORTED;
// Now try to get an actual document loader factory for this contractid. If
// there is no contractid, don't try and just return false for *aIsSupported.
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory;
if (!value.IsEmpty()) {
docLoaderFactory = do_GetService(value.get());
}
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
cutils->FindInternalContentViewer(aType.get(), &vtype);
// If we got a factory, we should be able to handle this type
if (!docLoaderFactory) {
switch (vtype) {
case nsIContentUtils::TYPE_UNSUPPORTED:
*aIsSupported = nsIWebNavigationInfo::UNSUPPORTED;
}
else if (value.EqualsLiteral(CONTENT_DLF_CONTRACT)) {
break;
case nsIContentUtils::TYPE_PLUGIN:
*aIsSupported = nsIWebNavigationInfo::PLUGIN;
break;
case nsIContentUtils::TYPE_UNKNOWN:
*aIsSupported = nsIWebNavigationInfo::OTHER;
break;
case nsIContentUtils::TYPE_CONTENT:
PRBool isImage = PR_FALSE;
mImgLoader->SupportImageWithMimeType(aType.get(), &isImage);
if (isImage) {
@ -141,12 +141,7 @@ nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType,
else {
*aIsSupported = nsIWebNavigationInfo::OTHER;
}
}
else if (value.EqualsLiteral(PLUGIN_DLF_CONTRACT)) {
*aIsSupported = nsIWebNavigationInfo::PLUGIN;
}
else {
*aIsSupported = nsIWebNavigationInfo::OTHER;
break;
}
return NS_OK;

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

@ -531,7 +531,7 @@ RegisterTypes(nsICategoryManager* aCatMgr,
// this allows users of layout's viewers (the docshell for example)
// to query the types of viewers layout can create.
rv = aCatMgr->AddCategoryEntry("Gecko-Content-Viewers", contentType,
"@mozilla.org/content/document-loader-factory;1",
CONTENT_DLF_CONTRACTID,
aPersist, PR_TRUE, nsnull);
if (NS_FAILED(rv)) break;
}

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

@ -52,6 +52,9 @@ class nsILoadGroup;
class nsIStreamListener;
struct nsModuleComponentInfo;
#define CONTENT_DLF_CONTRACTID "@mozilla.org/content/document-loader-factory;1"
#define PLUGIN_DLF_CONTRACTID "@mozilla.org/content/plugin/document-loader-factory;1"
class nsContentDLF : public nsIDocumentLoaderFactory
{
public:

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

@ -1397,7 +1397,7 @@ static const nsModuleComponentInfo gLayoutComponents[] = {
{ "Document Loader Factory",
NS_CONTENT_DOCUMENT_LOADER_FACTORY_CID,
"@mozilla.org/content/document-loader-factory;1",
CONTENT_DLF_CONTRACTID,
CreateContentDLF,
nsContentDLF::RegisterDocumentFactories,
nsContentDLF::UnregisterDocumentFactories },
@ -1448,7 +1448,7 @@ static const nsModuleComponentInfo gLayoutComponents[] = {
{ "Plugin Document Loader Factory",
NS_PLUGINDOCLOADERFACTORY_CID,
"@mozilla.org/content/plugin/document-loader-factory;1",
PLUGIN_DLF_CONTRACTID,
CreateContentDLF },
{ "Plugin Document",

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

@ -64,6 +64,23 @@ interface nsIPluginStreamListener;
[ptr] native PRLibraryPtr(PRLibrary);
[ref] native nsIStreamListenerRef(nsIStreamListener *);
[ptr] native nsPluginNativeWindowPtr(nsPluginNativeWindow);
native FullPagePluginEnabledType(FullPagePluginEnabledType);
%{C++
enum FullPagePluginEnabledType
{
// No plugin was found for this MIME type.
NOT_ENABLED,
// A plugin is available and should take precedence over builtin
// content viewers.
OVERRIDE_BUILTIN,
// A plugin is available, but a builtin content viewers should be used if
// present.
AVAILABLE
};
%}
[scriptable, uuid(D419142E-0571-416B-B797-2A8E6624491D)]
interface nsIPluginHost : nsISupports
@ -106,6 +123,8 @@ interface nsIPluginHost : nsISupports
// NS_ERROR_FAILURE if there is no plugin for this type.
[noscript] void isPluginEnabledForType(in string aMimeType);
[noscript] FullPagePluginEnabledType isFullPagePluginEnabledForType(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.
[noscript] void isPluginEnabledForExtension(in string aExtension, in constCharStarRef aMimeType);

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

@ -2610,6 +2610,42 @@ nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
return NS_OK;
}
NS_IMETHODIMP
nsPluginHost::IsFullPagePluginEnabledForType(const char* aMimeType,
FullPagePluginEnabledType* aResult)
{
*aResult = NOT_ENABLED;
nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (!psvc)
return NS_OK;
// A preference controls whether or not the full page plugin is disabled for
// a particular type. The string must be in the form:
// type1,type2,type3,type4
// Note: need an actual interface to control this and subsequent disabling
// (and other plugin host settings) so applications can reliably disable
// plugins - without relying on implementation details such as prefs/category
// manager entries.
nsXPIDLCString overrideTypes;
psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
overrideTypes.Insert(',', 0);
overrideTypes.Append(',');
nsCAutoString commaSeparated(',');
commaSeparated.Append(aMimeType);
commaSeparated.Append(',');
if (overrideTypes.Find(commaSeparated) != kNotFound)
return NS_OK;
nsPluginTag* plugin = FindPluginForType(aMimeType, PR_TRUE);
if (!plugin || !plugin->IsEnabled())
return NS_OK;
*aResult = mOverrideInternalTypes ? OVERRIDE_BUILTIN : AVAILABLE;
return NS_OK;
}
// check comma delimitered extensions
static int CompareExtensions(const char *aExtensionList, const char *aExtension)
{
@ -3354,9 +3390,6 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile * pluginsDir,
pluginTag->SetHost(this);
pluginTag->mNext = mPlugins;
mPlugins = pluginTag;
if (pluginTag->IsEnabled())
pluginTag->RegisterWithCategoryManager(mOverrideInternalTypes);
}
}

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

@ -412,104 +412,16 @@ nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
return NS_OK;
}
void
nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
nsPluginTag::nsRegisterType aType)
{
if (!mMimeTypeArray)
return;
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
if (!catMan)
return;
const char *contractId = "@mozilla.org/content/plugin/document-loader-factory;1";
nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (!psvc)
return; // NS_ERROR_OUT_OF_MEMORY
// A preference controls whether or not the full page plugin is disabled for
// a particular type. The string must be in the form:
// type1,type2,type3,type4
// Note: need an actual interface to control this and subsequent disabling
// (and other plugin host settings) so applications can reliably disable
// plugins - without relying on implementation details such as prefs/category
// manager entries.
nsXPIDLCString overrideTypes;
psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
nsCAutoString overrideTypesFormatted;
overrideTypesFormatted.Assign(',');
overrideTypesFormatted += overrideTypes;
overrideTypesFormatted.Append(',');
nsACString::const_iterator start, end;
for (int i = 0; i < mVariants; i++) {
if (aType == ePluginUnregister) {
nsXPIDLCString value;
if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
mMimeTypeArray[i],
getter_Copies(value)))) {
// Only delete the entry if a plugin registered for it
if (strcmp(value, contractId) == 0) {
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
mMimeTypeArray[i],
PR_TRUE);
}
}
} else {
overrideTypesFormatted.BeginReading(start);
overrideTypesFormatted.EndReading(end);
nsDependentCString mimeType(mMimeTypeArray[i]);
nsCAutoString commaSeparated;
commaSeparated.Assign(',');
commaSeparated += mimeType;
commaSeparated.Append(',');
if (!FindInReadable(commaSeparated, start, end)) {
catMan->AddCategoryEntry("Gecko-Content-Viewers",
mMimeTypeArray[i],
contractId,
PR_FALSE, /* persist: broken by bug 193031 */
aOverrideInternalTypes, /* replace if we're told to */
nsnull);
}
}
PLUGIN_LOG(PLUGIN_LOG_NOISY,
("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
mMimeTypeArray[i], mFileName.get()));
}
}
void nsPluginTag::Mark(PRUint32 mask)
{
PRBool wasEnabled = IsEnabled();
mFlags |= mask;
// Update entries in the category manager if necessary.
if (mPluginHost && wasEnabled != IsEnabled()) {
if (wasEnabled)
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
else
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
}
}
void nsPluginTag::UnMark(PRUint32 mask)
{
PRBool wasEnabled = IsEnabled();
mFlags &= ~mask;
// Update entries in the category manager if necessary.
if (mPluginHost && wasEnabled != IsEnabled()) {
if (wasEnabled)
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
else
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
}
}
PRBool nsPluginTag::HasFlag(PRUint32 flag)
@ -563,12 +475,6 @@ void nsPluginTag::TryUnloadPlugin()
// again so the calling code should not be fooled and reload
// the library fresh
mLibrary = nsnull;
// Remove mime types added to the category manager
// only if we were made 'active' by setting the host
if (mPluginHost) {
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
}
}
/* nsPluginInstanceTag */

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

@ -66,11 +66,6 @@ struct nsPluginInfo;
class nsPluginTag : public nsIPluginTag
{
public:
enum nsRegisterType {
ePluginRegister,
ePluginUnregister
};
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGINTAG
@ -98,8 +93,6 @@ public:
PRUint32 Flags();
PRBool Equals(nsPluginTag* aPluginTag);
PRBool IsEnabled();
void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
nsRegisterType aType = ePluginRegister);
nsRefPtr<nsPluginTag> mNext;
nsPluginHost *mPluginHost;