问题
cts测试时发现在result.xml头部中有很多关于手机的信息,包括当前系统有哪些功能,以及build版本等等,这些心怎么显示出来的?
分析
cts 测试中会在TestDeviceSetup app中调用 getFeatures() 该方法返回所有系统的feature,该app是cts的tool源码路径为/cts/tool/device-setup.
getFeature的具体实现:
StringBuilder features = new StringBuilder();
try {
Set<String> checkedFeatures = new HashSet<String>();
PackageManager packageManager = getContext().getPackageManager();
for (String featureName : getPackageManagerFeatures()) {
checkedFeatures.add(featureName);
boolean hasFeature = packageManager.hasSystemFeature(featureName);
addFeature(features, featureName, "sdk", hasFeature);
}
FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
if (featureInfos != null) {
for (FeatureInfo featureInfo : featureInfos) {
if (featureInfo.name != null && !checkedFeatures.contains(featureInfo.name)) {
addFeature(features, featureInfo.name, "other", true);
}
}
}
} catch (Exception exception) {
Log.e(TAG, "Error getting features: " + exception.getMessage(), exception);
}
实现上分为两步:
1)直接从PackageManager类中获取,该类定义了系统的大部分feature的字符串常量;
private List<String> getPackageManagerFeatures() {
try {
List<String> features = new ArrayList<String>();
Field[] fields = PackageManager.class.getFields();
for (Field field : fields) {
if (field.getName().startsWith("FEATURE_")) {
String feature = (String) field.get(null);
features.add(feature);
}
}
return features;
} catch (IllegalAccessException illegalAccess) {
throw new RuntimeException(illegalAccess);
}
}
该方法是用发射机制将PackageManager类中的以FEATURE_公共常量列出来。下面是该类中的部分常量;
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
/**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device is capable of communicating with
* other devices via Bluetooth.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
/**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device has a camera facing away
* from the screen.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_CAMERA = "android.hardware.camera";
/**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device's camera supports auto-focus.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus";
/*
2)系统在启动PackageMangerService时会将对应的系统Feature加载并保存 在一个HashMap中,那通过在这个容器里找到相关feature的信息,如果有证明存在。
packageManager.getSystemAvailableFeatures(),会返回FeatureInfo的数组,保存的是一些Feature的信息。
该数组的获取就是通过前面提到的HashMap 对象有关。
系统启动的时候怎么判断是否有哪些Feature,就是通过解析获取/sys/etc下的xml来的。
该文件有很多的系统Feature的定义