use of com.didi.virtualapk.PluginManager in project VirtualAPK by didi.
the class RemoteContentProvider method getContentProvider.
private ContentProvider getContentProvider(final Uri uri) {
final PluginManager pluginManager = PluginManager.getInstance(getContext());
Uri pluginUri = Uri.parse(uri.getQueryParameter(KEY_URI));
final String auth = pluginUri.getAuthority();
ContentProvider cachedProvider = sCachedProviders.get(auth);
if (cachedProvider != null) {
return cachedProvider;
}
synchronized (sCachedProviders) {
LoadedPlugin plugin = pluginManager.getLoadedPlugin(uri.getQueryParameter(KEY_PKG));
if (plugin == null) {
try {
pluginManager.loadPlugin(new File(uri.getQueryParameter(KEY_PLUGIN)));
} catch (Exception e) {
e.printStackTrace();
}
}
final ProviderInfo providerInfo = pluginManager.resolveContentProvider(auth, 0);
if (providerInfo != null) {
RunUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
LoadedPlugin loadedPlugin = pluginManager.getLoadedPlugin(uri.getQueryParameter(KEY_PKG));
ContentProvider contentProvider = (ContentProvider) Class.forName(providerInfo.name).newInstance();
contentProvider.attachInfo(loadedPlugin.getPluginContext(), providerInfo);
sCachedProviders.put(auth, contentProvider);
} catch (Exception e) {
e.printStackTrace();
}
}
}, true);
return sCachedProviders.get(auth);
}
}
return null;
}
use of com.didi.virtualapk.PluginManager in project AndroidLife by CaMnter.
the class IContentProviderProxy method wrapperUri.
/**
* 1. 在 IContentProvider 调用任何方法的时候,都去找这个方法中的 Uri 参数
* - 当 IContentProvider # call(...) 的时候,先抽出 Bundle,再寻找其中的 Uri
* 2. 校验 url 是否是插件 ContentProvider
* 3. 是的话,获取 插件 ContentProvider 对应的 ProviderInfo 和 LoadedPlugin
* - 构造 插桩 ContentProvider 的 Uri
* - 该协议是复合 Uri 协议,包含了最初的 插件 ContentProvider Uri 信息
* 4. 根据 复合 Uri 协议,会 call 向 插桩 ContentProvider,在 插桩 ContentProvider
* - 内,再次分发 插件 ContentProvider Uri
*
* 5. 将复合 Uri 协议,替换 1. 中找到的 Uri 参数,IContentProvider # call(...) 的时
* - 候,先抽出 Bundle,替换其中的 Uri
*/
private void wrapperUri(Method method, Object[] args) {
Uri uri = null;
int index = 0;
if (args != null) {
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Uri) {
uri = (Uri) args[i];
index = i;
break;
}
}
}
Bundle bundleInCallMethod = null;
if (method.getName().equals("call")) {
bundleInCallMethod = getBundleParameter(args);
if (bundleInCallMethod != null) {
String uriString = bundleInCallMethod.getString(KEY_WRAPPER_URI);
if (uriString != null) {
uri = Uri.parse(uriString);
}
}
}
if (uri == null) {
return;
}
PluginManager pluginManager = PluginManager.getInstance(mContext);
ProviderInfo info = pluginManager.resolveContentProvider(uri.getAuthority(), 0);
if (info != null) {
String pkg = info.packageName;
LoadedPlugin plugin = pluginManager.getLoadedPlugin(pkg);
String pluginUri = Uri.encode(uri.toString());
StringBuilder builder = new StringBuilder(PluginContentResolver.getUri(mContext));
builder.append("/?plugin=" + plugin.getLocation());
builder.append("&pkg=" + pkg);
builder.append("&uri=" + pluginUri);
Uri wrapperUri = Uri.parse(builder.toString());
if (method.getName().equals("call")) {
bundleInCallMethod.putString(KEY_WRAPPER_URI, wrapperUri.toString());
} else {
args[index] = wrapperUri;
}
}
}
use of com.didi.virtualapk.PluginManager in project AndroidLife by CaMnter.
the class RemoteContentProvider method getContentProvider.
/**
* 获取插件 ContentProvider
*
* 1. 解析复合 Uri 协议,获取其中包含的插件 Uri 协议
* 2. 获取插件 插件 Uri 协议 中的 Authority
* 3. 根据 插件 Uri Authority,拿出插件 ContentProvider 缓存
*
* 4. 当前面没获取到插件 ContentProvider 缓存的时候,根据 插件 Uri 协议包含的该 ContentProvider 所在
* - apk file 的绝对路径,获取到对应的 LoadedPlugin。如果还没有 LoadedPlugin,需要根据 apk file path
* - 加载出 LoadedPlugin
*
* 5. 在保证有 LoadedPlugin 缓存的情况下。去获取该 插件 ContentProvider 对应的 ProviderInfo 信息
* 6. 给 主线程 发消息,主线程获取对应的 LoadedPlugin 缓存,然后加载出对应的 插件 ContentProvider class
* - 手动调用 ContentProvider # attachInfo(...)。最后加入到 插件 ContentProvider 集合内
*
* @param uri uri
* @return ContentProvider
*/
private ContentProvider getContentProvider(final Uri uri) {
final PluginManager pluginManager = PluginManager.getInstance(getContext());
Uri pluginUri = Uri.parse(uri.getQueryParameter(KEY_URI));
final String auth = pluginUri.getAuthority();
ContentProvider cachedProvider = sCachedProviders.get(auth);
if (cachedProvider != null) {
return cachedProvider;
}
synchronized (sCachedProviders) {
LoadedPlugin plugin = pluginManager.getLoadedPlugin(uri.getQueryParameter(KEY_PKG));
if (plugin == null) {
try {
pluginManager.loadPlugin(new File(uri.getQueryParameter(KEY_PLUGIN)));
} catch (Exception e) {
e.printStackTrace();
}
}
final ProviderInfo providerInfo = pluginManager.resolveContentProvider(auth, 0);
if (providerInfo != null) {
RunUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
LoadedPlugin loadedPlugin = pluginManager.getLoadedPlugin(uri.getQueryParameter(KEY_PKG));
ContentProvider contentProvider = (ContentProvider) Class.forName(providerInfo.name).newInstance();
contentProvider.attachInfo(loadedPlugin.getPluginContext(), providerInfo);
sCachedProviders.put(auth, contentProvider);
} catch (Exception e) {
e.printStackTrace();
}
}
}, true);
return sCachedProviders.get(auth);
}
}
return null;
}
use of com.didi.virtualapk.PluginManager in project VirtualAPK by didi.
the class IContentProviderProxy method wrapperUri.
private void wrapperUri(Method method, Object[] args) {
Uri uri = null;
int index = 0;
if (args != null) {
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Uri) {
uri = (Uri) args[i];
index = i;
break;
}
}
}
Bundle bundleInCallMethod = null;
if (method.getName().equals("call")) {
bundleInCallMethod = getBundleParameter(args);
if (bundleInCallMethod != null) {
String uriString = bundleInCallMethod.getString(KEY_WRAPPER_URI);
if (uriString != null) {
uri = Uri.parse(uriString);
}
}
}
if (uri == null) {
return;
}
PluginManager pluginManager = PluginManager.getInstance(mContext);
ProviderInfo info = pluginManager.resolveContentProvider(uri.getAuthority(), 0);
if (info != null) {
String pkg = info.packageName;
LoadedPlugin plugin = pluginManager.getLoadedPlugin(pkg);
String pluginUri = Uri.encode(uri.toString());
StringBuilder builder = new StringBuilder(PluginContentResolver.getUri(mContext));
builder.append("/?plugin=" + plugin.getLocation());
builder.append("&pkg=" + pkg);
builder.append("&uri=" + pluginUri);
Uri wrapperUri = Uri.parse(builder.toString());
if (method.getName().equals("call")) {
bundleInCallMethod.putString(KEY_WRAPPER_URI, wrapperUri.toString());
} else {
args[index] = wrapperUri;
}
}
}
Aggregations