关于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绑定到一起的。
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绑定到一起的。
相关文章推荐
- 关于Android中View滑动知识的一点个人理解
- 2.7-3 Android Studio 的Gradle一点理解, 查看gradle 版本和android 插件的版本
- webkit加载flash 10.3插件跟踪过程
- 关于插件技术的一点理解
- webkit加载flash 10.3插件跟踪过程
- 关于android 和 耗时操作的一点理解
- 【Android ContentProvider 一】关于ContactsContract.CommonDataKinds.Phone.CONTENT_URI的一点理解
- android 4.0中关于webview加载flash并使flash全屏的问题(附demo)
- android 4.0中关于webview加载flash并使flash全屏的问题(附demo)
- [转载+实践理解]Android动画---如何正确使用平移动画(关于fillBefore和fillAfter的一点说明)(转载)
- 2.7-3 Android Studio 的Gradle一点理解, 查看gradle 版本和android 插件的版本
- 2.7-3 Android Studio 的Gradle一点理解, 查看gradle 版本和android 插件的版本
- android 如何动态的加载类----app插件技术
- 理解WebKit和Chromium: Chromium for Android
- 关于对FLASH开发,starling、starling feathers、starling MVC框架的理解
- Android开发中关于Layout_weight的理解
- android插件开发——加载插件
- android-关于Resources的理解。
- 理解WebKit和Chromium: 插件机制(NPAPI Plugin)
- Android WebKit插件的基本结构