您的位置:首页 > 移动开发 > Android开发

关于Android Webkit的Flash插件加载的一点理解

2011-06-12 21:05 477 查看
这个不是文档,这个是个人臆测。

Webkit插件加载路径代码在external/webkit/webcore/plugins/PluginDatabase.cpp中。

代码为:

Vector<String> PluginDatabase::defaultPluginDirectories()

{

Vector<String> paths;

// Add paths specific to each platform

#if defined(XP_UNIX)

String userPluginPath = homeDirectoryPath();

userPluginPath.append(String("/.mozilla/plugins"));

paths.append(userPluginPath);

userPluginPath = homeDirectoryPath();

userPluginPath.append(String("/.netscape/plugins"));

paths.append(userPluginPath);

paths.append("/usr/lib/browser/plugins");

paths.append("/usr/local/lib/mozilla/plugins");

paths.append("/usr/lib/firefox/plugins");

paths.append("/usr/lib64/browser-plugins");

paths.append("/usr/lib/browser-plugins");

paths.append("/usr/lib/mozilla/plugins");

paths.append("/usr/local/netscape/plugins");

paths.append("/opt/mozilla/plugins");

paths.append("/opt/mozilla/lib/plugins");

paths.append("/opt/netscape/plugins");

paths.append("/opt/netscape/communicator/plugins");

paths.append("/usr/lib/netscape/plugins");

paths.append("/usr/lib/netscape/plugins-libc5");

paths.append("/usr/lib/netscape/plugins-libc6");

paths.append("/usr/lib64/netscape/plugins");

paths.append("/usr/lib64/mozilla/plugins");

paths.append("/usr/lib/nsbrowser/plugins");

paths.append("/usr/lib64/nsbrowser/plugins");

String mozHome(getenv("MOZILLA_HOME"));

mozHome.append("/plugins");

paths.append(mozHome);

Vector<String> mozPaths;

String mozPath(getenv("MOZ_PLUGIN_PATH"));

mozPath.split(UChar(':'), /* allowEmptyEntries */ false, mozPaths);

paths.append(mozPaths);

#elif defined(XP_MACOSX)

String userPluginPath = homeDirectoryPath();

userPluginPath.append(String("/Library/Internet Plug-Ins"));

paths.append(userPluginPath);

paths.append("/Library/Internet Plug-Ins");

#elif defined(XP_WIN)

String userPluginPath = homeDirectoryPath();

userPluginPath.append(String("//Application
Data//Mozilla//plugins"));

paths.append(userPluginPath);

#endif

// Add paths specific to each port

#if PLATFORM(QT)

Vector<String> qtPaths;

String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").constData());

qtPath.split(UChar(':'), /* allowEmptyEntries */ false, qtPaths);

paths.append(qtPaths);

#endif

#if PLATFORM(ANDROID)

if (android::JavaSharedClient::GetPluginClient())

return android::JavaSharedClient::GetPluginClient()->getPluginDirectories();

#endif


return paths;

}

红色代码返回到Java共享段,路径为frameworks/base/core/java/android/webkit/PluginManager.java

这儿代码还没仔细看,后续介绍。

String[] getPluginDirectories() {

ArrayList<String> directories = new ArrayList<String>();

PackageManager pm = mContext.getPackageManager();

List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(

PLUGIN_ACTION), PackageManager.GET_SERVICES

| 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, "Ignore bad plugin");

continue;

}

// retrieve information from the plugin's manifest

PackageInfo pkgInfo;

try {

pkgInfo = pm.getPackageInfo(serviceInfo.packageName,

PackageManager.GET_PERMISSIONS

| PackageManager.GET_SIGNATURES);

} catch (NameNotFoundException e) {

Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);

continue;

}

if (pkgInfo == null) {

continue;

}

// check if their is a conflict in the lib directory names

String directory = pkgInfo.applicationInfo.dataDir + "/lib";

if (directories.contains(directory)) {

continue;

}

// check if the plugin has the required permissions

String permissions[] = pkgInfo.requestedPermissions;

if (permissions == null) {

continue;

}

boolean permissionOk = false;

for (String permit : permissions) {

if (PLUGIN_PERMISSION.equals(permit)) {

permissionOk = true;

break;

}

}

if (!permissionOk) {

continue;

}

// check to ensure the plugin is properly signed

Signature signatures[] = pkgInfo.signatures;

if (signatures == null) {

continue;

}

if (SystemProperties.getBoolean("ro.secure", false)) {

boolean signatureMatch = false;

for (Signature signature : signatures) {

for (int i = 0; i < SIGNATURES.length; i++) {

if (SIGNATURES[i].equals(signature)) {

signatureMatch = true;

break;

}

}

}

if (!signatureMatch) {

continue;

}

}

// determine the type of plugin from the manifest

if (serviceInfo.metaData == null) {

Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined");

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()]);

}

狗日的插件打开地址:external/webkit/WebCore/plugins/android/PluginPackageAndroid.cpp

webkit找插件的过程

1. PluginDatabase::defaultPluginDirectories()

2. GetPluginClient()->getPluginDirectories()

3. 因为JavaBridge继承自PluginClient,所以WTF::Vector<WebCore::String>JavaBridge::getPluginDirectories()

4. 找到mGetPluginDirectories这个方法,调用java的方法getPluginDirectories

5. private String[] JWebCoreJavaBridge::getPluginDirectories()

6. String[] PluginManager::getPluginDirectories()

7. 经过一系列的包的权限等的分析,把通过筛选的路径返回。

此上只是找到合适的路径,那么打开过程呢。

1. addExtraPluginDirectory或者installedPlugins

2. bool PluginDatabase::refresh()

3. PluginPackage::createPackage

4. PluginPackage::fetchInfo()

5. // Open the library

void *handle = dlopen(m_path.utf8().data(), RTLD_NOW);

如何在java里添加extra_plugin的路径

webkit_web_settings_add_extra_plugin_directory

loadJavaClass

anp_loadJavaClass

------------------------------------------------------------------------

private Class<?> getPluginClass(String libName, String clsName)

String getPluginsAPKName(String pluginLib)

pluginManager.getPluginClass(pkgName, clsName);

可见浏览器插件是跟apk绑定到一起的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: