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_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "nsXULAppAPI.h"
|
||||
#endif
|
||||
|
||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||
public:
|
||||
// This stores both the content and the frame so that Instantiate calls can be
|
||||
@@ -200,6 +204,9 @@ nsPluginErrorEvent::Run()
|
||||
mContent.get()));
|
||||
nsString type;
|
||||
switch (mState) {
|
||||
case ePluginClickToPlay:
|
||||
type = NS_LITERAL_STRING("PluginClickToPlay");
|
||||
break;
|
||||
case ePluginUnsupported:
|
||||
type = NS_LITERAL_STRING("PluginNotFound");
|
||||
break;
|
||||
@@ -1056,6 +1063,10 @@ nsObjectLoadingContent::ObjectState() const
|
||||
case eType_Image:
|
||||
return ImageState();
|
||||
case eType_Plugin:
|
||||
#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
|
||||
// something, and are thus not broken in this sense. The same goes for
|
||||
@@ -1070,6 +1081,8 @@ nsObjectLoadingContent::ObjectState() const
|
||||
// Otherwise, broken
|
||||
nsEventStates state = NS_EVENT_STATE_BROKEN;
|
||||
switch (mFallbackReason) {
|
||||
case ePluginClickToPlay:
|
||||
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
|
||||
case ePluginDisabled:
|
||||
state |= NS_EVENT_STATE_HANDLER_DISABLED;
|
||||
break;
|
||||
@@ -1949,6 +1962,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
||||
/* static */ PluginSupportState
|
||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content)
|
||||
return ePluginClickToPlay;
|
||||
#endif
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
if (!pluginHost) {
|
||||
|
||||
@@ -65,7 +65,8 @@ enum PluginSupportState {
|
||||
ePluginBlocklisted, // The plugin is blocklisted and disabled
|
||||
ePluginOutdated, // The plugin is considered outdated, but not disabled
|
||||
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
|
||||
// current full-screen element.
|
||||
#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!
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#include "nsXPCOMCID.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
|
||||
// for the dialog
|
||||
@@ -2251,6 +2252,11 @@ nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
|
||||
|
||||
nsresult nsPluginHost::LoadPlugins()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
// do not do anything if it is already done
|
||||
// use ReloadPlugins() to enforce loading
|
||||
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(mozTypeUnsupported, ":-moz-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",
|
||||
NS_EVENT_STATE_HANDLER_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
||||
|
||||
@@ -437,10 +437,14 @@ pref("browser.ui.touch.weight.visited", 120); // percentage
|
||||
// plugins
|
||||
#if MOZ_PLATFORM_MAEMO == 6
|
||||
pref("plugin.disable", false);
|
||||
pref("dom.ipc.plugins.enabled", true);
|
||||
#elifdef ANDROID
|
||||
pref("plugin.disable", false);
|
||||
pref("dom.ipc.plugins.enabled", false);
|
||||
#else
|
||||
pref("plugin.disable", true);
|
||||
#endif
|
||||
pref("dom.ipc.plugins.enabled", true);
|
||||
#endif
|
||||
|
||||
// process priority
|
||||
// higher values give content process less CPU time
|
||||
|
||||
@@ -400,6 +400,7 @@ var Browser = {
|
||||
messageManager.addMessageListener("Browser:CertException", this);
|
||||
messageManager.addMessageListener("Browser:BlockedSite", this);
|
||||
messageManager.addMessageListener("Browser:ErrorPage", this);
|
||||
messageManager.addMessageListener("Browser:PluginClickToPlayClicked", this);
|
||||
|
||||
// Broadcast a UIReady message so add-ons know we are finished with startup
|
||||
let event = document.createEvent("Events");
|
||||
@@ -498,6 +499,7 @@ var Browser = {
|
||||
messageManager.removeMessageListener("Browser:CertException", this);
|
||||
messageManager.removeMessageListener("Browser:BlockedSite", this);
|
||||
messageManager.removeMessageListener("Browser:ErrorPage", this);
|
||||
messageManager.removeMessageListener("Browser:PluginClickToPlayClicked", this);
|
||||
|
||||
var os = Services.obs;
|
||||
os.removeObserver(XPInstallObserver, "addon-install-blocked");
|
||||
@@ -1275,6 +1277,31 @@ var Browser = {
|
||||
case "Browser:ErrorPage":
|
||||
this._handleErrorPage(aMessage);
|
||||
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();
|
||||
|
||||
|
||||
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 missingPlugin "A plugin is needed to display this content.">
|
||||
<!ENTITY clickToPlayPlugin "Tap here to activate plugin.">
|
||||
<!ENTITY disabledPlugin "This plugin is disabled.">
|
||||
<!ENTITY blockedPlugin.label "This plugin has been blocked for your protection.">
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
<xul:spacer flex="1"/>
|
||||
<xul:box class="icon"/>
|
||||
<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 msgBlocked">&blockedPlugin.label;</html:div>
|
||||
<html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
|
||||
|
||||
@@ -41,12 +41,15 @@
|
||||
embed:-moz-handler-disabled,
|
||||
embed:-moz-handler-blocked,
|
||||
embed:-moz-handler-crashed,
|
||||
embed:-moz-handler-clicktoplay,
|
||||
applet:-moz-handler-disabled,
|
||||
applet:-moz-handler-blocked,
|
||||
applet:-moz-handler-crashed,
|
||||
applet:-moz-handler-clicktoplay,
|
||||
object:-moz-has-handlerref:-moz-handler-disabled,
|
||||
object:-moz-has-handlerref:-moz-handler-blocked,
|
||||
object:-moz-handler-crashed {
|
||||
object:-moz-handler-crashed,
|
||||
object:-moz-handler-clicktoplay {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
-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-handler-clicktoplay .mainBox,
|
||||
:-moz-handler-disabled .mainBox,
|
||||
:-moz-handler-blocked .mainBox {
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
:-moz-type-unsupported .mainBox:focus,
|
||||
:-moz-handler-clicktoplay .mainBox:focus,
|
||||
:-moz-handler-disabled .mainBox:focus,
|
||||
:-moz-handler-blocked .mainBox:focus {
|
||||
outline: 1px dotted;
|
||||
@@ -40,6 +42,7 @@ html|applet:not([height]), html|applet[height=""] {
|
||||
}
|
||||
|
||||
:-moz-type-unsupported .msgUnsupported,
|
||||
:-moz-handler-clicktoplay .msgClickToPlay,
|
||||
:-moz-handler-disabled .msgDisabled,
|
||||
:-moz-handler-disabled .msgManagePlugins,
|
||||
:-moz-handler-blocked .msgBlocked,
|
||||
|
||||
@@ -34,6 +34,9 @@ html|a {
|
||||
:-moz-type-unsupported .icon[status="ready"] {
|
||||
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 {
|
||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@ html|a {
|
||||
:-moz-type-unsupported .icon[status="ready"] {
|
||||
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 {
|
||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDisabled.png);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user