/* ** DroidPlugin Project ** ** Copyright(c) 2015 Andy Zhang <[email protected]> ** ** This file is part of DroidPlugin. ** ** DroidPlugin is free software: you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation, either ** version 3 of the License, or (at your option) any later version. ** ** DroidPlugin is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with DroidPlugin. If not, see <http://www.gnu.org/licenses/lgpl.txt> ** **/ package com.morgoo.droidplugin.pm.parser; import android.annotation.TargetApi; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import com.morgoo.droidplugin.reflect.FieldUtils; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; /** * 负责Intent匹配。 * Created by Andy Zhang([email protected]) on 2015/2/15. */ public class IntentMatcher { private static final String TAG = IntentMatcher.class.getSimpleName(); private static final Comparator<ResolveInfo> mResolvePrioritySorter = new Comparator<ResolveInfo>() { public int compare(ResolveInfo r1, ResolveInfo r2) { int v1 = r1.priority; int v2 = r2.priority; //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); if (v1 != v2) { return (v1 > v2) ? -1 : 1; } v1 = r1.preferredOrder; v2 = r2.preferredOrder; if (v1 != v2) { return (v1 > v2) ? -1 : 1; } if (r1.isDefault != r2.isDefault) { return r1.isDefault ? -1 : 1; } v1 = r1.match; v2 = r2.match; //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); if (v1 != v2) { return (v1 > v2) ? -1 : 1; } // if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) { // if (r1.system != r2.system) { // return r1.system ? -1 : 1; // } // } return 0; } }; public static final List<ResolveInfo> resolveReceiverIntent(Context context, Map<String, PluginPackageParser> pluginPackages, Intent intent, String resolvedType, int flags) throws Exception { if (intent == null || context == null) { return null; } List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); ComponentName comp = intent.getComponent(); if (comp == null) { if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } } if (comp != null && comp.getPackageName() != null) { PluginPackageParser parser = pluginPackages.get(comp.getPackageName()); if (parser != null) { queryIntentReceiverForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } } else { //intent指定的包名不在我们的插件列表中。 } Collections.sort(list, mResolvePrioritySorter); return list; } final String pkgName = intent.getPackage(); if (pkgName != null) { PluginPackageParser parser = pluginPackages.get(pkgName); if (parser != null) { queryIntentReceiverForPackage(context, parser, intent, flags, list); } else { //intent指定的包名不在我们的插件列表中。 } } else { for (PluginPackageParser parser : pluginPackages.values()) { queryIntentReceiverForPackage(context, parser, intent, flags, list); } } Collections.sort(list, mResolvePrioritySorter); return list; } public static final List<ResolveInfo> resolveServiceIntent(Context context, Map<String, PluginPackageParser> pluginPackages, Intent intent, String resolvedType, int flags) throws Exception { if (intent == null || context == null) { return null; } List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); ComponentName comp = intent.getComponent(); if (comp == null) { if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } } if (comp != null && comp.getPackageName() != null) { PluginPackageParser parser = pluginPackages.get(comp.getPackageName()); if (parser != null) { queryIntentServiceForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } } else { //intent指定的包名不在我们的插件列表中。 } Collections.sort(list, mResolvePrioritySorter); return list; } final String pkgName = intent.getPackage(); if (pkgName != null) { PluginPackageParser parser = pluginPackages.get(pkgName); if (parser != null) { queryIntentServiceForPackage(context, parser, intent, flags, list); } else { //intent指定的包名不在我们的插件列表中。 } } else { for (PluginPackageParser parser : pluginPackages.values()) { queryIntentServiceForPackage(context, parser, intent, flags, list); } } Collections.sort(list, mResolvePrioritySorter); return list; } public static final List<ResolveInfo> resolveProviderIntent(Context context, Map<String, PluginPackageParser> pluginPackages, Intent intent, String resolvedType, int flags) throws Exception { if (intent == null || context == null) { return null; } List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); ComponentName comp = intent.getComponent(); if (comp == null) { if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } } if (comp != null && comp.getPackageName() != null) { PluginPackageParser parser = pluginPackages.get(comp.getPackageName()); if (parser != null) { queryIntentProviderForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } } else { //intent指定的包名不在我们的插件列表中。 } Collections.sort(list, mResolvePrioritySorter); return list; } final String pkgName = intent.getPackage(); if (pkgName != null) { PluginPackageParser parser = pluginPackages.get(pkgName); if (parser != null) { queryIntentProviderForPackage(context, parser, intent, flags, list); } else { //intent指定的包名不在我们的插件列表中。 } } else { for (PluginPackageParser parser : pluginPackages.values()) { queryIntentProviderForPackage(context, parser, intent, flags, list); } } Collections.sort(list, mResolvePrioritySorter); return list; } public static final List<ResolveInfo> resolveActivityIntent(Context context, Map<String, PluginPackageParser> pluginPackages, Intent intent, String resolvedType, int flags) throws Exception { if (intent == null || context == null) { return null; } List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); ComponentName comp = intent.getComponent(); if (comp == null) { if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } } if (comp != null && comp.getPackageName() != null) { PluginPackageParser parser = pluginPackages.get(comp.getPackageName()); if (parser != null) { queryIntentActivityForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } } else { //intent指定的包名不在我们的插件列表中。 } Collections.sort(list, mResolvePrioritySorter); return list; } final String pkgName = intent.getPackage(); if (pkgName != null) { PluginPackageParser parser = pluginPackages.get(pkgName); if (parser != null) { queryIntentActivityForPackage(context, parser, intent, flags, list); } else { //intent指定的包名不在我们的插件列表中。 } } else { for (PluginPackageParser parser : pluginPackages.values()) { queryIntentActivityForPackage(context, parser, intent, flags, list); } } Collections.sort(list, mResolvePrioritySorter); return list; } public static final List<ResolveInfo> resolveIntent(Context context, Map<String, PluginPackageParser> pluginPackages, Intent intent, String resolvedType, int flags) throws Exception { if (intent == null || context == null) { return null; } List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); ComponentName comp = intent.getComponent(); if (comp == null) { if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } } if (comp != null && comp.getPackageName() != null) { PluginPackageParser parser = pluginPackages.get(comp.getPackageName()); if (parser != null) { queryIntentActivityForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } queryIntentServiceForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } queryIntentProviderForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } queryIntentReceiverForPackage(context, parser, intent, flags, list); if (list.size() > 0) { Collections.sort(list, mResolvePrioritySorter); return list; } } else { //intent指定的包名不在我们的插件列表中。 } Collections.sort(list, mResolvePrioritySorter); return list; } final String pkgName = intent.getPackage(); if (pkgName != null) { PluginPackageParser parser = pluginPackages.get(pkgName); if (parser != null) { queryIntentActivityForPackage(context, parser, intent, flags, list); queryIntentServiceForPackage(context, parser, intent, flags, list); queryIntentProviderForPackage(context, parser, intent, flags, list); queryIntentReceiverForPackage(context, parser, intent, flags, list); } else { //intent指定的包名不在我们的插件列表中。 } } else { for (PluginPackageParser parser : pluginPackages.values()) { queryIntentActivityForPackage(context, parser, intent, flags, list); queryIntentServiceForPackage(context, parser, intent, flags, list); queryIntentProviderForPackage(context, parser, intent, flags, list); queryIntentReceiverForPackage(context, parser, intent, flags, list); } } Collections.sort(list, mResolvePrioritySorter); return list; } private static void queryIntentReceiverForPackage(Context context, PluginPackageParser packageParser, Intent intent, int flags, List<ResolveInfo> outList) throws Exception { List<ActivityInfo> receivers = packageParser.getReceivers(); if (receivers != null && receivers.size() >= 0) { for (ActivityInfo receiver : receivers) { List<IntentFilter> intentFilters = packageParser.getReceiverIntentFilter(receiver); if (intentFilters != null && intentFilters.size() > 0) { for (IntentFilter intentFilter : intentFilters) { int match = intentFilter.match(context.getContentResolver(), intent, true, ""); if (match >= 0) { ActivityInfo flagInfo = packageParser.getReceiverInfo(new ComponentName(receiver.packageName, receiver.name), flags); if ((flags & PackageManager.MATCH_DEFAULT_ONLY) != 0) { if (intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) { ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = true; outList.add(resolveInfo); } else { //只是匹配默认。这里也算匹配不上。 } } else { ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = false; outList.add(resolveInfo); } } } if (outList.size() <= 0) { //没有在插件包中找到IntentFilter匹配的ACTIVITY } } else { //该插件包中没有具有IntentFilter的ACTIVITY } } } else { //该插件apk包中没有ACTIVITY } } private static void queryIntentProviderForPackage(Context context, PluginPackageParser packageParser, Intent intent, int flags, List<ResolveInfo> outList) throws Exception { List<ProviderInfo> providerInfos = packageParser.getProviders(); if (providerInfos != null && providerInfos.size() >= 0) { for (ProviderInfo providerInfo : providerInfos) { ComponentName className = new ComponentName(providerInfo.packageName, providerInfo.name); List<IntentFilter> intentFilters = packageParser.getProviderIntentFilter(className); if (intentFilters != null && intentFilters.size() > 0) { for (IntentFilter intentFilter : intentFilters) { int match = intentFilter.match(context.getContentResolver(), intent, true, ""); if (match >= 0) { ProviderInfo flagInfo = packageParser.getProviderInfo(new ComponentName(providerInfo.packageName, providerInfo.name), flags); if ((flags & PackageManager.MATCH_DEFAULT_ONLY) != 0) { if (intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) { ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = true; outList.add(resolveInfo); } else { //只是匹配默认。这里也算匹配不上。 } } else { ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = false; outList.add(resolveInfo); } } } if (outList.size() <= 0) { //没有在插件包中找到IntentFilter匹配的Service } } else { //该插件包中没有具有IntentFilter的Service } } } else { //该插件apk包中没有Service } } private static void queryIntentServiceForPackage(Context context, PluginPackageParser packageParser, Intent intent, int flags, List<ResolveInfo> outList) throws Exception { List<ServiceInfo> serviceInfos = packageParser.getServices(); if (serviceInfos != null && serviceInfos.size() >= 0) { for (ServiceInfo serviceInfo : serviceInfos) { ComponentName className = new ComponentName(serviceInfo.packageName, serviceInfo.name); List<IntentFilter> intentFilters = packageParser.getServiceIntentFilter(className); if (intentFilters != null && intentFilters.size() > 0) { for (IntentFilter intentFilter : intentFilters) { int match = intentFilter.match(context.getContentResolver(), intent, true, ""); if (match >= 0) { ServiceInfo flagServiceInfo = packageParser.getServiceInfo(new ComponentName(serviceInfo.packageName, serviceInfo.name), flags); if ((flags & PackageManager.MATCH_DEFAULT_ONLY) != 0) { if (intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) { ResolveInfo resolveInfo = newResolveInfo(flagServiceInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = true; outList.add(resolveInfo); } else { //只是匹配默认。这里也算匹配不上。 } } else { ResolveInfo resolveInfo = newResolveInfo(flagServiceInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = false; outList.add(resolveInfo); } } } if (outList.size() <= 0) { //没有在插件包中找到IntentFilter匹配的Service } } else { //该插件包中没有具有IntentFilter的Service } } } else { //该插件apk包中没有Service } } private static void queryIntentActivityForPackage(Context context, PluginPackageParser packageParser, Intent intent, int flags, List<ResolveInfo> outList) throws Exception { List<ActivityInfo> activityInfos = packageParser.getActivities(); if (activityInfos != null && activityInfos.size() >= 0) { for (ActivityInfo activityInfo : activityInfos) { ComponentName className = new ComponentName(activityInfo.packageName, activityInfo.name); List<IntentFilter> intentFilters = packageParser.getActivityIntentFilter(className); if (intentFilters != null && intentFilters.size() > 0) { for (IntentFilter intentFilter : intentFilters) { int match = intentFilter.match(context.getContentResolver(), intent, true, ""); if (match >= 0) { ActivityInfo flagInfo = packageParser.getActivityInfo(new ComponentName(activityInfo.packageName, activityInfo.name), flags); if ((flags & PackageManager.MATCH_DEFAULT_ONLY) != 0) { if (intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) { ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = true; outList.add(resolveInfo); } else { //只是匹配默认。这里也算匹配不上。 } } else { ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter); resolveInfo.match = match; resolveInfo.isDefault = false; outList.add(resolveInfo); } } } if (outList.size() <= 0) { //没有在插件包中找到IntentFilter匹配的ACTIVITY } } else { //该插件包中没有具有IntentFilter的ACTIVITY } } } else { //该插件apk包中没有ACTIVITY } } @TargetApi(VERSION_CODES.KITKAT) private static ResolveInfo newResolveInfo(ProviderInfo providerInfo, IntentFilter intentFilter) { ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.providerInfo = providerInfo; resolveInfo.filter = intentFilter; resolveInfo.resolvePackageName = providerInfo.packageName; resolveInfo.labelRes = providerInfo.labelRes; resolveInfo.icon = providerInfo.icon; resolveInfo.specificIndex = 1; // 默认就是false,不用再设置了。 // resolveInfo.system = false; resolveInfo.priority = intentFilter.getPriority(); resolveInfo.preferredOrder = 0; return resolveInfo; } private static ResolveInfo newResolveInfo(ServiceInfo serviceInfo, IntentFilter intentFilter) { ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.serviceInfo = serviceInfo; resolveInfo.filter = intentFilter; resolveInfo.resolvePackageName = serviceInfo.packageName; resolveInfo.labelRes = serviceInfo.labelRes; resolveInfo.icon = serviceInfo.icon; resolveInfo.specificIndex = 1; // if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { // 默认就是false,不用再设置了。 // resolveInfo.system = false; // } resolveInfo.priority = intentFilter.getPriority(); resolveInfo.preferredOrder = 0; return resolveInfo; } private static ResolveInfo newResolveInfo(ActivityInfo activityInfo, IntentFilter intentFilter) { ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.activityInfo = activityInfo; resolveInfo.filter = intentFilter; resolveInfo.resolvePackageName = activityInfo.packageName; resolveInfo.labelRes = activityInfo.labelRes; resolveInfo.icon = activityInfo.icon; resolveInfo.specificIndex = 1; // if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) { //// 默认就是false,不用再设置了。 // resolveInfo.system = false; // } resolveInfo.priority = intentFilter.getPriority(); resolveInfo.preferredOrder = 0; return resolveInfo; } public static ResolveInfo findBest(List<ResolveInfo> infos) { return infos.get(0); } }