Skip to content

Commit

Permalink
Merge branch 'refresh-rate'
Browse files Browse the repository at this point in the history
* refresh-rate:
  bump to version 2.1
  feat: remove 0th percentile frame info to fix crash
  feat: collect a wider range of frame percentile info
  bump to version 2.0
  feat: update View Results Online link
  fix: inject a DB instance into loadRefreshRate
  feat: set benchmark thresholds based on display refresh rate
  feat: upload results to new endpoint
  feat: record display refresh rate and upload it to the API
  • Loading branch information
joshchoo committed Apr 28, 2020
2 parents a0d1b86 + 17f1853 commit cd636db
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 19 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "com.android.benchmark"
minSdkVersion 24
targetSdkVersion 29
versionCode 3
versionName "1.2"
versionCode 5
versionName "2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/android/benchmark/api/JankBenchAPI.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.android.benchmark.api;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.view.FrameMetrics;

Expand Down Expand Up @@ -52,6 +54,13 @@ private static boolean upload(Entry entry, String url) throws IOException {

private static Entry createEntry(Context context) {
int lastRunId = GlobalResultsStore.getInstance(context).getLastRunId();
SQLiteDatabase db = GlobalResultsStore.getInstance(context).getReadableDatabase();
int lastRunRefreshRate;
try {
lastRunRefreshRate = GlobalResultsStore.getInstance(context).loadRefreshRate(lastRunId, db);
} finally {
db.close();
}
HashMap<String, UiBenchmarkResult> resultsMap = GlobalResultsStore.getInstance(context).loadDetailedAggregatedResults(lastRunId);

Entry entry = new Entry();
Expand All @@ -69,6 +78,7 @@ private static Entry createEntry(Context context) {
entry.setBuildType(Build.TYPE);
entry.setBuildTime(String.valueOf(Build.TIME));
entry.setFingerprint(Build.FINGERPRINT);
entry.setRefreshRate(lastRunRefreshRate);

String kernel_version = getKernelVersion();
entry.setKernelVersion(kernel_version);
Expand All @@ -88,6 +98,14 @@ private static Entry createEntry(Context context) {
result.setBadFramePct(100 * uiResult.getNumBadFrames() / (double) uiResult.getTotalFrameCount());
result.setTotalFrames(uiResult.getTotalFrameCount());
result.setMsAvg(uiResult.getAverage(FrameMetrics.TOTAL_DURATION));
result.setMs10thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 10));
result.setMs20thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 20));
result.setMs30thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 30));
result.setMs40thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 40));
result.setMs50thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 50));
result.setMs60thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 60));
result.setMs70thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 70));
result.setMs80thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 80));
result.setMs90thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 90));
result.setMs95thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 95));
result.setMs99thPctl(uiResult.getPercentile(FrameMetrics.TOTAL_DURATION, 99));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public void run() {

return true;
} else if (id == R.id.action_view_results) {
Uri webpage = Uri.parse("https://data.jankbench.tk");
Uri webpage = Uri.parse("https://jankbenchx.now.sh");
Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class Constants {
private Constants() {}

public static final String BASE_URL = "https://api.jankbench.tk/";
public static final String BASE_URL = "https://jankbenchx.now.sh/api/";
public static final String BENCHMARK_VERSION = "0.1";
}
10 changes: 10 additions & 0 deletions app/src/main/java/com/android/benchmark/models/Entry.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public class Entry {
@SerializedName("results")
@Expose
private List<Result> results = null;
@SerializedName("refresh_rate")
@Expose
private Integer refreshRate;

public Integer getRunId() {
return runId;
Expand Down Expand Up @@ -172,4 +175,11 @@ public void setResults(List<Result> results) {
this.results = results;
}

public int getRefreshRate() {
return refreshRate;
}

public void setRefreshRate(int refreshRate) {
this.refreshRate = refreshRate;
}
}
88 changes: 88 additions & 0 deletions app/src/main/java/com/android/benchmark/models/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@ public class Result {
@SerializedName("ms_avg")
@Expose
private Double msAvg;
@SerializedName("ms_10th_pctl")
@Expose
private Double ms10thPctl;
@SerializedName("ms_20th_pctl")
@Expose
private Double ms20thPctl;
@SerializedName("ms_30th_pctl")
@Expose
private Double ms30thPctl;
@SerializedName("ms_40th_pctl")
@Expose
private Double ms40thPctl;
@SerializedName("ms_50th_pctl")
@Expose
private Double ms50thPctl;
@SerializedName("ms_60th_pctl")
@Expose
private Double ms60thPctl;
@SerializedName("ms_70th_pctl")
@Expose
private Double ms70thPctl;
@SerializedName("ms_80th_pctl")
@Expose
private Double ms80thPctl;
@SerializedName("ms_90th_pctl")
@Expose
private Double ms90thPctl;
Expand Down Expand Up @@ -103,6 +127,70 @@ public void setMsAvg(Double msAvg) {
this.msAvg = msAvg;
}

public Double getMs10thPctl() {
return ms10thPctl;
}

public void setMs10thPctl(Double ms10thPctl) {
this.ms10thPctl = ms10thPctl;
}

public Double getMs20thPctl() {
return ms20thPctl;
}

public void setMs20thPctl(Double ms20thPctl) {
this.ms20thPctl = ms20thPctl;
}

public Double getMs30thPctl() {
return ms30thPctl;
}

public void setMs30thPctl(Double ms30thPctl) {
this.ms30thPctl = ms30thPctl;
}

public Double getMs40thPctl() {
return ms40thPctl;
}

public void setMs40thPctl(Double ms40thPctl) {
this.ms40thPctl = ms40thPctl;
}

public Double getMs50thPctl() {
return ms50thPctl;
}

public void setMs50thPctl(Double ms50thPctl) {
this.ms50thPctl = ms50thPctl;
}

public Double getMs60thPctl() {
return ms60thPctl;
}

public void setMs60thPctl(Double ms60thPctl) {
this.ms60thPctl = ms60thPctl;
}

public Double getMs70thPctl() {
return ms70thPctl;
}

public void setMs70thPctl(Double ms70thPctl) {
this.ms70thPctl = ms70thPctl;
}

public Double getMs80thPctl() {
return ms80thPctl;
}

public void setMs80thPctl(Double ms80thPctl) {
this.ms80thPctl = ms80thPctl;
}

public Double getMs90thPctl() {
return ms90thPctl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class GlobalResultsStore extends SQLiteOpenHelper {

private static GlobalResultsStore sInstance;
private static final String UI_RESULTS_TABLE = "ui_results";
private static final String REFRESH_RATE_TABLE = "refresh_rates";

private final Context mContext;

Expand Down Expand Up @@ -76,10 +77,15 @@ public void onCreate(SQLiteDatabase sqLiteDatabase) {
" total_duration REAL," +
" jank_frame BOOLEAN, " +
" device_charging INTEGER);");

sqLiteDatabase.execSQL("CREATE TABLE " + REFRESH_RATE_TABLE + " (" +
" _id INTEGER PRIMARY KEY AUTOINCREMENT," +
" run_id INTEGER," +
" refresh_rate INTEGER);");
}

public void storeRunResults(String testName, int runId, int iteration,
UiBenchmarkResult result) {
UiBenchmarkResult result, float refresh_rate) {
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();

Expand Down Expand Up @@ -121,6 +127,13 @@ public void storeRunResults(String testName, int runId, int iteration,
}
db.insert(UI_RESULTS_TABLE, null, cv);
}

// Store Display Refresh Rate
ContentValues cv = new ContentValues();
cv.put("run_id", runId);
cv.put("refresh_rate", Math.round(refresh_rate));
db.insert(REFRESH_RATE_TABLE, null, cv);

db.setTransactionSuccessful();
Toast.makeText(mContext, "Score: " + result.getScore()
+ " Jank: " + (100 * sortedJankIndices.length) / (float) totalFrameCount + "%",
Expand Down Expand Up @@ -180,7 +193,8 @@ public ArrayList<UiBenchmarkResult> loadTestResults(String testName, int runId)

UiBenchmarkResult iterationResult;
if (resultList.size() == iteration) {
iterationResult = new UiBenchmarkResult(values);
int refresh_rate = loadRefreshRate(runId, db);
iterationResult = new UiBenchmarkResult(values, refresh_rate);
resultList.add(iteration, iterationResult);
} else {
iterationResult = resultList.get(iteration);
Expand Down Expand Up @@ -257,7 +271,8 @@ public HashMap<String, ArrayList<UiBenchmarkResult>> loadDetailedResults(int run

UiBenchmarkResult iterationResult;
if (resultList.size() == iteration) {
iterationResult = new UiBenchmarkResult(values);
int refresh_rate = loadRefreshRate(runId, db);
iterationResult = new UiBenchmarkResult(values, refresh_rate);
resultList.add(iterationResult);
} else {
iterationResult = resultList.get(iteration);
Expand Down Expand Up @@ -290,6 +305,25 @@ public int getLastRunId() {
return runId;
}

public int loadRefreshRate(int runId, SQLiteDatabase db) {
int refresh_rate = -1;

try {
String[] columnsToQuery = new String[] {
"run_id",
"refresh_rate"
};
Cursor cursor = db.query(REFRESH_RATE_TABLE, columnsToQuery, "run_id=?", new String[] { Integer.toString(runId) }, null, null, null);
if (cursor.moveToFirst()) {
refresh_rate = cursor.getInt((1));
}
cursor.close();
} finally {
}

return refresh_rate;
}

public HashMap<String, UiBenchmarkResult> loadDetailedAggregatedResults(int runId) {
SQLiteDatabase db = getReadableDatabase();
HashMap<String, UiBenchmarkResult> testsResults = new HashMap<>();
Expand Down Expand Up @@ -340,7 +374,8 @@ public HashMap<String, UiBenchmarkResult> loadDetailedAggregatedResults(int runI

UiBenchmarkResult result = testsResults.get(testName);
if (result == null) {
result = new UiBenchmarkResult(values);
int refresh_rate = loadRefreshRate(runId, db);
result = new UiBenchmarkResult(values, refresh_rate);
testsResults.put(testName, result);
} else {
result.update(values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@
*/
@TargetApi(24)
public class UiBenchmarkResult {
private static final int BASE_SCORE = 100;
private static final int ZERO_SCORE_TOTAL_DURATION_MS = 32;
private static final int JANK_PENALTY_THRESHOLD_MS = 12;
private static final int ZERO_SCORE_ABOVE_THRESHOLD_MS =
private int BASE_SCORE = 100;
private int CONSISTENCY_BONUS_MAX = 100;

private int FRAME_PERIOD_MS = 16;
private int ZERO_SCORE_TOTAL_DURATION_MS = 2 * FRAME_PERIOD_MS;
private int JANK_PENALTY_THRESHOLD_MS = (int) Math.floor(0.75 * FRAME_PERIOD_MS);
private int ZERO_SCORE_ABOVE_THRESHOLD_MS =
ZERO_SCORE_TOTAL_DURATION_MS - JANK_PENALTY_THRESHOLD_MS;
private static final double JANK_PENALTY_PER_MS_ABOVE_THRESHOLD =
private double JANK_PENALTY_PER_MS_ABOVE_THRESHOLD =
BASE_SCORE / (double)ZERO_SCORE_ABOVE_THRESHOLD_MS;
private static final int CONSISTENCY_BONUS_MAX = 100;

private static final int METRIC_WAS_JANKY = -1;

Expand All @@ -52,20 +54,30 @@ public class UiBenchmarkResult {
FrameMetrics.SWAP_BUFFERS_DURATION,
FrameMetrics.TOTAL_DURATION,
};
public static final int FRAME_PERIOD_MS = 16;

private final DescriptiveStatistics[] mStoredStatistics;

public UiBenchmarkResult(List<FrameMetrics> instances) {
public UiBenchmarkResult(List<FrameMetrics> instances, int refresh_rate) {
initializeThresholds(refresh_rate);
mStoredStatistics = new DescriptiveStatistics[METRICS.length];
insertMetrics(instances);
}

public UiBenchmarkResult(double[] values) {
public UiBenchmarkResult(double[] values, int refresh_rate) {
initializeThresholds(refresh_rate);
mStoredStatistics = new DescriptiveStatistics[METRICS.length];
insertValues(values);
}

// Dynamically set threshold values based on display refresh rate
private void initializeThresholds(int refresh_rate) {
FRAME_PERIOD_MS = Math.floorDiv(1000, refresh_rate);
ZERO_SCORE_TOTAL_DURATION_MS = FRAME_PERIOD_MS * 2;
JANK_PENALTY_THRESHOLD_MS = (int) Math.floor(0.75 * FRAME_PERIOD_MS);
ZERO_SCORE_ABOVE_THRESHOLD_MS = ZERO_SCORE_TOTAL_DURATION_MS - JANK_PENALTY_THRESHOLD_MS;
JANK_PENALTY_PER_MS_ABOVE_THRESHOLD = BASE_SCORE / (double)ZERO_SCORE_ABOVE_THRESHOLD_MS;
}

public void update(List<FrameMetrics> instances) {
insertMetrics(instances);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

import android.annotation.TargetApi;
import android.app.Instrumentation;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.view.Display;
import android.view.FrameMetrics;
import android.view.MotionEvent;
import android.view.ViewTreeObserver;
Expand Down Expand Up @@ -188,18 +191,27 @@ private void persistResults(List<FrameMetrics> stats) {
}

if (mResults == null) {
mResults = new UiBenchmarkResult(stats);
float refresh_rate = getFrameRate(mWindow.getContext());
mResults = new UiBenchmarkResult(stats, (int) refresh_rate);
} else {
mResults.update(stats);
}
}

private void writeResults() {
float refresh_rate = getFrameRate(mWindow.getContext());

GlobalResultsStore.getInstance(mWindow.getContext())
.storeRunResults(mTestName, mRunId, mIteration, mResults);
.storeRunResults(mTestName, mRunId, mIteration, mResults, refresh_rate);
}
}

private static float getFrameRate(Context context) {
final DisplayManager displayManager = context.getSystemService(DisplayManager.class);
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
return display.getRefreshRate();
}

private void initHandler() {
mHandler = new AutomatorHandler(getLooper(), mWindow, mCollectorThread, mCallback,
mTestName, mRunId, mIteration);
Expand Down

0 comments on commit cd636db

Please sign in to comment.