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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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