Bug 1381916 - Remove frontend support for plugins in Fennec r=nechen

MozReview-Commit-ID: Gkqe8Y5AMPV
This commit is contained in:
James Willcox 2017-07-18 15:46:53 -05:00
parent 5d84114d12
commit 25dad4abf2
17 changed files with 4 additions and 621 deletions

View File

@ -447,15 +447,9 @@ pref("browser.ui.scroll-toolbar-threshold", 10);
pref("browser.ui.selection.distance", 250);
// plugins
pref("plugin.disable", false);
pref("plugin.disable", true);
pref("dom.ipc.plugins.enabled", false);
// This pref isn't actually used anymore, but we're leaving this here to avoid changing
// the default so that we can migrate a user-set pref. See bug 885357.
pref("plugins.click_to_play", true);
// The default value for nsIPluginTag.enabledState (STATE_CLICKTOPLAY = 1)
pref("plugin.default.state", 1);
// product URLs
// The breakpad report server to link to in about:crashes
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");

View File

@ -31,11 +31,6 @@
android:layout_height="match_parent"
android:scrollbars="none"/>
<AbsoluteLayout android:id="@+id/plugin_container"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<org.mozilla.gecko.FormAssistPopup android:id="@+id/form_assist_popup"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -13,16 +13,6 @@
<item>0</item>
<item>1</item>
</string-array>
<string-array name="pref_plugins_entries">
<item>@string/pref_plugins_enabled</item>
<item>@string/pref_plugins_tap_to_play</item>
<item>@string/pref_plugins_disabled</item>
</string-array>
<string-array name="pref_plugins_values">
<item>1</item>
<item>2</item>
<item>0</item>
</string-array>
<string-array name="pref_char_encoding_entries">
<item>@string/pref_char_encoding_on</item>
<item>@string/pref_char_encoding_off</item>

View File

@ -54,12 +54,6 @@
<PreferenceCategory android:title="@string/pref_category_media">
<ListPreference android:key="plugin.enable"
android:title="@string/pref_plugins"
android:entries="@array/pref_plugins_entries"
android:entryValues="@array/pref_plugins_values"
android:persistent="false" />
<SwitchPreference android:key="media.autoplay.enabled"
android:title="@string/pref_media_autoplay_enabled"
android:summary="@string/pref_media_autoplay_enabled_summary" />

View File

@ -194,9 +194,6 @@ public abstract class GeckoApp extends GeckoActivity
protected GeckoView mLayerView;
private FullScreenHolder mFullScreenPluginContainer;
private View mFullScreenPluginView;
protected boolean mLastSessionCrashed;
protected boolean mShouldRestore;
private boolean mSessionRestoreParsingFinished = false;
@ -809,11 +806,6 @@ public abstract class GeckoApp extends GeckoActivity
} else if ("Update:Install".equals(event)) {
UpdateServiceHelper.applyUpdate(this);
} else if ("PluginHelper:playFlash".equals(event)) {
final SharedPreferences prefs = getSharedPreferences();
int count = prefs.getInt(PREFS_FLASH_USAGE, 0);
prefs.edit().putInt(PREFS_FLASH_USAGE, ++count).apply();
} else if ("Mma:reader_available".equals(event)) {
MmaDelegate.track(READER_AVAILABLE);
@ -917,113 +909,6 @@ public abstract class GeckoApp extends GeckoActivity
});
}
/* package */ void addFullScreenPluginView(View view) {
if (mFullScreenPluginView != null) {
Log.w(LOGTAG, "Already have a fullscreen plugin view");
return;
}
setFullScreen(true);
view.setWillNotDraw(false);
if (view instanceof SurfaceView) {
((SurfaceView) view).setZOrderOnTop(true);
}
mFullScreenPluginContainer = new FullScreenHolder(this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER);
mFullScreenPluginContainer.addView(view, layoutParams);
FrameLayout decor = (FrameLayout)getWindow().getDecorView();
decor.addView(mFullScreenPluginContainer, layoutParams);
mFullScreenPluginView = view;
}
@WrapForJNI(calledFrom = "gecko")
private static void addPluginView(final View view) {
final Activity activity = GeckoActivityMonitor.getInstance().getCurrentActivity();
if (!(activity instanceof GeckoApp)) {
return;
}
final GeckoApp geckoApp = (GeckoApp) activity;
if (ThreadUtils.isOnUiThread()) {
geckoApp.addFullScreenPluginView(view);
} else {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
geckoApp.addFullScreenPluginView(view);
}
});
}
}
/* package */ void removeFullScreenPluginView(View view) {
if (mFullScreenPluginView == null) {
Log.w(LOGTAG, "Don't have a fullscreen plugin view");
return;
}
if (mFullScreenPluginView != view) {
Log.w(LOGTAG, "Passed view is not the current full screen view");
return;
}
mFullScreenPluginContainer.removeView(mFullScreenPluginView);
// We need do do this on the next iteration in order to avoid
// a deadlock, see comment below in FullScreenHolder
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mLayerView.showSurface();
}
});
FrameLayout decor = (FrameLayout)getWindow().getDecorView();
decor.removeView(mFullScreenPluginContainer);
mFullScreenPluginView = null;
GeckoScreenOrientation.getInstance().unlock();
setFullScreen(false);
}
@WrapForJNI(calledFrom = "gecko")
private static void removePluginView(final View view) {
final Activity activity = GeckoActivityMonitor.getInstance().getCurrentActivity();
if (!(activity instanceof GeckoApp)) {
return;
}
final GeckoApp geckoApp = (GeckoApp) activity;
if (ThreadUtils.isOnUiThread()) {
geckoApp.removeFullScreenPluginView(view);
} else {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
geckoApp.removeFullScreenPluginView(view);
}
});
}
}
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
private static native void onFullScreenPluginHidden(View view);
@WrapForJNI(calledFrom = "gecko")
private static Context getPluginContext() {
return GeckoActivityMonitor.getInstance().getCurrentActivity();
}
private void showSetImageResult(final boolean success, final int message, final String path) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@ -1303,7 +1188,6 @@ public abstract class GeckoApp extends GeckoActivity
EventDispatcher.getInstance().registerGeckoThreadListener(this,
"Accessibility:Ready",
"Gecko:Ready",
"PluginHelper:playFlash",
null);
EventDispatcher.getInstance().registerUiThreadListener(this,
@ -2330,7 +2214,6 @@ public abstract class GeckoApp extends GeckoActivity
EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
"Accessibility:Ready",
"Gecko:Ready",
"PluginHelper:playFlash",
null);
EventDispatcher.getInstance().unregisterUiThreadListener(this,
@ -2545,12 +2428,6 @@ public abstract class GeckoApp extends GeckoActivity
return;
}
if (mFullScreenPluginView != null) {
onFullScreenPluginHidden(mFullScreenPluginView);
removeFullScreenPluginView(mFullScreenPluginView);
return;
}
if (mLayerView != null && mLayerView.isFullScreen()) {
EventDispatcher.getInstance().dispatch("FullScreen:Exit", null);
return;
@ -2683,71 +2560,6 @@ public abstract class GeckoApp extends GeckoActivity
}
}
private class FullScreenHolder extends FrameLayout {
public FullScreenHolder(Context ctx) {
super(ctx);
setBackgroundColor(0xff000000);
}
@Override
public void addView(View view, int index) {
/**
* This normally gets called when Flash adds a separate SurfaceView
* for the video. It is unhappy if we have the LayerView underneath
* it for some reason so we need to hide that. Hiding the LayerView causes
* its surface to be destroyed, which causes a pause composition
* event to be sent to Gecko. We synchronously wait for that to be
* processed. Simultaneously, however, Flash is waiting on a mutex so
* the post() below is an attempt to avoid a deadlock.
*/
super.addView(view, index);
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mLayerView.hideSurface();
}
});
}
/**
* The methods below are simply copied from what Android WebKit does.
* It wasn't ever called in my testing, but might as well
* keep it in case it is for some reason. The methods
* all return true because we don't want any events
* leaking out from the fullscreen view.
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.isSystem()) {
return super.onKeyDown(keyCode, event);
}
mFullScreenPluginView.onKeyDown(keyCode, event);
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (event.isSystem()) {
return super.onKeyUp(keyCode, event);
}
mFullScreenPluginView.onKeyUp(keyCode, event);
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
mFullScreenPluginView.onTrackballEvent(event);
return true;
}
}
private int getVersionCode() {
int versionCode = 0;
try {

View File

@ -69,7 +69,6 @@ public class Tab {
private int mFaviconLoadId;
private String mContentType;
private boolean mHasTouchListeners;
private final ArrayList<View> mPluginViews;
private int mState;
private Bitmap mThumbnailBitmap;
private boolean mDesktopMode;
@ -129,7 +128,6 @@ public class Tab {
mTitle = title == null ? "" : title;
mSiteIdentity = new SiteIdentity();
mContentType = "";
mPluginViews = new ArrayList<View>();
mState = shouldShowProgress(url) ? STATE_LOADING : STATE_SUCCESS;
mLoadProgress = LOAD_PROGRESS_INIT;
mIconRequestBuilder = Icons.with(mAppContext).pageUrl(mUrl);
@ -736,18 +734,6 @@ public class Tab {
}
}
public void addPluginView(View view) {
mPluginViews.add(view);
}
public void removePluginView(View view) {
mPluginViews.remove(view);
}
public View[] getPluginViews() {
return mPluginViews.toArray(new View[mPluginViews.size()]);
}
public void setDesktopMode(boolean enabled) {
mDesktopMode = enabled;
}

View File

@ -361,10 +361,6 @@
<!ENTITY pref_clear_on_exit_title3 "Clear private data on exit">
<!ENTITY pref_clear_on_exit_summary2 "&brandShortName; will automatically clear your data whenever you select \u0022Quit\u0022 from the main menu">
<!ENTITY pref_clear_on_exit_dialog_title "Select which data to clear">
<!ENTITY pref_plugins "Plugins">
<!ENTITY pref_plugins_enabled "Enabled">
<!ENTITY pref_plugins_tap_to_play2 "Touch to play">
<!ENTITY pref_plugins_disabled "Disabled">
<!ENTITY pref_restore_tabs "Restore tabs">
<!ENTITY pref_restore_always "Always restore">
<!ENTITY pref_restore_quit "Don\'t restore after quitting &brandShortName;">

View File

@ -261,10 +261,6 @@
<string name="pref_clear_on_exit_title">&pref_clear_on_exit_title3;</string>
<string name="pref_clear_on_exit_summary2">&pref_clear_on_exit_summary2;</string>
<string name="pref_clear_on_exit_dialog_title">&pref_clear_on_exit_dialog_title;</string>
<string name="pref_plugins">&pref_plugins;</string>
<string name="pref_plugins_enabled">&pref_plugins_enabled;</string>
<string name="pref_plugins_tap_to_play">&pref_plugins_tap_to_play2;</string>
<string name="pref_plugins_disabled">&pref_plugins_disabled;</string>
<string name="pref_use_system_font_size">&pref_use_system_font_size;</string>
<string name="pref_use_system_font_size_summary">&pref_use_system_font_size_summary;</string>
<string name="pref_media_autoplay_enabled">&pref_media_autoplay_enabled;</string>

View File

@ -129,7 +129,6 @@ var WindowEventDispatcher = EventDispatcher.for(window);
var lazilyLoadedBrowserScripts = [
["MasterPassword", "chrome://browser/content/MasterPassword.js"],
["PluginHelper", "chrome://browser/content/PluginHelper.js"],
["OfflineApps", "chrome://browser/content/OfflineApps.js"],
["Linkifier", "chrome://browser/content/Linkify.js"],
["CastingApps", "chrome://browser/content/CastingApps.js"],
@ -1014,13 +1013,6 @@ var BrowserApp = {
}
if (currentUIVersion < 1) {
// Migrate user-set "plugins.click_to_play" pref. See bug 884694.
// Because the default value is true, a user-set pref means that the pref was set to false.
if (Services.prefs.prefHasUserValue("plugins.click_to_play")) {
Services.prefs.setIntPref("plugin.default.state", Ci.nsIPluginTag.STATE_ENABLED);
Services.prefs.clearUserPref("plugins.click_to_play");
}
// Migrate the "privacy.donottrackheader.value" pref. See bug 1042135.
if (Services.prefs.prefHasUserValue("privacy.donottrackheader.value")) {
// Make sure the doNotTrack value conforms to the conversion from
@ -1955,12 +1947,6 @@ var BrowserApp = {
aSubject.QueryInterface(Ci.nsIWritableVariant);
switch (aData) {
// The plugin pref is actually two separate prefs, so
// we need to handle it differently
case "plugin.enable":
aSubject.setAsAString(PluginHelper.getPluginPreference());
break;
// Handle master password
case "privacy.masterpassword.enabled":
aSubject.setAsBool(MasterPassword.enabled);
@ -1991,13 +1977,6 @@ var BrowserApp = {
let value = aSubject.QueryInterface(Ci.nsIVariant);
switch (aData) {
// The plugin pref is actually two separate prefs, so we need to
// handle it differently.
case "plugin.enable":
PluginHelper.setPluginPreference(value);
aSubject.setAsEmpty();
break;
// MasterPassword pref is not real, we just need take action and leave
case "privacy.masterpassword.enabled":
if (MasterPassword.enabled) {
@ -3473,9 +3452,6 @@ function Tab(aURL, aParams) {
this._parentId = -1;
this.lastTouchedAt = Date.now();
this.contentDocumentIsDisplayed = true;
this.pluginDoorhangerTimeout = null;
this.shouldShowPluginDoorhanger = true;
this.clickToPlayPluginsActivated = false;
this.desktopMode = false;
this.originalURI = null;
this.hasTouchListener = false;
@ -3643,7 +3619,6 @@ Tab.prototype = {
this.browser.addEventListener("DOMWindowFocus", this, true);
// Note that the XBL binding is untrusted
this.browser.addEventListener("PluginBindingAttached", this, true, true);
this.browser.addEventListener("VideoBindingAttached", this, true, true);
this.browser.addEventListener("VideoBindingCast", this, true, true);
@ -3758,7 +3733,6 @@ Tab.prototype = {
this.browser.removeEventListener("TabPreZombify", this, true);
this.browser.removeEventListener("DOMWindowFocus", this, true);
this.browser.removeEventListener("PluginBindingAttached", this, true, true);
this.browser.removeEventListener("VideoBindingAttached", this, true, true);
this.browser.removeEventListener("VideoBindingCast", this, true, true);
@ -4271,11 +4245,6 @@ Tab.prototype = {
break;
}
case "PluginBindingAttached": {
PluginHelper.handlePluginBindingAttached(this, aEvent);
break;
}
case "VideoBindingAttached": {
CastingApps.handleVideoBindingAttached(this, aEvent);
break;
@ -4454,12 +4423,6 @@ Tab.prototype = {
this.browser.messageManager.sendAsyncMessage("Reader:PushState", {isArticle: this.browser.isArticle});
}
// Reset state of click-to-play plugin notifications.
clearTimeout(this.pluginDoorhangerTimeout);
this.pluginDoorhangerTimeout = null;
this.shouldShowPluginDoorhanger = true;
this.clickToPlayPluginsActivated = false;
let baseDomain = "";
// For recognized scheme, get base domain from host.
let principalURI = contentWin.document.nodePrincipal.URI;
@ -5919,7 +5882,7 @@ var IdentityHandler = {
}
// We also allow "about:" by allowing the selector to be empty (i.e. '(|.....|...|...)'
let whitelist = /^about:($|about|accounts|addons|buildconfig|cache|config|crashes|devices|downloads|fennec|firefox|feedback|healthreport|home|license|logins|logo|memory|mozilla|networking|plugins|privatebrowsing|rights|serviceworkers|support|telemetry|webrtc)($|\?)/i;
let whitelist = /^about:($|about|accounts|addons|buildconfig|cache|config|crashes|devices|downloads|fennec|firefox|feedback|healthreport|home|license|logins|logo|memory|mozilla|networking|privatebrowsing|rights|serviceworkers|support|telemetry|webrtc)($|\?)/i;
if (uri.schemeIs("about") && whitelist.test(uri.spec)) {
return this.IDENTITY_MODE_CHROMEUI;
}

View File

@ -1407,229 +1407,6 @@ public class GeckoAppShell
}
}
/**
* A plugin that wish to be loaded in the WebView must provide this permission
* in their AndroidManifest.xml.
*/
public static final String PLUGIN_ACTION = "android.webkit.PLUGIN";
public static final String PLUGIN_PERMISSION = "android.webkit.permission.PLUGIN";
private static final String PLUGIN_SYSTEM_LIB = "/system/lib/plugins/";
private static final String PLUGIN_TYPE = "type";
private static final String TYPE_NATIVE = "native";
public static final ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<>();
// Returns null if plugins are blocked on the device.
static String[] getPluginDirectories() {
// Block on Pixel C.
if ((new File("/system/lib/hw/power.dragon.so")).exists()) {
Log.w(LOGTAG, "Blocking plugins because of Pixel C device (bug 1255122)");
return null;
}
// An awful hack to detect Tegra devices. Easiest way to do it without spinning up a EGL context.
boolean isTegra = (new File("/system/lib/hw/gralloc.tegra.so")).exists() ||
(new File("/system/lib/hw/gralloc.tegra3.so")).exists() ||
(new File("/sys/class/nvidia-gpu")).exists();
if (isTegra) {
// disable on KitKat (bug 957694)
if (Build.VERSION.SDK_INT >= 19) {
Log.w(LOGTAG, "Blocking plugins because of Tegra (bug 957694)");
return null;
}
// disable Flash on Tegra ICS with CM9 and other custom firmware (bug 736421)
final File vfile = new File("/proc/version");
try {
if (vfile.canRead()) {
final BufferedReader reader = new BufferedReader(new FileReader(vfile));
try {
final String version = reader.readLine();
if (version.indexOf("CM9") != -1 ||
version.indexOf("cyanogen") != -1 ||
version.indexOf("Nova") != -1) {
Log.w(LOGTAG, "Blocking plugins because of Tegra 2 + unofficial ICS bug (bug 736421)");
return null;
}
} finally {
reader.close();
}
}
} catch (IOException ex) {
// Do nothing.
}
}
ArrayList<String> directories = new ArrayList<String>();
PackageManager pm = getApplicationContext().getPackageManager();
List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(PLUGIN_ACTION),
PackageManager.GET_META_DATA);
synchronized (mPackageInfoCache) {
// clear the list of existing packageInfo objects
mPackageInfoCache.clear();
for (ResolveInfo info : plugins) {
// retrieve the plugin's service information
ServiceInfo serviceInfo = info.serviceInfo;
if (serviceInfo == null) {
Log.w(LOGTAG, "Ignoring bad plugin.");
continue;
}
// Blacklist HTC's flash lite.
// See bug #704516 - We're not quite sure what Flash Lite does,
// but loading it causes Flash to give errors and fail to draw.
if (serviceInfo.packageName.equals("com.htc.flashliteplugin")) {
Log.w(LOGTAG, "Skipping HTC's flash lite plugin");
continue;
}
// Retrieve information from the plugin's manifest.
PackageInfo pkgInfo;
try {
pkgInfo = pm.getPackageInfo(serviceInfo.packageName,
PackageManager.GET_PERMISSIONS
| PackageManager.GET_SIGNATURES);
} catch (Exception e) {
Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
continue;
}
if (pkgInfo == null) {
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Could not load package information.");
continue;
}
/*
* find the location of the plugin's shared library. The default
* is to assume the app is either a user installed app or an
* updated system app. In both of these cases the library is
* stored in the app's data directory.
*/
String directory = pkgInfo.applicationInfo.dataDir + "/lib";
final int appFlags = pkgInfo.applicationInfo.flags;
final int updatedSystemFlags = ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
// preloaded system app with no user updates
if ((appFlags & updatedSystemFlags) == ApplicationInfo.FLAG_SYSTEM) {
directory = PLUGIN_SYSTEM_LIB + pkgInfo.packageName;
}
// check if the plugin has the required permissions
String permissions[] = pkgInfo.requestedPermissions;
if (permissions == null) {
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Does not have required permission.");
continue;
}
boolean permissionOk = false;
for (String permit : permissions) {
if (PLUGIN_PERMISSION.equals(permit)) {
permissionOk = true;
break;
}
}
if (!permissionOk) {
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Does not have required permission (2).");
continue;
}
// check to ensure the plugin is properly signed
Signature signatures[] = pkgInfo.signatures;
if (signatures == null) {
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Not signed.");
continue;
}
// determine the type of plugin from the manifest
if (serviceInfo.metaData == null) {
Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no defined type.");
continue;
}
String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE);
if (!TYPE_NATIVE.equals(pluginType)) {
Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType);
continue;
}
try {
Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name);
//TODO implement any requirements of the plugin class here!
boolean classFound = true;
if (!classFound) {
Log.e(LOGTAG, "The plugin's class' " + serviceInfo.name + "' does not extend the appropriate class.");
continue;
}
} catch (NameNotFoundException e) {
Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
continue;
} catch (ClassNotFoundException e) {
Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name);
continue;
}
// if all checks have passed then make the plugin available
mPackageInfoCache.add(pkgInfo);
directories.add(directory);
}
}
return directories.toArray(new String[directories.size()]);
}
static String getPluginPackage(String pluginLib) {
if (pluginLib == null || pluginLib.length() == 0) {
return null;
}
synchronized (mPackageInfoCache) {
for (PackageInfo pkgInfo : mPackageInfoCache) {
if (pluginLib.contains(pkgInfo.packageName)) {
return pkgInfo.packageName;
}
}
}
return null;
}
static Class<?> getPluginClass(String packageName, String className)
throws NameNotFoundException, ClassNotFoundException {
Context pluginContext = getApplicationContext().createPackageContext(packageName,
Context.CONTEXT_INCLUDE_CODE |
Context.CONTEXT_IGNORE_SECURITY);
ClassLoader pluginCL = pluginContext.getClassLoader();
return pluginCL.loadClass(className);
}
@WrapForJNI
private static Class<?> loadPluginClass(String className, String libName) {
try {
final String packageName = getPluginPackage(libName);
final int contextFlags = Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY;
final Context pluginContext = getApplicationContext().createPackageContext(
packageName, contextFlags);
return pluginContext.getClassLoader().loadClass(className);
} catch (java.lang.ClassNotFoundException cnfe) {
Log.w(LOGTAG, "Couldn't find plugin class " + className, cnfe);
return null;
} catch (android.content.pm.PackageManager.NameNotFoundException nnfe) {
Log.w(LOGTAG, "Couldn't find package.", nnfe);
return null;
}
}
private static Context sApplicationContext;
@WrapForJNI

View File

@ -259,15 +259,8 @@ public class GeckoThread extends Thread {
res.updateConfiguration(config, null);
}
String[] pluginDirs = null;
try {
pluginDirs = GeckoAppShell.getPluginDirectories();
} catch (Exception e) {
Log.w(LOGTAG, "Caught exception getting plugin dirs.", e);
}
final String resourcePath = context.getPackageResourcePath();
GeckoLoader.setupGeckoEnvironment(context, pluginDirs, context.getFilesDir().getPath());
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath());
try {
loadGeckoLibs(context, resourcePath);

View File

@ -57,34 +57,6 @@ public final class GeckoLoader {
return sGREDir;
}
private static void setupPluginEnvironment(Context context, String[] pluginDirs) {
// setup plugin path directories
try {
// Check to see if plugins were blocked.
if (pluginDirs == null) {
putenv("MOZ_PLUGINS_BLOCKED=1");
putenv("MOZ_PLUGIN_PATH=");
return;
}
StringBuilder pluginSearchPath = new StringBuilder();
for (int i = 0; i < pluginDirs.length; i++) {
pluginSearchPath.append(pluginDirs[i]);
pluginSearchPath.append(":");
}
putenv("MOZ_PLUGIN_PATH=" + pluginSearchPath);
File pluginDataDir = context.getDir("plugins", 0);
putenv("ANDROID_PLUGIN_DATADIR=" + pluginDataDir.getPath());
File pluginPrivateDataDir = context.getDir("plugins_private", 0);
putenv("ANDROID_PLUGIN_DATADIR_PRIVATE=" + pluginPrivateDataDir.getPath());
} catch (Exception ex) {
Log.w(LOGTAG, "Caught exception getting plugin dirs.", ex);
}
}
private static void setupDownloadEnvironment(final Context context) {
try {
File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
@ -134,7 +106,7 @@ public final class GeckoLoader {
}
}
public static void setupGeckoEnvironment(Context context, String[] pluginDirs, String profilePath) {
public static void setupGeckoEnvironment(Context context, String profilePath) {
// if we have an intent (we're being launched by an activity)
// read in any environmental variables from it here
final SafeIntent intent = sIntent;
@ -155,7 +127,6 @@ public final class GeckoLoader {
putenv("MOZ_ANDROID_PACKAGE_NAME=" + context.getPackageName());
setupPluginEnvironment(context, pluginDirs);
setupDownloadEnvironment(context);
// profile home path

View File

@ -1,17 +0,0 @@
<html style="margin: 0; padding: 0">
<head>
<title>Adobe Flash Test</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<meta charset="utf-8">
</head>
<body style="margin: 0; padding: 0">
<object width="100" height="100"
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/
pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0">
<param name="SRC" value="green.swf">
<embed src="green.swf" width="100" height="100">
</embed>
</object>
</body>
</html>

View File

@ -81,7 +81,6 @@ public class StringHelper {
public final String ROBOCOP_PICTURE_LINK_URL = "/robocop/robocop_picture_link.html";
public final String ROBOCOP_SEARCH_URL = "/robocop/robocop_search.html";
public final String ROBOCOP_TEXT_PAGE_URL = "/robocop/robocop_text_page.html";
public final String ROBOCOP_ADOBE_FLASH_URL = "/robocop/robocop_adobe_flash.html";
public final String ROBOCOP_INPUT_URL = "/robocop/robocop_input.html";
public final String ROBOCOP_READER_MODE_BASIC_ARTICLE = "/robocop/reader_mode_pages/basic_article.html";
public final String ROBOCOP_LINK_TO_SLOW_LOADING = "/robocop/robocop_link_to_slow_loading.html";
@ -218,8 +217,6 @@ public class StringHelper {
public final String ADVANCED;
public final String DONT_SHOW_MENU;
public final String SHOW_MENU;
public final String DISABLED;
public final String TAP_TO_PLAY;
public final String HIDE_TITLE_BAR;
public final String RESTORE_TABS_LABEL;
@ -401,8 +398,6 @@ public class StringHelper {
ADVANCED = res.getString(R.string.pref_category_advanced);
DONT_SHOW_MENU = res.getString(R.string.pref_char_encoding_off);
SHOW_MENU = res.getString(R.string.pref_char_encoding_on);
DISABLED = res.getString(R.string.pref_plugins_disabled );
TAP_TO_PLAY = res.getString(R.string.pref_plugins_tap_to_play);
HIDE_TITLE_BAR = res.getString(R.string.pref_scroll_title_bar_summary );
RESTORE_TABS_LABEL = res.getString(R.string.pref_restore);

View File

@ -1,33 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.tests;
import org.json.JSONObject;
import org.mozilla.gecko.PaintedSurface;
import android.os.Build;
/**
* Tests that Flash is working
* - loads a page containing a Flash plugin
* - verifies it rendered properly
*/
public class testAdobeFlash extends PixelTest {
public void testLoad() {
// Enable plugins
setPreferenceAndWaitForChange("plugin.enable", "1");
blockForGeckoReady();
String url = getAbsoluteUrl(mStringHelper.ROBOCOP_ADOBE_FLASH_URL);
PaintedSurface painted = loadAndGetPainted(url);
mAsserter.ispixel(painted.getPixelAt(0, 0), 0, 0xff, 0, "Pixel at 0, 0");
mAsserter.ispixel(painted.getPixelAt(50, 50), 0, 0xff, 0, "Pixel at 50, 50");
mAsserter.ispixel(painted.getPixelAt(101, 0), 0xff, 0xff, 0xff, "Pixel at 101, 0");
mAsserter.ispixel(painted.getPixelAt(0, 101), 0xff, 0xff, 0xff, "Pixel at 0, 101");
}
}

View File

@ -465,14 +465,6 @@ auto GeckoAppShell::KillAnyZombies() -> void
return mozilla::jni::Method<KillAnyZombies_t>::Call(GeckoAppShell::Context(), nullptr);
}
constexpr char GeckoAppShell::LoadPluginClass_t::name[];
constexpr char GeckoAppShell::LoadPluginClass_t::signature[];
auto GeckoAppShell::LoadPluginClass(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> mozilla::jni::Class::LocalRef
{
return mozilla::jni::Method<LoadPluginClass_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1);
}
constexpr char GeckoAppShell::LockScreenOrientation_t::name[];
constexpr char GeckoAppShell::LockScreenOrientation_t::signature[];

View File

@ -1256,27 +1256,6 @@ public:
static auto KillAnyZombies() -> void;
struct LoadPluginClass_t {
typedef GeckoAppShell Owner;
typedef mozilla::jni::Class::LocalRef ReturnType;
typedef mozilla::jni::Class::Param SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
mozilla::jni::String::Param> Args;
static constexpr char name[] = "loadPluginClass";
static constexpr char signature[] =
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::CURRENT;
};
static auto LoadPluginClass(mozilla::jni::String::Param, mozilla::jni::String::Param) -> mozilla::jni::Class::LocalRef;
struct LockScreenOrientation_t {
typedef GeckoAppShell Owner;
typedef void ReturnType;