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