diff options
author | kjyoun@google.com <kjyoun@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-26 08:48:02 +0000 |
---|---|---|
committer | kjyoun@google.com <kjyoun@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-26 08:48:02 +0000 |
commit | 7752111e67891fe059234d8a95273bfd787ea9e7 (patch) | |
tree | ddf086eb2cac14c6ea2f0ece3b035f8bbf92637a | |
parent | e7ecb9f057db7f5f769c7f6a6ae82215e21531a8 (diff) | |
download | chromium_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
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(); + } +} |