今天遇到了一个获取NFC配置的判断条件方法,调用的是PackageManager里面的hasSystemFeature方法,兜兜转转最终才找到是在device.mk添加的配置,具体流程如下:
最初遭遇的方法:getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)
然后在/android/frameworks/base/core/java/android/content/pm/PackageManager.java 找到了FEATURE_NFC 以及 hasSystemFeature的定义
public static final String FEATURE_NFC = "android.hardware.nfc";
public abstract boolean hasSystemFeature(String name);
PackageManager本身就是个抽象类,里面的hasSystemFeature方法就是个尚未实现的抽象方法。接下来寻找实现的该方法的派生类
-------------------
用OpenGrok找到了/android/frameworks/base/core/java/android/app/ApplicationPackageManager.java
该类继承了PackageManager,下面是hasSystemFeature的具体实现
@Override
public boolean hasSystemFeature(String name) {
try {
return mPM.hasSystemFeature(name);
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
}
mPM是一个接口类
private final IPackageManager mPM;
然后找到实现 IPackageManager 的类/android/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public boolean hasSystemFeature(String name) {
synchronized (mPackages) {
return mAvailableFeatures.containsKey(name);
}
}
mAvailableFeature 是在SystemConfig 的一个成员变量
/android/frameworks/base/services/core/java/com/android/server/SystemConfig.java
在SystemConfig的构造函数中,发现mAvailableFeature其实是读取的/system/etc/permissions/ 里面的xml配置文件
readPermissions(Environment.buildPath(Environment.getRootDirectory(), "etc", "permissions"), false);
------------------------
现在我们就要看看这个xml配置文件是在哪里被复制过去的。
在项目的nfc.mk文件中,我似乎找到了复制文件的踪影
# These are the hardware-specific features
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.nfc.xml:system/etc/permissions/android.hardware.nfc.xml
而nfc.mk 是在项目的 device.mk中定义的,至此,我们从使用的地方逆向找到了定义的文件
在寻找的过程中,抽象类和接口类的实现地方是最容易被迷惑的。特记此篇保存这种寻找的感觉