bug 687265 - Front-end support for flash on Android Fennec r=mbrubeck,blassey,dolske,jst

This commit is contained in:
Brad Lassey
2011-10-07 13:46:02 -04:00
parent 8b47856ac4
commit 03fb4f1a1b
14 changed files with 127 additions and 4 deletions

View File

@@ -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) {

View File

@@ -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
};
/**

View File

@@ -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!

View File

@@ -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)

View File

@@ -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",

View File

@@ -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

View File

@@ -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;
}
}
}
};

View File

@@ -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();

View File

@@ -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.">

View File

@@ -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>

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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);
}