源码链接

https://android.googlesource.com/platform/frameworks/base/+/633dc9b/services/java/com/android/server/firewall/IntentFirewall.java
源码如下:

package com.android.server.firewall;import android.content.Intent;import android.content.IntentFilter;import android.content.pm.ActivityInfo;import android.content.pm.ApplicationInfo;import android.content.pm.PackageManager;import android.os.Environment;import android.os.ServiceManager;import android.util.Slog;import android.util.Xml;import com.android.internal.util.XmlUtils;import com.android.server.IntentResolver;import com.android.server.pm.PackageManagerService;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlPullParserException;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;public class IntentFirewall {private static final String TAG = "IntentFirewall";// e.g. /data/system/ifw/ifw.xml or /data/secure/system/ifw/ifw.xmlprivate static final File RULES_FILE =new File(Environment.getSystemSecureDirectory(), "ifw/ifw.xml");private static final String TAG_RULES = "rules";private static final String TAG_ACTIVITY = "activity";private static final String TAG_SERVICE = "service";private static final String TAG_BROADCAST = "broadcast";private static final HashMap<String, FilterFactory> factoryMap;private final AMSInterface mAms;private final IntentResolver<FirewallIntentFilter, Rule> mActivityResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mServiceResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mBroadcastResolver =new FirewallIntentResolver();static {FilterFactory[] factories = new FilterFactory[] {AndFilter.FACTORY,OrFilter.FACTORY,NotFilter.FACTORY,StringFilter.ACTION,StringFilter.COMPONENT,StringFilter.COMPONENT_NAME,StringFilter.COMPONENT_PACKAGE,StringFilter.DATA,StringFilter.HOST,StringFilter.MIME_TYPE,StringFilter.PATH,StringFilter.SENDER_PACKAGE,StringFilter.SSP,CategoryFilter.FACTORY,SenderFilter.FACTORY,SenderPermissionFilter.FACTORY,PortFilter.FACTORY};// load factor ~= .75factoryMap = new HashMap<String, FilterFactory>(factories.length * 4 / 3);for (int i=0; i<factories.length; i++) {FilterFactory factory = factories[i];factoryMap.put(factory.getTagName(), factory);}}public IntentFirewall(AMSInterface ams) {mAms = ams;readRules(getRulesFile());}public boolean checkStartActivity(Intent intent, ApplicationInfo callerApp,String callerPackage, int callerUid, int callerPid, String resolvedType,ActivityInfo resolvedActivity) {List<Rule> matchingRules = mActivityResolver.queryIntent(intent, resolvedType, false, 0);boolean log = false;boolean block = false;for (int i=0; i< matchingRules.size(); i++) {Rule rule = matchingRules.get(i);if (rule.matches(this, intent, callerApp, callerPackage, callerUid, callerPid,resolvedType, resolvedActivity.applicationInfo)) {block |= rule.getBlock();log |= rule.getLog();// if we've already determined that we should both block and log, there's no need// to continue trying rulesif (block && log) {break;}}}if (log) {// TODO: log info about intent to event log}return !block;}public static File getRulesFile() {return RULES_FILE;}private void readRules(File rulesFile) {FileInputStream fis;try {fis = new FileInputStream(rulesFile);} catch (FileNotFoundException ex) {// Nope, no rules. Nothing else to do!return;}try {XmlPullParser parser = Xml.newPullParser();parser.setInput(fis, null);XmlUtils.beginDocument(parser, TAG_RULES);int outerDepth = parser.getDepth();while (XmlUtils.nextElementWithin(parser, outerDepth)) {IntentResolver<FirewallIntentFilter, Rule> resolver = null;String tagName = parser.getName();if (tagName.equals(TAG_ACTIVITY)) {resolver = mActivityResolver;} else if (tagName.equals(TAG_SERVICE)) {resolver = mServiceResolver;} else if (tagName.equals(TAG_BROADCAST)) {resolver = mBroadcastResolver;}if (resolver != null) {Rule rule = new Rule();try {rule.readFromXml(parser);} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;}for (int i=0; i<rule.getIntentFilterCount(); i++) {resolver.addFilter(rule.getIntentFilter(i));}}}} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} finally {try {fis.close();} catch (IOException ex) {Slog.e(TAG, "Error while closing " + rulesFile, ex);}}}static Filter parseFilter(XmlPullParser parser) throws IOException, XmlPullParserException {String elementName = parser.getName();FilterFactory factory = factoryMap.get(elementName);if (factory == null) {throw new XmlPullParserException("Unknown element in filter list: " + elementName);}return factory.newFilter(parser);}private static class Rule extends AndFilter {private static final String TAG_INTENT_FILTER = "intent-filter";private static final String ATTR_BLOCK = "block";private static final String ATTR_LOG = "log";private final ArrayList<FirewallIntentFilter> mIntentFilters =new ArrayList<FirewallIntentFilter>(1);private boolean block;private boolean log;@Overridepublic Rule readFromXml(XmlPullParser parser) throws IOException, XmlPullParserException {block = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_BLOCK));log = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_LOG));super.readFromXml(parser);return this;}@Overrideprotected void readChild(XmlPullParser parser) throws IOException, XmlPullParserException {if (parser.getName().equals(TAG_INTENT_FILTER)) {FirewallIntentFilter intentFilter = new FirewallIntentFilter(this);intentFilter.readFromXml(parser);mIntentFilters.add(intentFilter);} else {super.readChild(parser);}}public int getIntentFilterCount() {return mIntentFilters.size();}public FirewallIntentFilter getIntentFilter(int index) {return mIntentFilters.get(index);}public boolean getBlock() {return block;}public boolean getLog() {return log;}}private static class FirewallIntentFilter extends IntentFilter {private final Rule rule;public FirewallIntentFilter(Rule rule) {this.rule = rule;}}private static class FirewallIntentResolverextends IntentResolver<FirewallIntentFilter, Rule> {@Overrideprotected boolean allowFilterResult(FirewallIntentFilter filter, List<Rule> dest) {return !dest.contains(filter.rule);}@Overrideprotected boolean isPackageForFilter(String packageName, FirewallIntentFilter filter) {return true;}@Overrideprotected FirewallIntentFilter[] newArray(int size) {return new FirewallIntentFilter[size];}@Overrideprotected Rule newResult(FirewallIntentFilter filter, int match, int userId) {return filter.rule;}@Overrideprotected void sortResults(List<Rule> results) {// there's no need to sort the resultsreturn;}}/** * This interface contains the methods we need from ActivityManagerService. This allows AMS to * export these methods to us without making them public, and also makes it easier to test this * component. */public interface AMSInterface {int checkComponentPermission(String permission, int pid, int uid,int owningUid, boolean exported);}/** * Checks if the caller has access to a component * * @param permission If present, the caller must have this permission * @param pid The pid of the caller * @param uid The uid of the caller * @param owningUid The uid of the application that owns the component * @param exported Whether the component is exported * @return True if the caller can access the described component */boolean checkComponentPermission(String permission, int pid, int uid, int owningUid,boolean exported) {return mAms.checkComponentPermission(permission, pid, uid, owningUid, exported) ==PackageManager.PERMISSION_GRANTED;}boolean signaturesMatch(int uid1, int uid2) {PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;}}

组件IntentFirewall的作用

IntentFirewall是Android框架中的一个组件,它可以根据XML文件中定义的规则来控制Intent的发送和接收。Intent是Android中用于组件间通信和启动的一种消息对象,它可以携带动作、数据、类别等信息。IntentFirewall可以根据Intent的属性和调用者的信息,决定是否允许或拒绝Intent的传递,从而增强系统的安全性和灵活性。
主要功能主要有以下几条:
(1)过滤任何类型的Intent,包括Activity,Service,Broadcast和ContentProvider。
(2)动态更新过滤规则,无需重启系统。
(3)支持多种过滤条件,包括动作、数据、类别、组件、权限、用户、进程等。
(4)支持多种过滤动作,包括阻止、记录、修改和转发Intent。

代码逻辑如下:

根据提供的Android IntentFirewall源代码,概括了其主要逻辑如下:

  1. 定义相关常量和变量,包括规则文件路径、解析器等

  2. 构造函数中初始化解析器,并读取规则文件

  3. checkStartActivity()方法检查启动Activity的Intent是否被阻止

  4. readRules()方法读取并解析规则文件

  5. parseFilter()解析过滤器标签

  6. Rule类封装单条规则信息

  7. FirewallIntentFilter类扩展IntentFilter表示规则Intent过滤器

  8. FirewallIntentResolver类自定义的解析器实现

  9. 定义AMSInterface接口与AMS服务交互

  10. checkComponentPermission()根据权限检查组件访问

  11. signaturesMatch()检查两个UID签名是否匹配

综上,该类主要实现了一个基于规则的Android Intent防火墙,可以通过配置来过滤恶意的组件启动请求,保护应用安全。

详细解读具体代码逻辑

private static final String TAG = "IntentFirewall";

这行代码定义了一个私有的静态的最终的字符串常量,名为TAG,值为”IntentFirewall”,用于作为日志的标签。

private static final File RULES_FILE =new File(Environment.getSystemSecureDirectory(), "ifw/ifw.xml");

这行代码定义了一个私有的静态的最终的文件常量,名为RULES_FILE,值为一个File对象,用于表示规则文件的位置,它调用了Environment类的getSystemSecureDirectory方法,获取系统的安全目录,然后在该目录下创建一个名为”ifw/ifw.xml”的文件。

private static final String TAG_RULES = "rules";private static final String TAG_ACTIVITY = "activity";private static final String TAG_SERVICE = "service";private static final String TAG_BROADCAST = "broadcast";

这块代码定义了四个私有的静态的最终的字符串常量,分别名为TAG_RULES,TAG_ACTIVITY,TAG_SERVICE,TAG_BROADCAST,值分别为为”rules”,“activity”,“service”,“broadcast”,用于分别表示XML文件中的根元素的标签、活动类型的过滤规则的标签、服务类型的过滤规则的标签、广播类型的过滤规则的标签。这段代码是IntentFirewall类的一部分,用于定义一些常量和成员变量,它们分别用于表示日志的标签,规则文件的位置,XML文件中的元素的标签,过滤器工厂的映射,ActivityManagerService的接口,以及不同类型的过滤规则的解析器。

private static final HashMap<String, FilterFactory> factoryMap;private final AMSInterface mAms;private final IntentResolver<FirewallIntentFilter, Rule> mActivityResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mServiceResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mBroadcastResolver =new FirewallIntentResolver();
  • private static final HashMap factoryMap; 这行代码定义了一个私有的静态的最终的哈希映射常量,名为factoryMap,类型为HashMap,用于存储过滤器工厂的对象,键为过滤器的名称,值为过滤器工厂的实例。
  • private final AMSInterface mAms; 这行代码定义了一个私有的最终的接口变量,名为mAms,类型为AMSInterface,用于表示ActivityManagerService的接口,用于管理和调度系统中的四大组件。
  • private final IntentResolver mActivityResolver = new FirewallIntentResolver(); 这行代码定义了一个私有的最终的IntentResolver变量,名为mActivityResolver,类型为IntentResolver,值为一个FirewallIntentResolver对象,用于存储和查询活动类型的过滤规则。
  • private final IntentResolver mServiceResolver = new FirewallIntentResolver(); 这行代码定义了一个私有的最终的IntentResolver变量,名为mServiceResolver,类型为IntentResolver,值为一个FirewallIntentResolver对象,用于存储和查询服务类型的过滤规则。
  • private final IntentResolver mBroadcastResolver = new FirewallIntentResolver(); 这行代码定义了一个私有的最终的IntentResolver变量,名为mBroadcastResolver,类型为IntentResolver,值为一个FirewallIntentResolver对象,用于存储和查询广播类型的过滤规则。

这代码是IntentFirewall类的一部分,用于定义一些成员变量,它们分别用于表示过滤器工厂的映射,ActivityManagerService的接口,以及不同类型的过滤规则的解析器。

static {FilterFactory[] factories = new FilterFactory[] {AndFilter.FACTORY,OrFilter.FACTORY,NotFilter.FACTORY,StringFilter.ACTION,StringFilter.COMPONENT,StringFilter.COMPONENT_NAME,StringFilter.COMPONENT_PACKAGE,StringFilter.DATA,StringFilter.HOST,StringFilter.MIME_TYPE,StringFilter.PATH,StringFilter.SENDER_PACKAGE,StringFilter.SSP,CategoryFilter.FACTORY,SenderFilter.FACTORY,SenderPermissionFilter.FACTORY,PortFilter.FACTORY};
  • static { 这行代码表示开始一个静态代码块,用于在类加载时执行一些初始化操作,只执行一次。
  • FilterFactory[] factories = new FilterFactory[] { 这行代码定义了一个FilterFactory类型的数组,名为factories,用于存储所有可用的过滤器工厂的对象,过滤器工厂是用于创建和管理过滤器的类,过滤器是用于定义过滤条件的接口。
  • AndFilter.FACTORY, 这行代码表示将AndFilter类的FACTORY常量添加到factories数组中,这是一个AndFilterFactory类型的对象,用于创建和管理AndFilter类型的过滤器,AndFilter是用于实现逻辑与操作的过滤器,它可以包含多个子过滤器,只有当所有子过滤器都匹配时,才返回true。
  • OrFilter.FACTORY, 这行代码表示将OrFilter类的FACTORY常量添加到factories数组中,这是一个OrFilterFactory类型的对象,用于创建和管理OrFilter类型的过滤器,OrFilter是用于实现逻辑或操作的过滤器,它可以包含多个子过滤器,只要有一个子过滤器匹配,就返回true。
  • NotFilter.FACTORY, 这行代码表示将NotFilter类的FACTORY常量添加到factories数组中,这是一个NotFilterFactory类型的对象,用于创建和管理NotFilter类型的过滤器,NotFilter是用于实现逻辑非操作的过滤器,它可以包含一个子过滤器,返回子过滤器的相反结果。
  • StringFilter.ACTION, 这行代码表示将StringFilter类的ACTION常量添加到factories数组中,这是一个StringFilter类型的对象,用于创建和管理StringFilter类型的过滤器,StringFilter是用于匹配字符串属性的过滤器,它可以指定一个或多个字符串值,以及一个匹配模式,比如完全匹配,前缀匹配,后缀匹配,正则匹配等。ACTION常量表示匹配Intent的动作属性,比如android.intent.action.VIEW等。
  • StringFilter.COMPONENT, 这行代码表示将StringFilter类的COMPONENT常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的组件属性,比如com.example.app.MainActivity等。
  • StringFilter.COMPONENT_NAME, 这行代码表示将StringFilter类的COMPONENT_NAME常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的组件的名称属性,比如MainActivity等。
  • StringFilter.COMPONENT_PACKAGE, 这行代码表示将StringFilter类的COMPONENT_PACKAGE常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的组件的包名属性,比如com.example.app等。
  • StringFilter.DATA, 这行代码表示将StringFilter类的DATA常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据属性,比如http://www.example.com等。
  • StringFilter.HOST, 这行代码表示将StringFilter类的HOST常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的主机属性,比如www.example.com等。
  • StringFilter.MIME_TYPE, 这行代码表示将StringFilter类的MIME_TYPE常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的MIME类型属性,比如image/jpeg等。
  • StringFilter.PATH, 这行代码表示将StringFilter类的PATH常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的路径属性,比如/index.html等。
  • StringFilter.SENDER_PACKAGE, 这行代码表示将StringFilter类的SENDER_PACKAGE常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的发送者的包名属性,比如com.example.sender等。
  • StringFilter.SSP, 这行代码表示将StringFilter类的SSP常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的方案特定部分(Scheme Specific Part)属性,比如//www.example.com/index.html等。
  • CategoryFilter.FACTORY, 这行代码表示将CategoryFilter类的FACTORY常量添加到factories数组中,这是一个CategoryFilterFactory类型的对象,用于创建和管理CategoryFilter类型的过滤器,CategoryFilter是用于匹配Intent的类别属性的过滤器,它可以指定一个或多个类别值,比如android.intent.category.BROWSABLE等。
  • SenderFilter.FACTORY, 这行代码表示将SenderFilter类的FACTORY常量添加到factories数组中,这是一个SenderFilterFactory类型的对象,用于创建和管理SenderFilter类型的过滤器,SenderFilter是用于匹配Intent的发送者的过滤器,它可以指定一个或多个用户ID,进程ID,应用信息等。
  • SenderPermissionFilter.FACTORY, 这行代码表示将SenderPermissionFilter类的FACTORY常量添加到factories数组中,这是一个SenderPermissionFilterFactory类型的对象,用于创建和管理SenderPermissionFilter类型的过滤器,SenderPermissionFilter是用于匹配Intent的发送者的权限的过滤器,它可以指定一个或多个权限名称,以及是否需要强制执行等。
  • PortFilter.FACTORY 这行代码表示将PortFilter类的FACTORY常量添加到factories数组中,这是一个PortFilterFactory类型的对象,用于创建和管理PortFilter类型的过滤器,PortFilter是用于匹配Intent的数据的端口属性的过滤器,它可以指定一个或多个端口范围,比如80-8080等。
  • }; 这行代码表示结束数组的初始化。
factoryMap = new HashMap<String, FilterFactory>(factories.length * 4 / 3);for (int i=0; i<factories.length; i++) {FilterFactory factory = factories[i];factoryMap.put(factory.getTagName(), factory);}
  • factoryMap = new HashMap(factories.length * 4 / 3); 这行代码创建了一个HashMap对象,指定键和值的类型为String和FilterFactory,分别表示过滤器的名称和实例,然后将其赋值给factoryMap常量,用于存储过滤器工厂的映射。这里使用了一个参数的构造方法,指定HashMap的初始容量为factories数组的长度乘以4除以3,这样做的目的是为了减少HashMap的扩容次数,提高性能。
  • for (int i=0; i<factories.length; i++) { 这行代码开始一个for循环,用于遍历factories数组中的每个元素,每个元素都是一个FilterFactory对象,用于创建和管理过滤器。
  • FilterFactory factory = factories[i]; 这行代码定义了一个FilterFactory类型的变量,名为factory,然后将factories数组中的第i个元素赋值给它,表示当前的过滤器工厂对象。
  • factoryMap.put(factory.getTagName(), factory); 这行代码调用factoryMap对象的put方法,将factory对象的getTagName方法返回的字符串作为键,将factory对象本身作为值,添加到factoryMap中,表示将过滤器的名称和实例映射起来。
  • } 这行代码表示结束for循环。
public IntentFirewall(AMSInterface ams) {mAms = ams;readRules(getRulesFile());}

用于获取规则文件的对象,它返回一个文件类型的常量,表示规则文件的位置。它调用了Environment类的getSystemSecureDirectory方法,获取系统的安全目录,然后在该目录下创建一个名为”ifw/ifw.xml”的文件。

private void readRules(File rulesFile) {FileInputStream fis;try {fis = new FileInputStream(rulesFile);} catch (FileNotFoundException ex) {// Nope, no rules. Nothing else to do!return;}try {XmlPullParser parser = Xml.newPullParser();parser.setInput(fis, null);XmlUtils.beginDocument(parser, TAG_RULES);int outerDepth = parser.getDepth();while (XmlUtils.nextElementWithin(parser, outerDepth)) {IntentResolver<FirewallIntentFilter, Rule> resolver = null;String tagName = parser.getName();if (tagName.equals(TAG_ACTIVITY)) {resolver = mActivityResolver;} else if (tagName.equals(TAG_SERVICE)) {resolver = mServiceResolver;} else if (tagName.equals(TAG_BROADCAST)) {resolver = mBroadcastResolver;}if (resolver != null) {Rule rule = new Rule();try {rule.readFromXml(parser);} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;}for (int i=0; i<rule.getIntentFilterCount(); i++) {resolver.addFilter(rule.getIntentFilter(i));}}}} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} finally {try {fis.close();} catch (IOException ex) {Slog.e(TAG, "Error while closing " + rulesFile, ex);}}}
  • 这个方法的参数是一个File类型的对象,表示存储过滤规则的XML文件。
  • 这个方法首先定义了一个FileInputStream类型的变量,用于读取文件的内容,然后使用一个try-catch语句,尝试创建一个FileInputStream对象,如果发生FileNotFoundException异常,就表示没有找到规则文件,就直接返回。
  • 然后使用另一个try-catch-finally语句,尝试解析文件的内容,如果发生XmlPullParserException或IOException异常,就表示读取过滤规则时出错,就打印一条错误信息,最后无论是否发生异常,都尝试关闭文件输入流,如果发生IOException异常,就表示关闭文件时出错,就打印一条错误信息。
  • 在try语句中,创建一个XmlPullParser对象,用于解析XML文件的内容,然后设置输入源为文件输入流,使用默认的编码格式,然后开始解析XML文件,并检查根元素的标签是否为rules。
  • 然后获取XML文件的初始深度,然后使用一个while循环,在当前深度范围内,查找下一个元素的开始标签,如果找到,就继续循环,否则,就跳出循环。
  • 在循环中,根据当前元素的标签名,选择相应的IntentResolver对象,用于存储和查询不同类型的过滤规则,如果找到了匹配的IntentResolver对象,就创建一个Rule对象,用于存储当前元素的过滤规则,然后使用一个try-catch语句,尝试从当前元素的属性和子元素中读取过滤规则的条件和动作,如果发生异常,就打印一条错误信息,然后继续循环。
  • 在try语句中,使用一个for循环,遍历Rule对象的所有IntentFilter对象,每个IntentFilter对象都是一个FirewallIntentFilter类型的实例,用于定义过滤规则的匹配条件,比如动作、类别、数据等,然后将每个IntentFilter对象添加到IntentResolver中,用于后续的过滤和查询。

这段代码是IntentFirewall类的一个私有方法,用于从文件中读取过滤规则,并将其添加到相应的IntentResolver中,它使用了XmlPullParser对象来解析XML文件的内容,然后使用Rule对象和IntentFilter对象来存储和管理过滤规则的条件和动作。

 static Filter parseFilter(XmlPullParser parser) throws IOException, XmlPullParserException {String elementName = parser.getName();FilterFactory factory = factoryMap.get(elementName);if (factory == null) {throw new XmlPullParserException("Unknown element in filter list: " + elementName);}return factory.newFilter(parser);}
  • 这个方法的参数是一个XmlPullParser类型的对象,表示用于解析XML文件的解析器,它抛出了IOException和XmlPullParserException两种异常,表示可能发生的输入输出错误和解析错误。
  • 这个方法的返回值是一个Filter类型的对象,表示根据XML文件中的元素创建的过滤器,过滤器是用于定义过滤条件的接口。
  • 这个方法首先调用parser对象的getName方法,获取当前元素的标签名,然后将其赋值给一个字符串变量,名为elementName。
  • 然后使用factoryMap对象的get方法,根据elementName作为键,从哈希映射中获取对应的值,这个值是一个FilterFactory类型的对象,表示用于创建和管理过滤器的工厂,然后将其赋值给一个FilterFactory类型的变量,名为factory。
  • 如果factory变量为null,表示没有找到匹配的过滤器工厂,就抛出一个XmlPullParserException异常,表示在过滤器列表中存在未知的元素,异常的信息包含了elementName的值。
  • 如果factory变量不为null,表示找到了匹配的过滤器工厂,就调用factory对象的newFilter方法,传入parser对象作为参数,从当前元素的属性和子元素中创建一个新的过滤器对象,然后将其返回。

这段代码是一个静态的方法,用于根据XML文件中的元素创建一个过滤器对象,它使用了一个哈希映射来存储过滤器工厂的映射,然后根据元素的标签名来查找和创建过滤器,如果没有找到匹配的过滤器工厂,就抛出一个异常。

private static class Rule extends AndFilter {private static final String TAG_INTENT_FILTER = "intent-filter";private static final String ATTR_BLOCK = "block";private static final String ATTR_LOG = "log";private final ArrayList<FirewallIntentFilter> mIntentFilters =new ArrayList<FirewallIntentFilter>(1);private boolean block;private boolean log;@Overridepublic Rule readFromXml(XmlPullParser parser) throws IOException, XmlPullParserException {block = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_BLOCK));log = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_LOG));super.readFromXml(parser);return this;}@Overrideprotected void readChild(XmlPullParser parser) throws IOException, XmlPullParserException {if (parser.getName().equals(TAG_INTENT_FILTER)) {FirewallIntentFilter intentFilter = new FirewallIntentFilter(this);intentFilter.readFromXml(parser);mIntentFilters.add(intentFilter);} else {super.readChild(parser);}}public int getIntentFilterCount() {return mIntentFilters.size();}public FirewallIntentFilter getIntentFilter(int index) {return mIntentFilters.get(index);}public boolean getBlock() {return block;}public boolean getLog() {return log;}}
  • 这段代码定义了一个私有的静态的内部类,名为Rule,继承了AndFilter类,用于表示一个过滤规则,包括过滤条件和过滤动作。
  • 这个类定义了两个私有的静态的最终的字符串常量,分别是TAG_INTENT_FILTER和ATTR_BLOCK,值分别是”intent-filter”和”block”,用于表示XML文件中的元素的标签和属性。
  • 这个类定义了另外两个私有的静态的最终的字符串常量,分别是ATTR_LOG和ATTR_BLOCK,值分别是”log”和”block”,用于表示XML文件中的元素的属性。
  • 这个类定义了一个私有的最终的ArrayList变量,名为mIntentFilters,类型为ArrayList,值为一个新的ArrayList对象,用于存储过滤规则的所有IntentFilter对象,IntentFilter对象是用于定义过滤条件的对象,比如动作、类别、数据等。
  • 这个类定义了两个私有的布尔变量,分别是block和log,用于表示过滤动作,block为true表示阻止Intent的传递,log为true表示记录Intent的信息。
  • 这个类重写了AndFilter类的readFromXml方法,用于从XML文件中读取过滤规则的条件和动作,它接收一个XmlPullParser类型的参数,表示用于解析XML文件的解析器,它抛出了IOException和XmlPullParserException两种异常,表示可能发生的输入输出错误和解析错误。
  • 这个方法首先调用parser对象的getAttributeValue方法,传入null和ATTR_BLOCK作为参数,获取当前元素的block属性的值,然后使用Boolean类的parseBoolean方法,将字符串值转换为布尔值,然后赋值给block变量。
  • 然后调用parser对象的getAttributeValue方法,传入null和ATTR_LOG作为参数,获取当前元素的log属性的值,然后使用Boolean类的parseBoolean方法,将字符串值转换为布尔值,然后赋值给log变量。
  • 然后调用父类的readFromXml方法,传入parser对象作为参数,从当前元素的子元素中读取过滤条件,比如AndFilter,OrFilter,NotFilter,StringFilter等,然后将它们添加到过滤条件的列表中。
  • 最后,返回当前的Rule对象,表示读取完成。
  • readChild:重写了AndFilter类的readChild方法,用于从XML文件中读取过滤规则的子元素,它接收一个XmlPullParser类型的参数,表示用于解析XML文件的解析器,它抛出了IOException和XmlPullParserException两种异常,表示可能发生的输入输出错误和解析错误。
    这个方法首先判断当前元素的标签名是否等于TAG_INTENT_FILTER常量,这是一个字符串常量,值为”intent-filter”,用于表示XML文件中的IntentFilter元素的标签,IntentFilter元素是用于定义过滤条件的元素,比如动作、类别、数据等。
    如果当前元素的标签名等于TAG_INTENT_FILTER常量,就表示当前元素是一个IntentFilter元素,就创建一个FirewallIntentFilter类型的对象,名为intentFilter,传入当前的Rule对象作为参数,表示这个IntentFilter属于这个Rule,然后调用intentFilter对象的readFromXml方法,传入parser对象作为参数,从当前元素的属性和子元素中读取IntentFilter的内容,然后将intentFilter对象添加到mIntentFilters变量中,这是一个ArrayList类型的变量,用于存储当前Rule的所有IntentFilter对象。
    如果当前元素的标签名不等于TAG_INTENT_FILTER常量,就表示当前元素是一个其他类型的过滤条件元素,比如AndFilter,OrFilter,NotFilter,StringFilter等,就调用父类的readChild方法,传入parser对象作为参数,从当前元素的属性和子元素中读取过滤条件的内容,然后将它们添加到过滤条件的列表中。总结:用于从XML文件中读取过滤规则的子元素,它根据当前元素的标签名,判断是一个IntentFilter元素还是一个其他类型的过滤条件元素,然后分别处理它们,将它们添加到当前Rule的过滤条件的列表中。

这段代码是一个私有的静态的内部类,是一个表示过滤规则的类,它继承了AndFilter类,定义了过滤条件和过滤动作,可以从XML文件中读取和创建。

private static class FirewallIntentFilter extends IntentFilter {private final Rule rule;public FirewallIntentFilter(Rule rule) {this.rule = rule;}}
  • 这段代码定义了一个私有的静态的内部类,名为FirewallIntentFilter,继承了IntentFilter类,用于表示一个过滤器,它可以匹配Intent的属性,比如动作、类别、数据等。
  • 这个类定义了一个私有的最终的Rule类型的变量,名为rule,用于表示这个过滤器所属的过滤规则,过滤规则是用于定义过滤条件和过滤动作的类,比如阻止或记录Intent的传递。
  • 这个类定义了一个公共的构造方法,接收一个Rule类型的参数,表示要创建的过滤器所属的过滤规则,然后将其赋值给rule变量,表示初始化过滤器的状态。

这段代码是一个私有的静态的内部类,用于表示一个过滤器,它继承了IntentFilter类,定义了一个过滤规则的变量,提供了一个构造方法,用于创建和初始化过滤器的对象。

private static class FirewallIntentResolverextends IntentResolver<FirewallIntentFilter, Rule> {@Overrideprotected boolean allowFilterResult(FirewallIntentFilter filter, List<Rule> dest) {return !dest.contains(filter.rule);}@Overrideprotected boolean isPackageForFilter(String packageName, FirewallIntentFilter filter) {return true;}@Overrideprotected FirewallIntentFilter[] newArray(int size) {return new FirewallIntentFilter[size];}@Overrideprotected Rule newResult(FirewallIntentFilter filter, int match, int userId) {return filter.rule;}@Overrideprotected void sortResults(List<Rule> results) {// there's no need to sort the resultsreturn;}}

这个类重写了IntentResolver类的以下方法:

  • allowFilterResult:用于判断是否允许将过滤器的结果添加到目标列表中,它接收一个FirewallIntentFilter类型的参数,表示要添加的过滤器,和一个List类型的参数,表示目标列表,它返回一个布尔值,表示是否允许添加。这个方法的逻辑是,如果目标列表中已经包含了过滤器所属的规则,就返回false,表示不允许重复添加,否则,就返回true,表示允许添加。
  • isPackageForFilter:用于判断一个包名是否适用于一个过滤器,它接收一个字符串类型的参数,表示要判断的包名,和一个FirewallIntentFilter类型的参数,表示要判断的过滤器,它返回一个布尔值,表示是否适用。这个方法的逻辑是,直接返回true,表示任何包名都适用于任何过滤器,不需要进行过滤。
  • newArray:用于创建一个指定大小的FirewallIntentFilter类型的数组,它接收一个整数类型的参数,表示要创建的数组的大小,它返回一个FirewallIntentFilter类型的数组,表示创建的数组。这个方法的逻辑是,使用new关键字,创建一个FirewallIntentFilter类型的数组,传入size参数作为数组的长度,然后返回这个数组。
  • newResult:用于创建一个新的过滤规则的结果,它接收一个FirewallIntentFilter类型的参数,表示匹配的过滤器,一个整数类型的参数match,表示匹配的结果,和一个整数类型的参数userId,表示用户的ID,它返回一个Rule类型的对象,表示创建的结果。这个方法的逻辑是,直接返回过滤器所属的规则,表示这个规则是匹配的结果。
  • sortResults:用于对过滤规则的结果进行排序,它接收一个List类型的参数,表示要排序的结果列表,它没有返回值。这个方法的逻辑是,直接返回,表示不需要对结果进行排序。

这是IntentFirewall类的一个私有的静态的内部类,用于存储和查询不同类型的过滤规则,它重写了IntentResolver类的一些方法,用于实现自定义的过滤逻辑。

public interface AMSInterface {int checkComponentPermission(String permission, int pid, int uid,int owningUid, boolean exported);}

这个接口定义了一个方法,名为checkComponentPermission,用于检查一个组件的权限,它接收以下参数:

  • permission:一个字符串类型的参数,表示要检查的权限的名称,比如android.permission.INTERNET等。
  • pid:一个整数类型的参数,表示要检查的进程的ID,比如1234等。
  • uid:一个整数类型的参数,表示要检查的用户的ID,比如1000等。
  • owningUid:一个整数类型的参数,表示拥有该组件的用户的ID,比如1001等。
  • exported:一个布尔类型的参数,表示该组件是否是可导出的,即是否可以被其他应用访问,比如true或false等。

这个方法的返回值是一个整数类型的值,表示检查的结果,比如PackageManager.PERMISSION_GRANTED表示允许访问,PackageManager.PERMISSION_DENIED表示拒绝访问等。

这是是一个公共的接口,用于表示ActivityManagerService的接口,它定义了一个方法,用于检查一个组件的权限,它接收一些参数,表示要检查的权限、进程、用户、组件等信息,它返回一个值,表示检查的结果。

boolean checkComponentPermission(String permission, int pid, int uid, int owningUid,boolean exported) {return mAms.checkComponentPermission(permission, pid, uid, owningUid, exported) ==PackageManager.PERMISSION_GRANTED;}
boolean signaturesMatch(int uid1, int uid2) {PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;}

这是ntentFirewall类的两个私有方法,用于检查组件的权限和签名,它们分别是:

  • checkComponentPermission:用于检查一个组件的权限,它接收一个字符串类型的参数,表示要检查的权限的名称,和四个整数类型的参数,分别表示要检查的进程的ID,用户的ID,拥有该组件的用户的ID,以及该组件是否是可导出的,它返回一个布尔值,表示是否允许访问。这个方法的逻辑是,调用mAms对象的checkComponentPermission方法,传入相同的参数,然后判断返回值是否等于PackageManager.PERMISSION_GRANTED常量,这是一个整数常量,表示允许访问的结果,如果相等,就返回true,否则,就返回false。mAms对象是一个AMSInterface类型的变量,表示ActivityManagerService的接口,用于管理和调度系统中的四大组件。
  • signaturesMatch:用于检查两个用户的签名是否匹配,它接收两个整数类型的参数,分别表示要检查的两个用户的ID,它返回一个布尔值,表示是否匹配。这个方法的逻辑是,定义一个PackageManagerService类型的变量,名为pm,然后调用ServiceManager类的getService方法,传入一个字符串常量,表示要获取的服务的名称,这个常量是”package”,表示要获取的是PackageManagerService,这是一个用于管理和安装应用的服务,然后将返回值强制转换为PackageManagerService类型,然后赋值给pm变量。然后调用pm对象的checkUidSignatures方法,传入两个用户的ID作为参数,然后判断返回值是否等于PackageManager.SIGNATURE_MATCH常量,这是一个整数常量,表示签名匹配的结果,如果相等,就返回true,否则,就返回false。

这两个方法用于检查组件的权限和签名的方法,它们分别调用ActivityManagerService和PackageManagerService的接口,然后根据返回值判断是否允许访问或匹配。