1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.compatibility.common.deviceinfo; 17 18 import android.content.pm.FeatureInfo; 19 import android.content.pm.PackageManager; 20 import android.os.Build; 21 22 import com.android.compatibility.common.util.DeviceInfoStore; 23 24 import java.lang.reflect.Field; 25 import java.lang.reflect.InvocationTargetException; 26 import java.lang.reflect.Method; 27 import java.util.ArrayList; 28 import java.util.HashSet; 29 import java.util.List; 30 import java.util.Set; 31 32 /** 33 * Feature device info collector. 34 */ 35 public final class FeatureDeviceInfo extends DeviceInfo { 36 37 @Override collectDeviceInfo(DeviceInfoStore store)38 protected void collectDeviceInfo(DeviceInfoStore store) throws Exception { 39 PackageManager packageManager = 40 getInstrumentation().getContext().getPackageManager(); 41 store.startArray("feature"); 42 43 List<String> sdkFeatures = getPackageManagerFeatures(); 44 45 FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures(); 46 if (featureInfos != null) { 47 for (FeatureInfo featureInfo : featureInfos) { 48 if (featureInfo.name != null) { 49 // Check if this feature is a "sdk" feature. 50 String type = "other"; 51 if (sdkFeatures.contains(featureInfo.name)) { 52 type = "sdk"; 53 sdkFeatures.remove(featureInfo.name); 54 } 55 // Add the feature version if avaiable. 56 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 57 int version = featureInfo.version; 58 addFeature(store, featureInfo.name, type, true, version); 59 } else { 60 addFeature(store, featureInfo.name, type, true); 61 } 62 } 63 } 64 } 65 66 // Store the remaining "sdk" features not avaiable on this device. 67 for (String featureName : sdkFeatures) { 68 boolean hasFeature = packageManager.hasSystemFeature(featureName); 69 addFeature(store, featureName, "sdk", hasFeature); 70 } 71 72 store.endArray(); 73 } 74 75 /** 76 * Use reflection to get the features defined by the SDK. If there are 77 * features that do not fit the convention of starting with "FEATURE_" 78 * then they will still be shown under the "Other Features" section. 79 * 80 * @return list of feature names from sdk 81 */ getPackageManagerFeatures()82 private List<String> getPackageManagerFeatures() { 83 try { 84 List<String> features = new ArrayList<String>(); 85 Field[] fields = PackageManager.class.getFields(); 86 for (Field field : fields) { 87 if (field.getName().startsWith("FEATURE_")) { 88 String feature = (String) field.get(null); 89 features.add(feature); 90 } 91 } 92 return features; 93 } catch (IllegalAccessException illegalAccess) { 94 throw new RuntimeException(illegalAccess); 95 } 96 } 97 addFeature( DeviceInfoStore store, String name, String type, boolean available)98 private void addFeature( 99 DeviceInfoStore store, 100 String name, 101 String type, 102 boolean available) throws Exception { 103 store.startGroup(); 104 store.addResult("name", name); 105 store.addResult("type", type); 106 store.addResult("available", available); 107 store.endGroup(); 108 } 109 addFeature( DeviceInfoStore store, String name, String type, boolean available, int version)110 private void addFeature( 111 DeviceInfoStore store, 112 String name, 113 String type, 114 boolean available, 115 int version) throws Exception { 116 store.startGroup(); 117 store.addResult("name", name); 118 store.addResult("type", type); 119 store.addResult("available", available); 120 store.addResult("version", version); 121 store.endGroup(); 122 } 123 } 124