1 /* 2 * Copyright (C) 2018 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 17 package com.android.game.qualification.tests; 18 19 import androidx.test.rule.ActivityTestRule; 20 import androidx.test.runner.AndroidJUnit4; 21 import androidx.test.InstrumentationRegistry; 22 23 import com.android.game.qualification.tests.ChoreoTestActivity; 24 import com.google.common.collect.Range; 25 26 import java.util.ArrayList; 27 28 import org.junit.Before; 29 import org.junit.Test; 30 import org.junit.runner.RunWith; 31 import org.junit.Rule; 32 33 import static com.google.common.truth.Truth.assertWithMessage; 34 35 /** 36 * Tests related to Choreographer 37 */ 38 39 @RunWith(AndroidJUnit4.class) 40 public class ChoreoTest { 41 42 @Rule 43 public ActivityTestRule<ChoreoTestActivity> mActivityRule = 44 new ActivityTestRule(ChoreoTestActivity.class, false, false); 45 46 @Before setUp()47 public void setUp() { 48 TestUtils.assumeGameCoreCertified(InstrumentationRegistry.getContext().getPackageManager()); 49 } 50 51 /** 52 * Check if the differences between Choreographer callbacks are not only near the refresh rate, 53 * but that the data does not deviate too much from the mean. 54 */ 55 @Test choreoCallbackTimes()56 public void choreoCallbackTimes() throws InterruptedException { 57 mActivityRule.launchActivity(null); 58 Thread.sleep(3000); 59 ChoreoTestActivity activity = mActivityRule.getActivity(); 60 mActivityRule.finishActivity(); 61 activity.waitUntilDestroyed(); 62 63 ArrayList<Long> intervals = activity.getFrameIntervals(); 64 65 double mean = 0; 66 double min = Double.MAX_VALUE, max = 0; 67 int maxIndex = 0; 68 69 assertWithMessage( 70 "number of frames: Need an adequate amount of frames in order to test Choreographer") 71 .that(intervals.size()) 72 .isGreaterThan(60); 73 74 for (int i = 0; i < intervals.size(); i++) { 75 long interval = intervals.get(i); 76 77 if(interval > max) { 78 max = interval; 79 } 80 81 if(interval < min) { 82 min = interval; 83 } 84 85 mean += interval; 86 } 87 mean = mean / (intervals.size() * 1E6); 88 89 double range = (max - min) / 1E6; 90 91 // TODO: Handle phones with different refresh rates like 90Hz 92 assertWithMessage( 93 "mean callback time: Choreographer callbacks must occur at roughly the same pace as " 94 + "the refresh rate") 95 .that(mean) 96 .isIn(Range.closed(16.45, 16.75)); 97 98 assertWithMessage( 99 "callback time range: Choreographer callbacks must not deviate too much from the mean") 100 .that(range) 101 .isLessThan(2.0); 102 } 103 } 104