PepperPluginManager.java revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.content.browser; 6 7import android.content.Context; 8import android.content.Intent; 9import android.content.pm.ApplicationInfo; 10import android.content.pm.PackageInfo; 11import android.content.pm.PackageManager; 12import android.content.pm.PackageManager.NameNotFoundException; 13import android.content.pm.ResolveInfo; 14import android.content.pm.ServiceInfo; 15import android.os.Bundle; 16import android.util.Log; 17 18import org.chromium.base.ContextTypes; 19 20import java.util.List; 21 22/** 23 * {@link PepperPluginManager} collects meta data about plugins from preloaded android apps 24 * that reply to PEPPERPLUGIN intent query. 25 */ 26public class PepperPluginManager { 27 28 private static final String LOGTAG = "PepperPluginManager"; 29 30 /** 31 * Service Action: A plugin wishes to be loaded in the ContentView must 32 * provide {@link android.content.IntentFilter IntentFilter} that accepts 33 * this action in its AndroidManifest.xml. 34 */ 35 public static final String PEPPER_PLUGIN_ACTION = "org.chromium.intent.PEPPERPLUGIN"; 36 public static final String PEPPER_PLUGIN_ROOT = "/system/lib/pepperplugin/"; 37 38 // A plugin will specify the following fields in its AndroidManifest.xml. 39 private static final String FILENAME = "filename"; 40 private static final String MIMETYPE = "mimetype"; 41 private static final String NAME = "name"; 42 private static final String DESCRIPTION = "description"; 43 private static final String VERSION = "version"; 44 45 private static String getPluginDescription(Bundle metaData) { 46 // Find the name of the plugin's shared library. 47 String filename = metaData.getString(FILENAME); 48 if (filename == null || filename.isEmpty()) { 49 return null; 50 } 51 // Find the mimetype of the plugin. Flash is handled in getFlashPath. 52 String mimetype = metaData.getString(MIMETYPE); 53 if (mimetype == null || mimetype.isEmpty()) { 54 return null; 55 } 56 // Assemble the plugin info, according to the format described in 57 // pepper_plugin_list.cc. 58 // (eg. path<#name><#description><#version>;mimetype) 59 StringBuffer plugin = new StringBuffer(PEPPER_PLUGIN_ROOT); 60 plugin.append(filename); 61 62 // Find the (optional) name/description/version of the plugin. 63 String name = metaData.getString(NAME); 64 String description = metaData.getString(DESCRIPTION); 65 String version = metaData.getString(VERSION); 66 67 if (name != null && !name.isEmpty()) { 68 plugin.append("#"); 69 plugin.append(name); 70 if (description != null && !description.isEmpty()) { 71 plugin.append("#"); 72 plugin.append(description); 73 if (version != null && !version.isEmpty()) { 74 plugin.append("#"); 75 plugin.append(version); 76 } 77 } 78 } 79 plugin.append(';'); 80 plugin.append(mimetype); 81 82 return plugin.toString(); 83 } 84 85 /** 86 * Collects information about installed plugins and returns a plugin description 87 * string, which will be appended to for command line to load plugins. 88 * 89 * @param context Android context 90 * @return Description string for plugins 91 */ 92 public static String getPlugins(final Context context) { 93 if (DeviceUtils.isTv(context) && 94 !ContextTypes.isRunningInWebapp(context)) { 95 // Chrome-for-tv enables plugins only on webapp mode. 96 return null; 97 } 98 StringBuffer ret = new StringBuffer(); 99 PackageManager pm = context.getPackageManager(); 100 List<ResolveInfo> plugins = pm.queryIntentServices( 101 new Intent(PEPPER_PLUGIN_ACTION), 102 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); 103 for (ResolveInfo info : plugins) { 104 // Retrieve the plugin's service information. 105 ServiceInfo serviceInfo = info.serviceInfo; 106 if (serviceInfo == null || serviceInfo.metaData == null || 107 serviceInfo.packageName == null) { 108 Log.e(LOGTAG, "Can't get service information from " + info); 109 continue; 110 } 111 112 // Retrieve the plugin's package information. 113 PackageInfo pkgInfo; 114 try { 115 pkgInfo = pm.getPackageInfo(serviceInfo.packageName, 0); 116 } catch (NameNotFoundException e) { 117 Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName); 118 continue; 119 } 120 if (pkgInfo == null || 121 (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 122 continue; 123 } 124 Log.i(LOGTAG, "The given plugin package is preloaded: " + serviceInfo.packageName); 125 126 String plugin = getPluginDescription(serviceInfo.metaData); 127 if (plugin == null) { 128 continue; 129 } 130 if (ret.length() > 0) { 131 ret.append(','); 132 } 133 ret.append(plugin); 134 } 135 return ret.toString(); 136 } 137} 138