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 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and limitations under the 13 * License. 14 * 15 */ 16 17 package com.android.benchmark.registry; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.ActivityInfo; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.content.res.Resources; 26 import android.content.res.TypedArray; 27 import android.content.res.XmlResourceParser; 28 import android.util.AttributeSet; 29 import android.util.SparseArray; 30 import android.util.Xml; 31 32 import com.android.benchmark.R; 33 34 import org.xmlpull.v1.XmlPullParser; 35 import org.xmlpull.v1.XmlPullParserException; 36 37 import java.io.IOException; 38 import java.util.ArrayList; 39 import java.util.List; 40 41 /** 42 */ 43 public class BenchmarkRegistry { 44 45 /** Metadata key for benchmark XML data */ 46 private static final String BENCHMARK_GROUP_META_KEY = 47 "com.android.benchmark.benchmark_group"; 48 49 /** Intent action specifying an activity that runs a single benchmark test. */ 50 private static final String ACTION_BENCHMARK = "com.android.benchmark.ACTION_BENCHMARK"; 51 public static final String EXTRA_ID = "com.android.benchmark.EXTRA_ID"; 52 53 private static final String TAG_BENCHMARK_GROUP = "com.android.benchmark.BenchmarkGroup"; 54 private static final String TAG_BENCHMARK = "com.android.benchmark.Benchmark"; 55 56 private List<BenchmarkGroup> mGroups; 57 58 private final Context mContext; 59 BenchmarkRegistry(Context context)60 public BenchmarkRegistry(Context context) { 61 mContext = context; 62 mGroups = new ArrayList<>(); 63 loadBenchmarks(); 64 } 65 getIntentFromInfo(ActivityInfo inf)66 private Intent getIntentFromInfo(ActivityInfo inf) { 67 Intent intent = new Intent(); 68 intent.setClassName(inf.packageName, inf.name); 69 return intent; 70 } 71 loadBenchmarks()72 public void loadBenchmarks() { 73 Intent intent = new Intent(ACTION_BENCHMARK); 74 intent.setPackage(mContext.getPackageName()); 75 76 PackageManager pm = mContext.getPackageManager(); 77 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 78 PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA); 79 80 for (ResolveInfo inf : resolveInfos) { 81 List<BenchmarkGroup> groups = parseBenchmarkGroup(inf.activityInfo); 82 if (groups != null) { 83 mGroups.addAll(groups); 84 } 85 } 86 } 87 seekToTag(XmlPullParser parser, String tag)88 private boolean seekToTag(XmlPullParser parser, String tag) 89 throws XmlPullParserException, IOException { 90 int eventType = parser.getEventType(); 91 while (eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_DOCUMENT) { 92 eventType = parser.next(); 93 } 94 return eventType != XmlPullParser.END_DOCUMENT && tag.equals(parser.getName()); 95 } 96 getCategory(int category)97 @BenchmarkCategory int getCategory(int category) { 98 switch (category) { 99 case BenchmarkCategory.COMPUTE: 100 return BenchmarkCategory.COMPUTE; 101 case BenchmarkCategory.UI: 102 return BenchmarkCategory.UI; 103 default: 104 return BenchmarkCategory.GENERIC; 105 } 106 } 107 parseBenchmarkGroup(ActivityInfo activityInfo)108 private List<BenchmarkGroup> parseBenchmarkGroup(ActivityInfo activityInfo) { 109 PackageManager pm = mContext.getPackageManager(); 110 111 ComponentName componentName = new ComponentName( 112 activityInfo.packageName, activityInfo.name); 113 114 SparseArray<List<BenchmarkGroup.Benchmark>> benchmarks = new SparseArray<>(); 115 String groupName, groupDescription; 116 try (XmlResourceParser parser = activityInfo.loadXmlMetaData(pm, BENCHMARK_GROUP_META_KEY)) { 117 118 if (!seekToTag(parser, TAG_BENCHMARK_GROUP)) { 119 return null; 120 } 121 122 Resources res = pm.getResourcesForActivity(componentName); 123 AttributeSet attributeSet = Xml.asAttributeSet(parser); 124 TypedArray groupAttribs = res.obtainAttributes(attributeSet, R.styleable.BenchmarkGroup); 125 126 groupName = groupAttribs.getString(R.styleable.BenchmarkGroup_name); 127 groupDescription = groupAttribs.getString(R.styleable.BenchmarkGroup_description); 128 groupAttribs.recycle(); 129 parser.next(); 130 131 while (seekToTag(parser, TAG_BENCHMARK)) { 132 TypedArray benchAttribs = 133 res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Benchmark); 134 int id = benchAttribs.getResourceId(R.styleable.Benchmark_id, -1); 135 String testName = benchAttribs.getString(R.styleable.Benchmark_name); 136 String testDescription = benchAttribs.getString(R.styleable.Benchmark_description); 137 int testCategory = benchAttribs.getInt(R.styleable.Benchmark_category, 138 BenchmarkCategory.GENERIC); 139 int category = getCategory(testCategory); 140 BenchmarkGroup.Benchmark benchmark = new BenchmarkGroup.Benchmark( 141 id, testName, category, testDescription); 142 List<BenchmarkGroup.Benchmark> benches = benchmarks.get(category); 143 if (benches == null) { 144 benches = new ArrayList<>(); 145 benchmarks.append(category, benches); 146 } 147 148 benches.add(benchmark); 149 150 benchAttribs.recycle(); 151 parser.next(); 152 } 153 } catch (PackageManager.NameNotFoundException | XmlPullParserException | IOException e) { 154 return null; 155 } 156 157 List<BenchmarkGroup> result = new ArrayList<>(); 158 Intent testIntent = getIntentFromInfo(activityInfo); 159 for (int i = 0; i < benchmarks.size(); i++) { 160 int cat = benchmarks.keyAt(i); 161 List<BenchmarkGroup.Benchmark> thisGroup = benchmarks.get(cat); 162 BenchmarkGroup.Benchmark[] benchmarkArray = 163 new BenchmarkGroup.Benchmark[thisGroup.size()]; 164 thisGroup.toArray(benchmarkArray); 165 result.add(new BenchmarkGroup(componentName, 166 groupName + " - " + getCategoryString(cat), groupDescription, benchmarkArray, 167 testIntent)); 168 } 169 170 return result; 171 } 172 getGroupCount()173 public int getGroupCount() { 174 return mGroups.size(); 175 } 176 getBenchmarkCount(int benchmarkIndex)177 public int getBenchmarkCount(int benchmarkIndex) { 178 BenchmarkGroup group = getBenchmarkGroup(benchmarkIndex); 179 if (group != null) { 180 return group.getBenchmarks().length; 181 } 182 return 0; 183 } 184 getBenchmarkGroup(int benchmarkIndex)185 public BenchmarkGroup getBenchmarkGroup(int benchmarkIndex) { 186 if (benchmarkIndex >= mGroups.size()) { 187 return null; 188 } 189 190 return mGroups.get(benchmarkIndex); 191 } 192 getCategoryString(int category)193 public static String getCategoryString(int category) { 194 switch (category) { 195 case BenchmarkCategory.UI: 196 return "UI"; 197 case BenchmarkCategory.COMPUTE: 198 return "Compute"; 199 case BenchmarkCategory.GENERIC: 200 return "Generic"; 201 default: 202 return ""; 203 } 204 } 205 getBenchmarkName(Context context, int benchmarkId)206 public static String getBenchmarkName(Context context, int benchmarkId) { 207 switch (benchmarkId) { 208 case R.id.benchmark_list_view_scroll: 209 return context.getString(R.string.list_view_scroll_name); 210 case R.id.benchmark_image_list_view_scroll: 211 return context.getString(R.string.image_list_view_scroll_name); 212 case R.id.benchmark_shadow_grid: 213 return context.getString(R.string.shadow_grid_name); 214 case R.id.benchmark_text_high_hitrate: 215 return context.getString(R.string.text_high_hitrate_name); 216 case R.id.benchmark_text_low_hitrate: 217 return context.getString(R.string.text_low_hitrate_name); 218 case R.id.benchmark_edit_text_input: 219 return context.getString(R.string.edit_text_input_name); 220 case R.id.benchmark_memory_bandwidth: 221 return context.getString(R.string.memory_bandwidth_name); 222 case R.id.benchmark_memory_latency: 223 return context.getString(R.string.memory_latency_name); 224 case R.id.benchmark_power_management: 225 return context.getString(R.string.power_management_name); 226 case R.id.benchmark_cpu_heat_soak: 227 return context.getString(R.string.cpu_heat_soak_name); 228 case R.id.benchmark_cpu_gflops: 229 return context.getString(R.string.cpu_gflops_name); 230 case R.id.benchmark_overdraw: 231 return context.getString(R.string.overdraw_name); 232 case R.id.benchmark_bitmap_upload: 233 return context.getString(R.string.bitmap_upload_name); 234 default: 235 return "Some Benchmark"; 236 } 237 } 238 } 239