Search in sources :

Example 1 with PluginManager

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;
}
Also used : PluginManager(com.didi.virtualapk.PluginManager) LoadedPlugin(com.didi.virtualapk.internal.LoadedPlugin) ProviderInfo(android.content.pm.ProviderInfo) ContentProvider(android.content.ContentProvider) Uri(android.net.Uri) File(java.io.File) OperationApplicationException(android.content.OperationApplicationException)

Example 2 with PluginManager

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;
        }
    }
}
Also used : PluginManager(com.didi.virtualapk.PluginManager) LoadedPlugin(com.didi.virtualapk.internal.LoadedPlugin) ProviderInfo(android.content.pm.ProviderInfo) Bundle(android.os.Bundle) Uri(android.net.Uri)

Example 3 with PluginManager

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;
}
Also used : PluginManager(com.didi.virtualapk.PluginManager) LoadedPlugin(com.didi.virtualapk.internal.LoadedPlugin) ProviderInfo(android.content.pm.ProviderInfo) ContentProvider(android.content.ContentProvider) Uri(android.net.Uri) File(java.io.File) OperationApplicationException(android.content.OperationApplicationException)

Example 4 with PluginManager

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;
        }
    }
}
Also used : PluginManager(com.didi.virtualapk.PluginManager) LoadedPlugin(com.didi.virtualapk.internal.LoadedPlugin) ProviderInfo(android.content.pm.ProviderInfo) Bundle(android.os.Bundle) Uri(android.net.Uri)

Aggregations

ProviderInfo (android.content.pm.ProviderInfo)4 Uri (android.net.Uri)4 PluginManager (com.didi.virtualapk.PluginManager)4 LoadedPlugin (com.didi.virtualapk.internal.LoadedPlugin)4 ContentProvider (android.content.ContentProvider)2 OperationApplicationException (android.content.OperationApplicationException)2 Bundle (android.os.Bundle)2 File (java.io.File)2