Bug 723217: Fix click-to-play support for plugins on Android. r=snorp

This commit is contained in:
Josh Aas 2012-02-10 08:39:40 -05:00
parent b351fc30f8
commit 7f8b14d760
5 changed files with 42 additions and 72 deletions

View File

@ -484,16 +484,18 @@ IsSupportedImage(const nsCString& aMimeType)
return NS_SUCCEEDED(rv) && supported; return NS_SUCCEEDED(rv) && supported;
} }
static bool nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMEType)
IsSupportedPlugin(const nsCString& aMIMEType, bool aShouldPlay)
{ {
if (!mShouldPlay) {
return NS_ERROR_PLUGIN_CLICKTOPLAY;
}
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID)); nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get()); nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
if (!pluginHost) { if (!pluginHost) {
return false; return false;
} }
nsresult rv = pluginHost->IsPluginEnabledForType(aMIMEType.get(), aShouldPlay); return pluginHost->IsPluginEnabledForType(aMIMEType.get());
return NS_SUCCEEDED(rv);
} }
static void static void
@ -517,9 +519,12 @@ GetExtensionFromURI(nsIURI* uri, nsCString& ext)
* Checks whether a plugin exists and is enabled for the extension * Checks whether a plugin exists and is enabled for the extension
* in the given URI. The MIME type is returned in the mimeType out parameter. * in the given URI. The MIME type is returned in the mimeType out parameter.
*/ */
static bool bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType, bool aShouldPlay)
{ {
if (!mShouldPlay) {
return false;
}
nsCAutoString ext; nsCAutoString ext;
GetExtensionFromURI(uri, ext); GetExtensionFromURI(uri, ext);
@ -534,8 +539,7 @@ IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType, bool aShouldPlay)
} }
const char* typeFromExt; const char* typeFromExt;
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt, if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
aShouldPlay))) {
mimeType = typeFromExt; mimeType = typeFromExt;
return true; return true;
} }
@ -568,6 +572,10 @@ nsObjectLoadingContent::~nsObjectLoadingContent()
nsresult nsresult
nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI) nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI)
{ {
if (!mShouldPlay) {
return NS_ERROR_PLUGIN_CLICKTOPLAY;
}
// Don't do anything if we already have an active instance. // Don't do anything if we already have an active instance.
if (mInstanceOwner) { if (mInstanceOwner) {
return NS_OK; return NS_OK;
@ -586,11 +594,6 @@ nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI*
nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this; nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this;
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this)); nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
nsCString typeToUse(aMimeType);
if (typeToUse.IsEmpty() && aURI) {
IsPluginEnabledByExtension(aURI, typeToUse, mShouldPlay);
}
nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> baseURI;
if (!aURI) { if (!aURI) {
// We need some URI. If we have nothing else, use the base URI. // We need some URI. If we have nothing else, use the base URI.
@ -730,10 +733,10 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
if ((channelType.EqualsASCII(APPLICATION_OCTET_STREAM) && if ((channelType.EqualsASCII(APPLICATION_OCTET_STREAM) &&
!mContentType.IsEmpty() && !mContentType.IsEmpty() &&
GetTypeOfContent(mContentType) != eType_Document) || GetTypeOfContent(mContentType) != eType_Document) ||
// Need to check IsSupportedPlugin() in addition to GetTypeOfContent() // Need to check IsPluginEnabledForType() in addition to GetTypeOfContent()
// because otherwise the default plug-in's catch-all behavior would // because otherwise the default plug-in's catch-all behavior would
// confuse things. // confuse things.
(IsSupportedPlugin(mContentType, mShouldPlay) && (NS_SUCCEEDED(IsPluginEnabledForType(mContentType)) &&
GetTypeOfContent(mContentType) == eType_Plugin)) { GetTypeOfContent(mContentType) == eType_Plugin)) {
// Set the type we'll use for dispatch on the channel. Otherwise we could // Set the type we'll use for dispatch on the channel. Otherwise we could
// end up trying to dispatch to a nsFrameLoader, which will complain that // end up trying to dispatch to a nsFrameLoader, which will complain that
@ -752,7 +755,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
if (mContentType.EqualsASCII(APPLICATION_OCTET_STREAM)) { if (mContentType.EqualsASCII(APPLICATION_OCTET_STREAM)) {
nsCAutoString extType; nsCAutoString extType;
if (IsPluginEnabledByExtension(uri, extType, mShouldPlay)) { if (IsPluginEnabledByExtension(uri, extType)) {
mContentType = extType; mContentType = extType;
chan->SetContentType(extType); chan->SetContentType(extType);
} }
@ -1297,8 +1300,8 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
nsCAutoString overrideType; nsCAutoString overrideType;
if ((caps & eOverrideServerType) && if ((caps & eOverrideServerType) &&
((!aTypeHint.IsEmpty() && IsSupportedPlugin(aTypeHint, mShouldPlay)) || ((!aTypeHint.IsEmpty() && NS_SUCCEEDED(IsPluginEnabledForType(aTypeHint))) ||
(aURI && IsPluginEnabledByExtension(aURI, overrideType, mShouldPlay)))) { (aURI && IsPluginEnabledByExtension(aURI, overrideType)))) {
ObjectType newType; ObjectType newType;
if (overrideType.IsEmpty()) { if (overrideType.IsEmpty()) {
newType = GetTypeOfContent(aTypeHint); newType = GetTypeOfContent(aTypeHint);
@ -1434,7 +1437,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
return NS_OK; return NS_OK;
} }
if (IsSupportedPlugin(aTypeHint, mShouldPlay)) { if (NS_SUCCEEDED(IsPluginEnabledForType(aTypeHint))) {
mType = eType_Plugin; mType = eType_Plugin;
} else { } else {
rv = NS_ERROR_NOT_AVAILABLE; rv = NS_ERROR_NOT_AVAILABLE;
@ -1744,7 +1747,7 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
return eType_Document; return eType_Document;
} }
if ((caps & eSupportPlugins) && IsSupportedPlugin(aMIMEType, mShouldPlay)) { if ((caps & eSupportPlugins) && NS_SUCCEEDED(IsPluginEnabledForType(aMIMEType))) {
return eType_Plugin; return eType_Plugin;
} }
@ -1755,16 +1758,10 @@ nsresult
nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID, nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID,
nsACString& aType) nsACString& aType)
{ {
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
if (!pluginHost) {
return NS_ERROR_NOT_AVAILABLE;
}
if (StringBeginsWith(aClassID, NS_LITERAL_STRING("java:"))) { if (StringBeginsWith(aClassID, NS_LITERAL_STRING("java:"))) {
// Supported if we have a java plugin // Supported if we have a java plugin
aType.AssignLiteral("application/x-java-vm"); aType.AssignLiteral("application/x-java-vm");
nsresult rv = pluginHost->IsPluginEnabledForType("application/x-java-vm"); nsresult rv = IsPluginEnabledForType(NS_LITERAL_CSTRING("application/x-java-vm"));
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_NOT_AVAILABLE; return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_NOT_AVAILABLE;
} }
@ -1772,11 +1769,11 @@ nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID,
if (StringBeginsWith(aClassID, NS_LITERAL_STRING("clsid:"), nsCaseInsensitiveStringComparator())) { if (StringBeginsWith(aClassID, NS_LITERAL_STRING("clsid:"), nsCaseInsensitiveStringComparator())) {
// Check if we have a plugin for that // Check if we have a plugin for that
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForType("application/x-oleobject"))) { if (NS_SUCCEEDED(IsPluginEnabledForType(NS_LITERAL_CSTRING("application/x-oleobject")))) {
aType.AssignLiteral("application/x-oleobject"); aType.AssignLiteral("application/x-oleobject");
return NS_OK; return NS_OK;
} }
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForType("application/oleobject"))) { if (NS_SUCCEEDED(IsPluginEnabledForType(NS_LITERAL_CSTRING("application/oleobject")))) {
aType.AssignLiteral("application/oleobject"); aType.AssignLiteral("application/oleobject");
return NS_OK; return NS_OK;
} }
@ -1832,7 +1829,7 @@ nsObjectLoadingContent::HandleBeingBlockedByContentPolicy(nsresult aStatus,
} }
} }
/* static */ PluginSupportState PluginSupportState
nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent, nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
const nsCString& aContentType) const nsCString& aContentType)
{ {
@ -1866,16 +1863,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
GetPluginDisabledState(aContentType); GetPluginDisabledState(aContentType);
} }
/* static */ PluginSupportState PluginSupportState
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType) nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
{ {
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID)); nsresult rv = IsPluginEnabledForType(aContentType);
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
if (!pluginHost) {
return ePluginUnsupported;
}
nsresult rv = pluginHost->IsPluginEnabledForType(aContentType.get());
if (rv == NS_ERROR_PLUGIN_DISABLED) if (rv == NS_ERROR_PLUGIN_DISABLED)
return ePluginDisabled; return ePluginDisabled;
if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY) if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY)
@ -2117,6 +2108,7 @@ nsObjectLoadingContent::PlayPlugin()
if (!nsContentUtils::IsCallerChrome()) if (!nsContentUtils::IsCallerChrome())
return NS_OK; return NS_OK;
mSrcStreamLoadInitiated = false;
mShouldPlay = true; mShouldPlay = true;
return LoadObject(mURI, true, mContentType, true); return LoadObject(mURI, true, mContentType, true);
} }

View File

@ -328,9 +328,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
* *
* This should only be called if the type of this content is eType_Null. * This should only be called if the type of this content is eType_Null.
*/ */
static PluginSupportState PluginSupportState GetPluginSupportState(nsIContent* aContent, const nsCString& aContentType);
GetPluginSupportState(nsIContent* aContent,
const nsCString& aContentType);
/** /**
* If the plugin for aContentType is disabled, return ePluginDisabled. * If the plugin for aContentType is disabled, return ePluginDisabled.
@ -339,17 +337,17 @@ class nsObjectLoadingContent : public nsImageLoadingContent
* *
* This should only be called if the type of this content is eType_Null. * This should only be called if the type of this content is eType_Null.
*/ */
static PluginSupportState PluginSupportState GetPluginDisabledState(const nsCString& aContentType);
GetPluginDisabledState(const nsCString& aContentType);
/** /**
* When there is no usable plugin available this will send UI events and * When there is no usable plugin available this will send UI events and
* update the AutoFallback object appropriate to the reason for there being * update the AutoFallback object appropriate to the reason for there being
* no plugin available. * no plugin available.
*/ */
static void void UpdateFallbackState(nsIContent* aContent, AutoFallback& fallback, const nsCString& aTypeHint);
UpdateFallbackState(nsIContent* aContent, AutoFallback& fallback,
const nsCString& aTypeHint); nsresult IsPluginEnabledForType(const nsCString& aMIMEType);
bool IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType);
/** /**
* The final listener to ship the data to (imagelib, uriloader, etc) * The final listener to ship the data to (imagelib, uriloader, etc)

View File

@ -1367,18 +1367,10 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
nsresult nsresult
nsPluginHost::IsPluginEnabledForType(const char* aMimeType) nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
{
// If plugins.click_to_play is false, plugins should always play
return IsPluginEnabledForType(aMimeType,
!Preferences::GetBool("plugins.click_to_play", false));
}
nsresult
nsPluginHost::IsPluginEnabledForType(const char* aMimeType, bool aShouldPlay)
{ {
nsPluginTag *plugin = FindPluginForType(aMimeType, true); nsPluginTag *plugin = FindPluginForType(aMimeType, true);
if (plugin) if (plugin)
return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY; return NS_OK;
// Pass false as the second arg so we can return NS_ERROR_PLUGIN_DISABLED // Pass false as the second arg so we can return NS_ERROR_PLUGIN_DISABLED
// for disabled plug-ins. // for disabled plug-ins.
@ -1393,7 +1385,7 @@ nsPluginHost::IsPluginEnabledForType(const char* aMimeType, bool aShouldPlay)
return NS_ERROR_PLUGIN_DISABLED; return NS_ERROR_PLUGIN_DISABLED;
} }
return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY; return NS_OK;
} }
// check comma delimitered extensions // check comma delimitered extensions
@ -1421,22 +1413,13 @@ static int CompareExtensions(const char *aExtensionList, const char *aExtension)
return PL_strcasecmp(pExt, aExtension); return PL_strcasecmp(pExt, aExtension);
} }
nsresult
nsPluginHost::IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType)
{
// If plugins.click_to_play is false, plugins should always play
return IsPluginEnabledForExtension(aExtension, aMimeType,
!Preferences::GetBool("plugins.click_to_play", false));
}
nsresult nsresult
nsPluginHost::IsPluginEnabledForExtension(const char* aExtension, nsPluginHost::IsPluginEnabledForExtension(const char* aExtension,
const char* &aMimeType, const char* &aMimeType)
bool aShouldPlay)
{ {
nsPluginTag *plugin = FindPluginEnabledForExtension(aExtension, aMimeType); nsPluginTag *plugin = FindPluginEnabledForExtension(aExtension, aMimeType);
if (plugin) if (plugin)
return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY; return NS_OK;
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

View File

@ -120,11 +120,8 @@ public:
nsIURI *aURL, nsIURI *aURL,
nsIPluginInstanceOwner *aOwner); nsIPluginInstanceOwner *aOwner);
nsresult IsPluginEnabledForType(const char* aMimeType); nsresult IsPluginEnabledForType(const char* aMimeType);
nsresult IsPluginEnabledForType(const char* aMimeType,
bool aShouldPlay);
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType); nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType,
bool aShouldPlay);
nsresult GetPluginCount(PRUint32* aPluginCount); nsresult GetPluginCount(PRUint32* aPluginCount);
nsresult GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray); nsresult GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray);

View File

@ -310,7 +310,7 @@ nsContentDLF::CreateInstance(const char* aCommand,
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID)); nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get()); nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
if(pluginHost && if(pluginHost &&
NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType, true))) { NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType))) {
return CreateDocument(aCommand, return CreateDocument(aCommand,
aChannel, aLoadGroup, aChannel, aLoadGroup,
aContainer, kPluginDocumentCID, aContainer, kPluginDocumentCID,