summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkjyoun@google.com <kjyoun@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-26 08:48:02 +0000
committerkjyoun@google.com <kjyoun@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-26 08:48:02 +0000
commit7752111e67891fe059234d8a95273bfd787ea9e7 (patch)
treeddf086eb2cac14c6ea2f0ece3b035f8bbf92637a
parente7ecb9f057db7f5f769c7f6a6ae82215e21531a8 (diff)
downloadchromium_src-7752111e67891fe059234d8a95273bfd787ea9e7.zip
chromium_src-7752111e67891fe059234d8a95273bfd787ea9e7.tar.gz
chromium_src-7752111e67891fe059234d8a95273bfd787ea9e7.tar.bz2
Enable pepper-plugin through PepperPluginManager
PepperPluginManager loads plugins only from system apk, to ensure that only pre-installed plugin should be loaded BUG=175929 Review URL: https://chromiumcodereview.appspot.com/12213082 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184608 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/android/android_browser_process.cc15
-rw-r--r--content/browser/android/content_startup_flags.cc8
-rw-r--r--content/browser/android/content_startup_flags.h3
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java15
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/PepperPluginManager.java130
5 files changed, 164 insertions, 7 deletions
diff --git a/content/browser/android/android_browser_process.cc b/content/browser/android/android_browser_process.cc
index 6a7f981..edc48e6 100644
--- a/content/browser/android/android_browser_process.cc
+++ b/content/browser/android/android_browser_process.cc
@@ -17,8 +17,11 @@ namespace content {
static void SetCommandLineFlags(JNIEnv*env,
jclass clazz,
- jint max_render_process_count) {
- SetContentCommandLineFlags(max_render_process_count);
+ jint max_render_process_count,
+ jstring plugin_descriptor) {
+ std::string plugin_str = (plugin_descriptor == NULL ?
+ std::string() : ConvertJavaStringToUTF8(env, plugin_descriptor));
+ SetContentCommandLineFlags(max_render_process_count, plugin_str);
}
static jboolean IsOfficialBuild(JNIEnv* env, jclass clazz) {
@@ -29,6 +32,14 @@ static jboolean IsOfficialBuild(JNIEnv* env, jclass clazz) {
#endif
}
+static jboolean IsPluginEnabled(JNIEnv* env, jclass clazz) {
+#if defined(ENABLE_PLUGINS)
+ return true;
+#else
+ return false;
+#endif
+}
+
bool RegisterAndroidBrowserProcess(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index d4c941f..fdfc1eb 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -15,7 +15,8 @@
namespace content {
-void SetContentCommandLineFlags(int max_render_process_count) {
+void SetContentCommandLineFlags(int max_render_process_count,
+ const std::string& plugin_descriptor) {
// May be called multiple times, to cover all possible program entry points.
static bool already_initialized = false;
if (already_initialized)
@@ -69,6 +70,11 @@ void SetContentCommandLineFlags(int max_render_process_count) {
parsed_command_line->AppendSwitch(
cc::switches::kEnableCompositorFrameMessage);
+
+ if (!plugin_descriptor.empty()) {
+ parsed_command_line->AppendSwitchNative(
+ switches::kRegisterPepperPlugins, plugin_descriptor);
+ }
}
} // namespace content
diff --git a/content/browser/android/content_startup_flags.h b/content/browser/android/content_startup_flags.h
index de9df53..836ea3c 100644
--- a/content/browser/android/content_startup_flags.h
+++ b/content/browser/android/content_startup_flags.h
@@ -12,7 +12,8 @@ namespace content {
// Force-appends flags to the command line turning on Android-specific
// features owned by Content. This is called as soon as possible during
// initialization to make sure code sees the new flags.
-void SetContentCommandLineFlags(int max_render_process_count);
+void SetContentCommandLineFlags(int max_render_process_count,
+ const std::string& plugin_descriptor);
} // namespace content
diff --git a/content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java b/content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java
index 17d96aa..2e26342 100644
--- a/content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java
+++ b/content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java
@@ -12,6 +12,7 @@ import android.util.Log;
import org.chromium.base.JNINamespace;
import org.chromium.content.app.ContentMain;
import org.chromium.content.app.LibraryLoader;
+import org.chromium.content.browser.PepperPluginManager;
import org.chromium.content.common.CommandLine;
import org.chromium.content.common.ProcessInitException;
@@ -96,7 +97,8 @@ public class AndroidBrowserProcess {
// Now we really need to have the resources ready.
resourceExtractor.waitForCompletion();
- nativeSetCommandLineFlags(maxRenderers);
+ nativeSetCommandLineFlags(maxRenderers,
+ nativeIsPluginEnabled() ? getPlugins(context) : null);
ContentMain.initApplicationContext(appContext);
int result = ContentMain.start();
if (result > 0) throw new ProcessInitException(result);
@@ -113,13 +115,20 @@ public class AndroidBrowserProcess {
// Having a single renderer should be sufficient for tests.
// We can't have more than MAX_RENDERERS_LIMIT.
- nativeSetCommandLineFlags(1 /* maxRenderers */);
+ nativeSetCommandLineFlags(1 /* maxRenderers */, null);
}
- private static native void nativeSetCommandLineFlags(int maxRenderProcesses);
+ private static String getPlugins(final Context context) {
+ return PepperPluginManager.getPlugins(context);
+ }
+
+ private static native void nativeSetCommandLineFlags(int maxRenderProcesses,
+ String pluginDescriptor);
// Is this an official build of Chrome? Only native code knows
// for sure. Official build knowledge is needed very early in
// process startup.
private static native boolean nativeIsOfficialBuild();
+
+ private static native boolean nativeIsPluginEnabled();
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/PepperPluginManager.java b/content/public/android/java/src/org/chromium/content/browser/PepperPluginManager.java
new file mode 100644
index 0000000..ad594b8
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/PepperPluginManager.java
@@ -0,0 +1,130 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * {@link PepperPluginManager} collects meta data about plugins from preloaded android apps
+ * that reply to PEPPERPLUGIN intent query.
+ */
+public class PepperPluginManager {
+
+ private static final String LOGTAG = "PepperPluginManager";
+
+ /**
+ * Service Action: A plugin wishes to be loaded in the ContentView must
+ * provide {@link android.content.IntentFilter IntentFilter} that accepts
+ * this action in its AndroidManifest.xml.
+ */
+ public static final String PEPPER_PLUGIN_ACTION = "org.chromium.intent.PEPPERPLUGIN";
+ public static final String PEPPER_PLUGIN_ROOT = "/system/lib/pepperplugin/";
+
+ // A plugin will specify the following fields in its AndroidManifest.xml.
+ private static final String FILENAME = "filename";
+ private static final String MIMETYPE = "mimetype";
+ private static final String NAME = "name";
+ private static final String DESCRIPTION = "description";
+ private static final String VERSION = "version";
+
+ private static String getPluginDescription(Bundle metaData) {
+ // Find the name of the plugin's shared library.
+ String filename = metaData.getString(FILENAME);
+ if (filename == null || filename.isEmpty()) {
+ return null;
+ }
+ // Find the mimetype of the plugin. Flash is handled in getFlashPath.
+ String mimetype = metaData.getString(MIMETYPE);
+ if (mimetype == null || mimetype.isEmpty()) {
+ return null;
+ }
+ // Assemble the plugin info, according to the format described in
+ // pepper_plugin_registry.cc.
+ // (eg. path<#name><#description><#version>;mimetype)
+ StringBuffer plugin = new StringBuffer(PEPPER_PLUGIN_ROOT);
+ plugin.append(filename);
+
+ // Find the (optional) name/description/version of the plugin.
+ String name = metaData.getString(NAME);
+ String description = metaData.getString(DESCRIPTION);
+ String version = metaData.getString(VERSION);
+
+ if (name != null && !name.isEmpty()) {
+ plugin.append("#");
+ plugin.append(name);
+ if (description != null && !description.isEmpty()) {
+ plugin.append("#");
+ plugin.append(description);
+ if (version != null && !version.isEmpty()) {
+ plugin.append("#");
+ plugin.append(version);
+ }
+ }
+ }
+ plugin.append(';');
+ plugin.append(mimetype);
+
+ return plugin.toString();
+ }
+
+ /**
+ * Collects information about installed plugins and returns a plugin description
+ * string, which will be appended to for command line to load plugins.
+ *
+ * @param context Android context
+ * @return Description string for plugins
+ */
+ public static String getPlugins(final Context context) {
+ StringBuffer ret = new StringBuffer();
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> plugins = pm.queryIntentServices(
+ new Intent(PEPPER_PLUGIN_ACTION),
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+ for (ResolveInfo info : plugins) {
+ // Retrieve the plugin's service information.
+ ServiceInfo serviceInfo = info.serviceInfo;
+ if (serviceInfo == null || serviceInfo.metaData == null ||
+ serviceInfo.packageName == null) {
+ Log.e(LOGTAG, "Can't get service information from " + info);
+ continue;
+ }
+
+ // Retrieve the plugin's package information.
+ PackageInfo pkgInfo;
+ try {
+ pkgInfo = pm.getPackageInfo(serviceInfo.packageName, 0);
+ } catch (NameNotFoundException e) {
+ Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
+ continue;
+ }
+ if (pkgInfo == null ||
+ (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ continue;
+ }
+ Log.i(LOGTAG, "The given plugin package is preloaded: " + serviceInfo.packageName);
+
+ String plugin = getPluginDescription(serviceInfo.metaData);
+ if (plugin == null) {
+ continue;
+ }
+ if (ret.length() > 0) {
+ ret.append(',');
+ }
+ ret.append(plugin);
+ }
+ return ret.toString();
+ }
+}