bug 687265 - Front-end support for flash on Android Fennec r=mbrubeck,blassey,dolske,jst
This commit is contained in:
@@ -105,6 +105,10 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
|||||||
#define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
|
#define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
|
||||||
#define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
|
#define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||||
public:
|
public:
|
||||||
// This stores both the content and the frame so that Instantiate calls can be
|
// This stores both the content and the frame so that Instantiate calls can be
|
||||||
@@ -200,6 +204,9 @@ nsPluginErrorEvent::Run()
|
|||||||
mContent.get()));
|
mContent.get()));
|
||||||
nsString type;
|
nsString type;
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
|
case ePluginClickToPlay:
|
||||||
|
type = NS_LITERAL_STRING("PluginClickToPlay");
|
||||||
|
break;
|
||||||
case ePluginUnsupported:
|
case ePluginUnsupported:
|
||||||
type = NS_LITERAL_STRING("PluginNotFound");
|
type = NS_LITERAL_STRING("PluginNotFound");
|
||||||
break;
|
break;
|
||||||
@@ -1056,7 +1063,11 @@ nsObjectLoadingContent::ObjectState() const
|
|||||||
case eType_Image:
|
case eType_Image:
|
||||||
return ImageState();
|
return ImageState();
|
||||||
case eType_Plugin:
|
case eType_Plugin:
|
||||||
case eType_Document:
|
#ifdef ANDROID
|
||||||
|
if (XRE_GetProcessType() == GeckoProcessType_Content)
|
||||||
|
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
|
||||||
|
#endif
|
||||||
|
case eType_Document:
|
||||||
// These are OK. If documents start to load successfully, they display
|
// These are OK. If documents start to load successfully, they display
|
||||||
// something, and are thus not broken in this sense. The same goes for
|
// something, and are thus not broken in this sense. The same goes for
|
||||||
// plugins.
|
// plugins.
|
||||||
@@ -1070,6 +1081,8 @@ nsObjectLoadingContent::ObjectState() const
|
|||||||
// Otherwise, broken
|
// Otherwise, broken
|
||||||
nsEventStates state = NS_EVENT_STATE_BROKEN;
|
nsEventStates state = NS_EVENT_STATE_BROKEN;
|
||||||
switch (mFallbackReason) {
|
switch (mFallbackReason) {
|
||||||
|
case ePluginClickToPlay:
|
||||||
|
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
|
||||||
case ePluginDisabled:
|
case ePluginDisabled:
|
||||||
state |= NS_EVENT_STATE_HANDLER_DISABLED;
|
state |= NS_EVENT_STATE_HANDLER_DISABLED;
|
||||||
break;
|
break;
|
||||||
@@ -1949,6 +1962,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
|||||||
/* static */ PluginSupportState
|
/* static */ PluginSupportState
|
||||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||||
{
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
if (XRE_GetProcessType() == GeckoProcessType_Content)
|
||||||
|
return ePluginClickToPlay;
|
||||||
|
#endif
|
||||||
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) {
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ enum PluginSupportState {
|
|||||||
ePluginBlocklisted, // The plugin is blocklisted and disabled
|
ePluginBlocklisted, // The plugin is blocklisted and disabled
|
||||||
ePluginOutdated, // The plugin is considered outdated, but not disabled
|
ePluginOutdated, // The plugin is considered outdated, but not disabled
|
||||||
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
|
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
|
||||||
ePluginCrashed
|
ePluginCrashed,
|
||||||
|
ePluginClickToPlay
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -264,6 +264,8 @@ private:
|
|||||||
// Content is the full screen element, or a frame containing the
|
// Content is the full screen element, or a frame containing the
|
||||||
// current full-screen element.
|
// current full-screen element.
|
||||||
#define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(34)
|
#define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(34)
|
||||||
|
// Handler for click to play plugin
|
||||||
|
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
|
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
|
||||||
|
|||||||
@@ -94,6 +94,7 @@
|
|||||||
#include "nsXPCOMCID.h"
|
#include "nsXPCOMCID.h"
|
||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
|
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
|
|
||||||
// for the dialog
|
// for the dialog
|
||||||
@@ -2251,6 +2252,11 @@ nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
|
|||||||
|
|
||||||
nsresult nsPluginHost::LoadPlugins()
|
nsresult nsPluginHost::LoadPlugins()
|
||||||
{
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// do not do anything if it is already done
|
// do not do anything if it is already done
|
||||||
// use ReloadPlugins() to enforce loading
|
// use ReloadPlugins() to enforce loading
|
||||||
if (mPluginsLoaded)
|
if (mPluginsLoaded)
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
|
|||||||
CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING)
|
CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING)
|
||||||
CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
|
CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
|
||||||
NS_EVENT_STATE_TYPE_UNSUPPORTED)
|
NS_EVENT_STATE_TYPE_UNSUPPORTED)
|
||||||
|
CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay",
|
||||||
|
NS_EVENT_STATE_TYPE_CLICK_TO_PLAY)
|
||||||
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
|
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
|
||||||
NS_EVENT_STATE_HANDLER_DISABLED)
|
NS_EVENT_STATE_HANDLER_DISABLED)
|
||||||
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
||||||
|
|||||||
@@ -437,10 +437,14 @@ pref("browser.ui.touch.weight.visited", 120); // percentage
|
|||||||
// plugins
|
// plugins
|
||||||
#if MOZ_PLATFORM_MAEMO == 6
|
#if MOZ_PLATFORM_MAEMO == 6
|
||||||
pref("plugin.disable", false);
|
pref("plugin.disable", false);
|
||||||
|
pref("dom.ipc.plugins.enabled", true);
|
||||||
|
#elifdef ANDROID
|
||||||
|
pref("plugin.disable", false);
|
||||||
|
pref("dom.ipc.plugins.enabled", false);
|
||||||
#else
|
#else
|
||||||
pref("plugin.disable", true);
|
pref("plugin.disable", true);
|
||||||
#endif
|
|
||||||
pref("dom.ipc.plugins.enabled", true);
|
pref("dom.ipc.plugins.enabled", true);
|
||||||
|
#endif
|
||||||
|
|
||||||
// process priority
|
// process priority
|
||||||
// higher values give content process less CPU time
|
// higher values give content process less CPU time
|
||||||
|
|||||||
@@ -400,6 +400,7 @@ var Browser = {
|
|||||||
messageManager.addMessageListener("Browser:CertException", this);
|
messageManager.addMessageListener("Browser:CertException", this);
|
||||||
messageManager.addMessageListener("Browser:BlockedSite", this);
|
messageManager.addMessageListener("Browser:BlockedSite", this);
|
||||||
messageManager.addMessageListener("Browser:ErrorPage", this);
|
messageManager.addMessageListener("Browser:ErrorPage", this);
|
||||||
|
messageManager.addMessageListener("Browser:PluginClickToPlayClicked", this);
|
||||||
|
|
||||||
// Broadcast a UIReady message so add-ons know we are finished with startup
|
// Broadcast a UIReady message so add-ons know we are finished with startup
|
||||||
let event = document.createEvent("Events");
|
let event = document.createEvent("Events");
|
||||||
@@ -498,6 +499,7 @@ var Browser = {
|
|||||||
messageManager.removeMessageListener("Browser:CertException", this);
|
messageManager.removeMessageListener("Browser:CertException", this);
|
||||||
messageManager.removeMessageListener("Browser:BlockedSite", this);
|
messageManager.removeMessageListener("Browser:BlockedSite", this);
|
||||||
messageManager.removeMessageListener("Browser:ErrorPage", this);
|
messageManager.removeMessageListener("Browser:ErrorPage", this);
|
||||||
|
messageManager.removeMessageListener("Browser:PluginClickToPlayClicked", this);
|
||||||
|
|
||||||
var os = Services.obs;
|
var os = Services.obs;
|
||||||
os.removeObserver(XPInstallObserver, "addon-install-blocked");
|
os.removeObserver(XPInstallObserver, "addon-install-blocked");
|
||||||
@@ -1275,6 +1277,31 @@ var Browser = {
|
|||||||
case "Browser:ErrorPage":
|
case "Browser:ErrorPage":
|
||||||
this._handleErrorPage(aMessage);
|
this._handleErrorPage(aMessage);
|
||||||
break;
|
break;
|
||||||
|
case "Browser:PluginClickToPlayClicked": {
|
||||||
|
// Save off session history
|
||||||
|
let parent = browser.parentNode;
|
||||||
|
let data = browser.__SS_data;
|
||||||
|
if (data.entries.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove the browser from the DOM, effectively killing it's content
|
||||||
|
parent.removeChild(browser);
|
||||||
|
|
||||||
|
// Re-create the browser as non-remote, so plugins work
|
||||||
|
browser.setAttribute("remote", "false");
|
||||||
|
parent.appendChild(browser);
|
||||||
|
|
||||||
|
// Reload the content using session history
|
||||||
|
browser.__SS_data = data;
|
||||||
|
let json = {
|
||||||
|
uri: data.entries[data.index - 1].url,
|
||||||
|
flags: null,
|
||||||
|
entries: data.entries,
|
||||||
|
index: data.index
|
||||||
|
};
|
||||||
|
browser.messageManager.sendAsyncMessage("WebNavigation:LoadURI", json);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1570,3 +1570,53 @@ var SelectionHandler = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SelectionHandler.init();
|
SelectionHandler.init();
|
||||||
|
|
||||||
|
|
||||||
|
var PluginHandler = {
|
||||||
|
init: function() {
|
||||||
|
addEventListener("PluginClickToPlay", this, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
addLinkClickCallback: function (linkNode, callbackName /*callbackArgs...*/) {
|
||||||
|
// XXX just doing (callback)(arg) was giving a same-origin error. bug?
|
||||||
|
let self = this;
|
||||||
|
let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
|
||||||
|
linkNode.addEventListener("click",
|
||||||
|
function(evt) {
|
||||||
|
if (!evt.isTrusted)
|
||||||
|
return;
|
||||||
|
evt.preventDefault();
|
||||||
|
if (callbackArgs.length == 0)
|
||||||
|
callbackArgs = [ evt ];
|
||||||
|
(self[callbackName]).apply(self, callbackArgs);
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
|
||||||
|
linkNode.addEventListener("keydown",
|
||||||
|
function(evt) {
|
||||||
|
if (!evt.isTrusted)
|
||||||
|
return;
|
||||||
|
if (evt.keyCode == evt.DOM_VK_RETURN) {
|
||||||
|
evt.preventDefault();
|
||||||
|
if (callbackArgs.length == 0)
|
||||||
|
callbackArgs = [ evt ];
|
||||||
|
evt.preventDefault();
|
||||||
|
(self[callbackName]).apply(self, callbackArgs);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEvent : function(event) {
|
||||||
|
if (event.type != "PluginClickToPlay")
|
||||||
|
return;
|
||||||
|
let plugin = event.target;
|
||||||
|
PluginHandler.addLinkClickCallback(plugin, "reloadToEnablePlugin");
|
||||||
|
},
|
||||||
|
|
||||||
|
reloadToEnablePlugin: function() {
|
||||||
|
sendAsyncMessage("Browser:PluginClickToPlayClicked", { });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PluginHandler.init();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
<!ENTITY pluginWizard.finalPage.restart.label "&brandShortName; needs to be restarted for the plugin(s) to work.">
|
<!ENTITY pluginWizard.finalPage.restart.label "&brandShortName; needs to be restarted for the plugin(s) to work.">
|
||||||
|
|
||||||
<!ENTITY missingPlugin "A plugin is needed to display this content.">
|
<!ENTITY missingPlugin "A plugin is needed to display this content.">
|
||||||
|
<!ENTITY clickToPlayPlugin "Tap here to activate plugin.">
|
||||||
<!ENTITY disabledPlugin "This plugin is disabled.">
|
<!ENTITY disabledPlugin "This plugin is disabled.">
|
||||||
<!ENTITY blockedPlugin.label "This plugin has been blocked for your protection.">
|
<!ENTITY blockedPlugin.label "This plugin has been blocked for your protection.">
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
<xul:spacer flex="1"/>
|
<xul:spacer flex="1"/>
|
||||||
<xul:box class="icon"/>
|
<xul:box class="icon"/>
|
||||||
<html:div class="msg msgUnsupported">&missingPlugin;</html:div>
|
<html:div class="msg msgUnsupported">&missingPlugin;</html:div>
|
||||||
|
<html:div class="msg msgClickToPlay"><html:a class="clickToPlayLink" href="">&clickToPlayPlugin;</html:a></html:div>
|
||||||
<html:div class="msg msgDisabled">&disabledPlugin;</html:div>
|
<html:div class="msg msgDisabled">&disabledPlugin;</html:div>
|
||||||
<html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
|
<html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
|
||||||
<html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
|
<html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
|
||||||
|
|||||||
@@ -41,12 +41,15 @@
|
|||||||
embed:-moz-handler-disabled,
|
embed:-moz-handler-disabled,
|
||||||
embed:-moz-handler-blocked,
|
embed:-moz-handler-blocked,
|
||||||
embed:-moz-handler-crashed,
|
embed:-moz-handler-crashed,
|
||||||
|
embed:-moz-handler-clicktoplay,
|
||||||
applet:-moz-handler-disabled,
|
applet:-moz-handler-disabled,
|
||||||
applet:-moz-handler-blocked,
|
applet:-moz-handler-blocked,
|
||||||
applet:-moz-handler-crashed,
|
applet:-moz-handler-crashed,
|
||||||
|
applet:-moz-handler-clicktoplay,
|
||||||
object:-moz-has-handlerref:-moz-handler-disabled,
|
object:-moz-has-handlerref:-moz-handler-disabled,
|
||||||
object:-moz-has-handlerref:-moz-handler-blocked,
|
object:-moz-has-handlerref:-moz-handler-blocked,
|
||||||
object:-moz-handler-crashed {
|
object:-moz-handler-crashed,
|
||||||
|
object:-moz-handler-clicktoplay {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-moz-binding: url('chrome://mozapps/content/plugins/pluginProblem.xml#pluginProblem') !important;
|
-moz-binding: url('chrome://mozapps/content/plugins/pluginProblem.xml#pluginProblem') !important;
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ html|applet:not([height]), html|applet[height=""] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:-moz-type-unsupported .mainBox,
|
:-moz-type-unsupported .mainBox,
|
||||||
|
:-moz-handler-clicktoplay .mainBox,
|
||||||
:-moz-handler-disabled .mainBox,
|
:-moz-handler-disabled .mainBox,
|
||||||
:-moz-handler-blocked .mainBox {
|
:-moz-handler-blocked .mainBox {
|
||||||
-moz-user-focus: normal;
|
-moz-user-focus: normal;
|
||||||
}
|
}
|
||||||
:-moz-type-unsupported .mainBox:focus,
|
:-moz-type-unsupported .mainBox:focus,
|
||||||
|
:-moz-handler-clicktoplay .mainBox:focus,
|
||||||
:-moz-handler-disabled .mainBox:focus,
|
:-moz-handler-disabled .mainBox:focus,
|
||||||
:-moz-handler-blocked .mainBox:focus {
|
:-moz-handler-blocked .mainBox:focus {
|
||||||
outline: 1px dotted;
|
outline: 1px dotted;
|
||||||
@@ -40,6 +42,7 @@ html|applet:not([height]), html|applet[height=""] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:-moz-type-unsupported .msgUnsupported,
|
:-moz-type-unsupported .msgUnsupported,
|
||||||
|
:-moz-handler-clicktoplay .msgClickToPlay,
|
||||||
:-moz-handler-disabled .msgDisabled,
|
:-moz-handler-disabled .msgDisabled,
|
||||||
:-moz-handler-disabled .msgManagePlugins,
|
:-moz-handler-disabled .msgManagePlugins,
|
||||||
:-moz-handler-blocked .msgBlocked,
|
:-moz-handler-blocked .msgBlocked,
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ html|a {
|
|||||||
:-moz-type-unsupported .icon[status="ready"] {
|
:-moz-type-unsupported .icon[status="ready"] {
|
||||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
|
background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
|
||||||
}
|
}
|
||||||
|
:-moz-handler-clicktoplay .icon {
|
||||||
|
background-image: url(chrome://mozapps/skin/plugins/contentPluginMissing.png);
|
||||||
|
}
|
||||||
:-moz-handler-disabled .icon {
|
:-moz-handler-disabled .icon {
|
||||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
|
background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ html|a {
|
|||||||
:-moz-type-unsupported .icon[status="ready"] {
|
:-moz-type-unsupported .icon[status="ready"] {
|
||||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
|
background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
|
||||||
}
|
}
|
||||||
|
:-moz-handler-clicktoplay .icon {
|
||||||
|
background-image: url(chrome://mozapps/skin/plugins/contentPluginMissing.png);
|
||||||
|
}
|
||||||
:-moz-handler-disabled .icon {
|
:-moz-handler-disabled .icon {
|
||||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
|
background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user