1b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes/* 2b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * Copyright (C) 2015 The Android Open Source Project 3b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * 4b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * Licensed under the Apache License, Version 2.0 (the License); 5b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * you may not use this file except in compliance with the License. 6b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * You may obtain a copy of the License at 7b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * 8b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * http://www.apache.org/licenses/LICENSE-2.0 9b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * 10b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * Unless required by applicable law or agreed to in writing, software 11b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * distributed under the License is distributed on an AS IS BASIS, 12b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * See the License for the specific language governing permissions and 14b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * limitations under the License. 15b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes */ 16b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 17b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandespackage com.android.benchmark.app; 18b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 19b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.annotation.TargetApi; 20b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.os.AsyncTask; 21b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.os.Bundle; 22b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.support.annotation.Nullable; 23b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.support.v4.app.ListFragment; 24b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.util.Log; 25b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.view.FrameMetrics; 26b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.widget.SimpleAdapter; 27b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 28b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.R; 29b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.registry.BenchmarkGroup; 30b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.registry.BenchmarkRegistry; 31b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.results.GlobalResultsStore; 32b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.results.UiBenchmarkResult; 33b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 34b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport org.apache.commons.math.stat.descriptive.SummaryStatistics; 35b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 36b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.io.FileWriter; 37b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.io.IOException; 38b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.net.URI; 39b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.text.DecimalFormat; 40b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.util.ArrayList; 41b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.util.HashMap; 42b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.util.Map; 43b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 44b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes@TargetApi(24) 45b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandespublic class UiResultsFragment extends ListFragment { 46b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private static final String TAG = "UiResultsFragment"; 47b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private static final int NUM_FIELDS = 20; 48b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 49b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private ArrayList<UiBenchmarkResult> mResults = new ArrayList<>(); 50b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 51b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private AsyncTask<Void, Void, ArrayList<Map<String, String>>> mLoadScoresTask = 52b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes new AsyncTask<Void, Void, ArrayList<Map<String, String>>>() { 53b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 54b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected ArrayList<Map<String, String>> doInBackground(Void... voids) { 55b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes String[] data; 56b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mResults.size() == 0 || mResults.get(0) == null) { 57b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data = new String[] { 58b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes "No metrics reported", "" 59b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes }; 60b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } else { 61b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data = new String[NUM_FIELDS * (1 + mResults.size()) + 2]; 62b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes SummaryStatistics stats = new SummaryStatistics(); 63b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes int totalFrameCount = 0; 64b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double totalAvgFrameDuration = 0; 65b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double total99FrameDuration = 0; 66b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double total95FrameDuration = 0; 67b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double total90FrameDuration = 0; 68b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double totalLongestFrame = 0; 69b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double totalShortestFrame = 0; 70b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 71b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes for (int i = 0; i < mResults.size(); i++) { 72b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes int start = (i * NUM_FIELDS) + + NUM_FIELDS; 73b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Iteration"; 74b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "" + i; 75b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Total Frames"; 76b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes int currentFrameCount = mResults.get(i).getTotalFrameCount(); 77b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes totalFrameCount += currentFrameCount; 78b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = Integer.toString(currentFrameCount); 79b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Average frame duration:"; 80b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double currentAvgFrameDuration = mResults.get(i).getAverage(FrameMetrics.TOTAL_DURATION); 81b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes totalAvgFrameDuration += currentAvgFrameDuration; 82b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", currentAvgFrameDuration); 83b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Frame duration 99th:"; 84b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double current99FrameDuration = mResults.get(i).getPercentile(FrameMetrics.TOTAL_DURATION, 99); 85b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes total99FrameDuration += current99FrameDuration; 86b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", current99FrameDuration); 87b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Frame duration 95th:"; 88b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double current95FrameDuration = mResults.get(i).getPercentile(FrameMetrics.TOTAL_DURATION, 95); 89b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes total95FrameDuration += current95FrameDuration; 90b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", current95FrameDuration); 91b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Frame duration 90th:"; 92b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double current90FrameDuration = mResults.get(i).getPercentile(FrameMetrics.TOTAL_DURATION, 90); 93b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes total90FrameDuration += current90FrameDuration; 94b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", current90FrameDuration); 95b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Longest frame:"; 96b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double longestFrame = mResults.get(i).getMaximum(FrameMetrics.TOTAL_DURATION); 97b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (totalLongestFrame == 0 || longestFrame > totalLongestFrame) { 98b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes totalLongestFrame = longestFrame; 99b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 100b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", longestFrame); 101b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Shortest frame:"; 102b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double shortestFrame = mResults.get(i).getMinimum(FrameMetrics.TOTAL_DURATION); 103b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (totalShortestFrame == 0 || totalShortestFrame > shortestFrame) { 104b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes totalShortestFrame = shortestFrame; 105b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 106b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", shortestFrame); 107b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Score:"; 108b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes double score = mResults.get(i).getScore(); 109b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes stats.addValue(score); 110b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", score); 111b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "=============="; 112b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "============================"; 113b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes }; 114b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 115b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes int start = 0; 116b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[0] = "Overall: "; 117b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[1] = ""; 118b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Total Frames"; 119b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = Integer.toString(totalFrameCount); 120b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Average frame duration:"; 121b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", totalAvgFrameDuration / mResults.size()); 122b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Frame duration 99th:"; 123b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", total99FrameDuration / mResults.size()); 124b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Frame duration 95th:"; 125b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", total95FrameDuration / mResults.size()); 126b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Frame duration 90th:"; 127b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", total90FrameDuration / mResults.size()); 128b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Longest frame:"; 129b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", totalLongestFrame); 130b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Shortest frame:"; 131b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", totalShortestFrame); 132b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "Score:"; 133b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = String.format("%.2f", stats.getGeometricMean()); 134b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "=============="; 135b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes data[(start++)] = "============================"; 136b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 137b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 138b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes ArrayList<Map<String, String>> dataMap = new ArrayList<>(); 139b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes for (int i = 0; i < data.length - 1; i += 2) { 140b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes HashMap<String, String> map = new HashMap<>(); 141b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes map.put("name", data[i]); 142b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes map.put("value", data[i + 1]); 143b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes dataMap.add(map); 144b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 145b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 146b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return dataMap; 147b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 148b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 149b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 150b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected void onPostExecute(ArrayList<Map<String, String>> dataMap) { 151b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes setListAdapter(new SimpleAdapter(getActivity(), dataMap, R.layout.results_list_item, 152b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes new String[] {"name", "value"}, new int[] { R.id.result_name, R.id.result_value })); 153b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes setListShown(true); 154b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 155b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes }; 156b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 157b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 158b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void onActivityCreated(@Nullable Bundle savedInstanceState) { 159b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes super.onActivityCreated(savedInstanceState); 160b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes setListShown(false); 161b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mLoadScoresTask.execute(); 162b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 163b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 164b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void setRunInfo(String name, int runId) { 165b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mResults = GlobalResultsStore.getInstance(getActivity()).loadTestResults(name, runId); 166b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 167b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes} 168