package com.limpoxe.fairy.content; import android.app.Application; import android.content.Intent; import android.os.Bundle; import com.limpoxe.fairy.util.LogUtil; import com.limpoxe.fairy.util.ResourceUtil; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * <Pre> * @author cailiming * </Pre> */ public class PluginDescriptor implements Serializable { private static final long serialVersionUID = -7545734825911798344L; public static final int UNKOWN = 0; public static final int BROADCAST = 1; public static final int ACTIVITY = 2; public static final int SERVICE = 4; public static final int PROVIDER = 6; public static final int FRAGMENT = 8; public static final int FUNCTION = 9; private String packageName; private String platformBuildVersionCode; private String platformBuildVersionName; private String minSdkVersion; private String targetSdkVersion; private String version; private String requiredHostVersionName; private String description; private boolean isStandalone; private boolean isEnabled; private String applicationName; private int applicationIcon; private int applicationLogo; private int applicationTheme; /** * 定义在插件Manifest中的meta-data标签 */ private transient Bundle metaData; private HashMap<String, PluginProviderInfo> providerInfos = new HashMap<String, PluginProviderInfo>(); /** * key: fragment id, * value: fragment class */ private HashMap<String, String> fragments = new HashMap<String, String>(); /** * key: localservice id, * value: localservice class */ private HashMap<String, String> functions = new HashMap<String, String>(); /** * key: activity class name * value: intentfilter list */ private HashMap<String, ArrayList<PluginIntentFilter>> activitys = new HashMap<String, ArrayList<PluginIntentFilter>>(); /** * key: activity class name * value: activity info in Manifest */ private HashMap<String, PluginActivityInfo> activityInfos = new HashMap<String, PluginActivityInfo>(); /** * key: service class name * value: intentfilter list */ private HashMap<String, ArrayList<PluginIntentFilter>> services = new HashMap<String, ArrayList<PluginIntentFilter>>(); private HashMap<String, String> serviceInfos = new HashMap<String, String>(); /** * key: receiver class name * value: intentfilter list */ private HashMap<String, ArrayList<PluginIntentFilter>> receivers = new HashMap<String, ArrayList<PluginIntentFilter>>(); private String installedPath; private String[] dependencies; private ArrayList<String> muliDexList; //=============getter and setter====================== public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public String getPlatformBuildVersionCode() { return platformBuildVersionCode; } public void setPlatformBuildVersionCode(String platformBuildVersionCode) { this.platformBuildVersionCode = platformBuildVersionCode; } public String getPlatformBuildVersionName() { return platformBuildVersionName; } public void setPlatformBuildVersionName(String platformBuildVersionName) { this.platformBuildVersionName = platformBuildVersionName; } public String getMinSdkVersion() { return minSdkVersion; } public void setMinSdkVersion(String minSdkVersion) { this.minSdkVersion = minSdkVersion; } public String getTargetSdkVersion() { return targetSdkVersion; } public void setTargetSdkVersion(String targetSdkVersion) { this.targetSdkVersion = targetSdkVersion; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public void setRequiredHostVersionName(String requiredHostVersionName) { this.requiredHostVersionName = requiredHostVersionName; } public String getRequiredHostVersionName() { return requiredHostVersionName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getApplicationIcon() { return applicationIcon; } public void setApplicationIcon(int icon) { this.applicationIcon = icon; } public int getApplicationLogo() { return applicationLogo; } public void setApplicationLogo(int logo) { this.applicationLogo = logo; } public int getApplicationTheme() { return applicationTheme; } public void setApplicationTheme(int theme) { this.applicationTheme = theme; } public Bundle getMetaData() { if (metaData == null) { if (installedPath != null) { metaData = ResourceUtil.getApplicationMetaData(installedPath); if (metaData == null) { metaData = new Bundle(); } } } return metaData; } public HashMap<String, String> getFragments() { return fragments; } public void setfragments(HashMap<String, String> fragments) { this.fragments = fragments; } public HashMap<String, String> getFunctions() { return functions; } public void setFunctions(HashMap<String, String> functions) { this.functions = functions; } public HashMap<String, ArrayList<PluginIntentFilter>> getReceivers() { return receivers; } public void setReceivers(HashMap<String, ArrayList<PluginIntentFilter>> receivers) { this.receivers = receivers; } public HashMap<String, ArrayList<PluginIntentFilter>> getActivitys() { return activitys; } public void setActivitys(HashMap<String, ArrayList<PluginIntentFilter>> activitys) { this.activitys = activitys; } public HashMap<String, PluginActivityInfo> getActivityInfos() { return activityInfos; } public void setActivityInfos(HashMap<String, PluginActivityInfo> activityInfos) { this.activityInfos = activityInfos; } public HashMap<String, String> getServiceInfos() { return serviceInfos; } public void setServiceInfos(HashMap<String, String> serviceInfos) { this.serviceInfos = serviceInfos; } public HashMap<String, ArrayList<PluginIntentFilter>> getServices() { return services; } public void setServices(HashMap<String, ArrayList<PluginIntentFilter>> services) { this.services = services; } public String getInstalledPath() { return installedPath; } public void setInstalledPath(String installedPath) { this.installedPath = installedPath; } public String[] getDependencies() { return dependencies; } public void setDependencies(String[] dependencies) { this.dependencies = dependencies; } public List<String> getMuliDexList() { return muliDexList; } public void setMuliDexList(ArrayList<String> muliDexList) { this.muliDexList = muliDexList; } public String getApplicationName() { return applicationName; } public void setApplicationName(String applicationName) { this.applicationName = applicationName; } public boolean isEnabled() { return isEnabled; } public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } public boolean isStandalone() { return isStandalone; } public void setStandalone(boolean isStandalone) { this.isStandalone = isStandalone; } public HashMap<String, PluginProviderInfo> getProviderInfos() { return providerInfos; } public void setProviderInfos(HashMap<String, PluginProviderInfo> providerInfos) { this.providerInfos = providerInfos; } /** * 需要根据id查询的只有fragment * @param clazzId * @return */ public String getPluginClassNameById(String clazzId) { String clazzName = getFragments().get(clazzId); if (clazzName == null) { LogUtil.w("PluginDescriptor", "clazzName not found for classId ", clazzId); } else { LogUtil.v("PluginDescriptor", "clazzName found ", clazzName); } return clazzName; } /** * 需要根据Id查询的只有fragment * @param clazzId * @return */ public boolean containsFragment(String clazzId) { if (getFragments().containsKey(clazzId) && isEnabled()) { return true; } return false; } /** * 根据className查询 * @param clazzName * @return */ public boolean containsName(String clazzName) { if (getFragments().containsValue(clazzName) && isEnabled()) { return true; } else if (getActivitys().containsKey(clazzName) && isEnabled()) { return true; } else if (getReceivers().containsKey(clazzName) && isEnabled()) { return true; } else if (getServices().containsKey(clazzName) && isEnabled()) { return true; } else if (getProviderInfos().containsKey(clazzName) && isEnabled()) { return true; } else if (getApplicationName().equals(clazzName) && !clazzName.equals(Application.class.getName()) && isEnabled()) { return true; } return false; } /** * 获取class的类型: activity * @return */ public int getType(String clazzName) { if (getFragments().containsValue(clazzName) && isEnabled()) { return FRAGMENT; } else if (getActivitys().containsKey(clazzName) && isEnabled()) { return ACTIVITY; } else if (getReceivers().containsKey(clazzName) && isEnabled()) { return BROADCAST; } else if (getServices().containsKey(clazzName) && isEnabled()) { return SERVICE; } else if (getProviderInfos().containsKey(clazzName) && isEnabled()) { return PROVIDER; } return UNKOWN; } public ArrayList<String> matchPlugin(Intent intent, int type) { PluginDescriptor plugin = this; ArrayList<String> result = null; String clazzName = null; // 如果是通过组件进行匹配的, 这里忽略了packageName if (intent.getComponent() != null) { if (plugin.containsName(intent.getComponent().getClassName())) { clazzName = intent.getComponent().getClassName(); result = new ArrayList<String>(1); result.add(clazzName); LogUtil.e("暂时不考虑不同的插件中配置了相同类全名的组件的问题, 先到先得"); return result; } } else { // 如果是通过IntentFilter进行匹配的 ArrayList<String> list = null; if (type == PluginDescriptor.ACTIVITY) { list = findClassNameByIntent(intent, plugin.getActivitys()); } else if (type == PluginDescriptor.SERVICE) { list = findClassNameByIntent(intent, plugin.getServices()); } else if (type == PluginDescriptor.BROADCAST) { list = findClassNameByIntent(intent, plugin.getReceivers()); } return list; } return null; } private static ArrayList<String> findClassNameByIntent(Intent intent, HashMap<String, ArrayList<PluginIntentFilter>> intentFilter) { if (intentFilter != null) { ArrayList<String> targetClassNameList = null; Iterator<Map.Entry<String, ArrayList<PluginIntentFilter>>> entry = intentFilter.entrySet().iterator(); while (entry.hasNext()) { Map.Entry<String, ArrayList<PluginIntentFilter>> item = entry.next(); Iterator<PluginIntentFilter> values = item.getValue().iterator(); while (values.hasNext()) { PluginIntentFilter filter = values.next(); int result = filter.match(intent.getAction(), intent.getType(), intent.getScheme(), intent.getData(), intent.getCategories()); if (result != PluginIntentFilter.NO_MATCH_ACTION && result != PluginIntentFilter.NO_MATCH_CATEGORY && result != PluginIntentFilter.NO_MATCH_DATA && result != PluginIntentFilter.NO_MATCH_TYPE) { if (targetClassNameList == null) { targetClassNameList = new ArrayList<String>(); } targetClassNameList.add(item.getKey()); } } } return targetClassNameList; } return null; } }