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 17package com.android.benchmark.app; 18 19import android.annotation.TargetApi; 20import android.os.AsyncTask; 21import android.os.Bundle; 22import android.support.annotation.Nullable; 23import android.support.v4.app.ListFragment; 24import android.util.Log; 25import android.view.FrameMetrics; 26import android.widget.SimpleAdapter; 27 28import com.android.benchmark.R; 29import com.android.benchmark.registry.BenchmarkGroup; 30import com.android.benchmark.registry.BenchmarkRegistry; 31import com.android.benchmark.results.GlobalResultsStore; 32import com.android.benchmark.results.UiBenchmarkResult; 33 34import org.apache.commons.math.stat.descriptive.SummaryStatistics; 35 36import java.io.FileWriter; 37import java.io.IOException; 38import java.net.URI; 39import java.text.DecimalFormat; 40import java.util.ArrayList; 41import java.util.HashMap; 42import java.util.Map; 43 44@TargetApi(24) 45public class UiResultsFragment extends ListFragment { 46 private static final String TAG = "UiResultsFragment"; 47 private static final int NUM_FIELDS = 20; 48 49 private ArrayList<UiBenchmarkResult> mResults = new ArrayList<>(); 50 51 private AsyncTask<Void, Void, ArrayList<Map<String, String>>> mLoadScoresTask = 52 new AsyncTask<Void, Void, ArrayList<Map<String, String>>>() { 53 @Override 54 protected ArrayList<Map<String, String>> doInBackground(Void... voids) { 55 String[] data; 56 if (mResults.size() == 0 || mResults.get(0) == null) { 57 data = new String[] { 58 "No metrics reported", "" 59 }; 60 } else { 61 data = new String[NUM_FIELDS * (1 + mResults.size()) + 2]; 62 SummaryStatistics stats = new SummaryStatistics(); 63 int totalFrameCount = 0; 64 double totalAvgFrameDuration = 0; 65 double total99FrameDuration = 0; 66 double total95FrameDuration = 0; 67 double total90FrameDuration = 0; 68 double totalLongestFrame = 0; 69 double totalShortestFrame = 0; 70 71 for (int i = 0; i < mResults.size(); i++) { 72 int start = (i * NUM_FIELDS) + + NUM_FIELDS; 73 data[(start++)] = "Iteration"; 74 data[(start++)] = "" + i; 75 data[(start++)] = "Total Frames"; 76 int currentFrameCount = mResults.get(i).getTotalFrameCount(); 77 totalFrameCount += currentFrameCount; 78 data[(start++)] = Integer.toString(currentFrameCount); 79 data[(start++)] = "Average frame duration:"; 80 double currentAvgFrameDuration = mResults.get(i).getAverage(FrameMetrics.TOTAL_DURATION); 81 totalAvgFrameDuration += currentAvgFrameDuration; 82 data[(start++)] = String.format("%.2f", currentAvgFrameDuration); 83 data[(start++)] = "Frame duration 99th:"; 84 double current99FrameDuration = mResults.get(i).getPercentile(FrameMetrics.TOTAL_DURATION, 99); 85 total99FrameDuration += current99FrameDuration; 86 data[(start++)] = String.format("%.2f", current99FrameDuration); 87 data[(start++)] = "Frame duration 95th:"; 88 double current95FrameDuration = mResults.get(i).getPercentile(FrameMetrics.TOTAL_DURATION, 95); 89 total95FrameDuration += current95FrameDuration; 90 data[(start++)] = String.format("%.2f", current95FrameDuration); 91 data[(start++)] = "Frame duration 90th:"; 92 double current90FrameDuration = mResults.get(i).getPercentile(FrameMetrics.TOTAL_DURATION, 90); 93 total90FrameDuration += current90FrameDuration; 94 data[(start++)] = String.format("%.2f", current90FrameDuration); 95 data[(start++)] = "Longest frame:"; 96 double longestFrame = mResults.get(i).getMaximum(FrameMetrics.TOTAL_DURATION); 97 if (totalLongestFrame == 0 || longestFrame > totalLongestFrame) { 98 totalLongestFrame = longestFrame; 99 } 100 data[(start++)] = String.format("%.2f", longestFrame); 101 data[(start++)] = "Shortest frame:"; 102 double shortestFrame = mResults.get(i).getMinimum(FrameMetrics.TOTAL_DURATION); 103 if (totalShortestFrame == 0 || totalShortestFrame > shortestFrame) { 104 totalShortestFrame = shortestFrame; 105 } 106 data[(start++)] = String.format("%.2f", shortestFrame); 107 data[(start++)] = "Score:"; 108 double score = mResults.get(i).getScore(); 109 stats.addValue(score); 110 data[(start++)] = String.format("%.2f", score); 111 data[(start++)] = "=============="; 112 data[(start++)] = "============================"; 113 }; 114 115 int start = 0; 116 data[0] = "Overall: "; 117 data[1] = ""; 118 data[(start++)] = "Total Frames"; 119 data[(start++)] = Integer.toString(totalFrameCount); 120 data[(start++)] = "Average frame duration:"; 121 data[(start++)] = String.format("%.2f", totalAvgFrameDuration / mResults.size()); 122 data[(start++)] = "Frame duration 99th:"; 123 data[(start++)] = String.format("%.2f", total99FrameDuration / mResults.size()); 124 data[(start++)] = "Frame duration 95th:"; 125 data[(start++)] = String.format("%.2f", total95FrameDuration / mResults.size()); 126 data[(start++)] = "Frame duration 90th:"; 127 data[(start++)] = String.format("%.2f", total90FrameDuration / mResults.size()); 128 data[(start++)] = "Longest frame:"; 129 data[(start++)] = String.format("%.2f", totalLongestFrame); 130 data[(start++)] = "Shortest frame:"; 131 data[(start++)] = String.format("%.2f", totalShortestFrame); 132 data[(start++)] = "Score:"; 133 data[(start++)] = String.format("%.2f", stats.getGeometricMean()); 134 data[(start++)] = "=============="; 135 data[(start++)] = "============================"; 136 } 137 138 ArrayList<Map<String, String>> dataMap = new ArrayList<>(); 139 for (int i = 0; i < data.length - 1; i += 2) { 140 HashMap<String, String> map = new HashMap<>(); 141 map.put("name", data[i]); 142 map.put("value", data[i + 1]); 143 dataMap.add(map); 144 } 145 146 return dataMap; 147 } 148 149 @Override 150 protected void onPostExecute(ArrayList<Map<String, String>> dataMap) { 151 setListAdapter(new SimpleAdapter(getActivity(), dataMap, R.layout.results_list_item, 152 new String[] {"name", "value"}, new int[] { R.id.result_name, R.id.result_value })); 153 setListShown(true); 154 } 155 }; 156 157 @Override 158 public void onActivityCreated(@Nullable Bundle savedInstanceState) { 159 super.onActivityCreated(savedInstanceState); 160 setListShown(false); 161 mLoadScoresTask.execute(); 162 } 163 164 public void setRunInfo(String name, int runId) { 165 mResults = GlobalResultsStore.getInstance(getActivity()).loadTestResults(name, runId); 166 } 167} 168