1 /* 2 * Copyright (C) 2020 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 android.dumpsys.cts; 18 19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 20 21 import java.io.BufferedReader; 22 import java.io.File; 23 import java.io.IOException; 24 import java.io.StringReader; 25 import java.util.concurrent.TimeUnit; 26 27 /** 28 * Test to check the format of the dumps of the gfxinfo. 29 */ 30 public class GfxInfoDumpsysTest extends BaseDumpsysTest { 31 private static final String TEST_APK = "CtsFramestatsTestApp.apk"; 32 private static final String TEST_PKG = "com.android.cts.framestatstestapp"; 33 34 /** 35 * Tests the output of "dumpsys gfxinfo framestats". 36 * 37 * @throws Exception 38 */ testGfxinfoFramestats()39 public void testGfxinfoFramestats() throws Exception { 40 final String MARKER = "---PROFILEDATA---"; 41 42 try { 43 // cleanup test apps that might be installed from previous partial test run 44 getDevice().uninstallPackage(TEST_PKG); 45 46 // install the test app 47 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); 48 File testAppFile = buildHelper.getTestFile(TEST_APK); 49 String installResult = getDevice().installPackage(testAppFile, false); 50 assertNull( 51 String.format("failed to install atrace test app. Reason: %s", installResult), 52 installResult); 53 54 getDevice().executeShellCommand("am start -W " + TEST_PKG); 55 // Currently "wait for launch" doesn't actually wait for the frame to be finished 56 // So do a little sleep to let things stabilize 57 Thread.sleep(500); 58 59 String frameinfo = mDevice.executeShellCommand("dumpsys gfxinfo " + 60 TEST_PKG + " framestats"); 61 assertNotNull(frameinfo); 62 assertTrue(frameinfo.length() > 0); 63 int profileStart = frameinfo.indexOf(MARKER); 64 int profileEnd = frameinfo.indexOf(MARKER, profileStart + 1); 65 assertTrue(profileStart >= 0); 66 assertTrue(profileEnd > profileStart); 67 String profileData = frameinfo.substring(profileStart + MARKER.length(), profileEnd); 68 assertTrue(profileData.length() > 0); 69 validateProfileData(profileData); 70 } finally { 71 getDevice().uninstallPackage(TEST_PKG); 72 } 73 } 74 validateProfileData(String profileData)75 private void validateProfileData(String profileData) throws IOException { 76 final int TIMESTAMP_COUNT = 22; 77 boolean foundAtLeastOneRow = false; 78 try (BufferedReader reader = new BufferedReader( 79 new StringReader(profileData))) { 80 String line; 81 // First line needs to be the headers 82 while ((line = reader.readLine()) != null && line.isEmpty()) {} 83 84 assertNotNull(line); 85 assertTrue("First line was not the expected header: " + line, 86 line.startsWith("Flags,FrameTimelineVsyncId,IntendedVsync,Vsync" 87 + ",InputEventId,HandleInputStart,AnimationStart,PerformTraversalsStart" 88 + ",DrawStart,FrameDeadline,FrameInterval,FrameStartTime" 89 + ",SyncQueued,SyncStart,IssueDrawCommandsStart,SwapBuffers" 90 + ",FrameCompleted,DequeueBufferDuration,QueueBufferDuration" 91 + ",GpuCompleted,SwapBuffersCompleted,DisplayPresentTime")); 92 93 long[] numparts = new long[TIMESTAMP_COUNT]; 94 while ((line = reader.readLine()) != null && !line.isEmpty()) { 95 96 String[] parts = line.split(","); 97 assertTrue(parts.length >= TIMESTAMP_COUNT); 98 for (int i = 0; i < TIMESTAMP_COUNT; i++) { 99 numparts[i] = assertInteger(parts[i]); 100 } 101 102 final long flags = numparts[0]; 103 // Flags = 1 just means the first frame of the window 104 if (flags != 0 && flags != 1) { 105 continue; 106 } 107 108 final long timestampIntendedVsync = numparts[2]; 109 final long timestampVsync = numparts[3]; 110 // skip InputEventId, since it's a randomly assigned id 111 final long timestampHandleInputStart = numparts[5]; 112 final long timestampAnimationStart = numparts[6]; 113 final long timestampPerformTraversalsStart = numparts[7]; 114 final long timestampDrawStart = numparts[8]; 115 // skip FrameDeadline, FrameInterval,FrameStartTime 116 final long timestampSyncQueued = numparts[12]; 117 final long timestampSyncStart = numparts[13]; 118 final long timestampIssueDrawCommandsStart = numparts[14]; 119 final long timestampSwapBuffers = numparts[15]; 120 final long timestampFrameCompleted = numparts[16]; 121 122 // assert time is flowing forwards. we need to check each entry explicitly 123 // as some entries do not represent a flow of events. 124 assertTrue("VSYNC happened before INTENDED_VSYNC", 125 timestampVsync >= timestampIntendedVsync); 126 assertTrue("HandleInputStart happened before VSYNC", 127 timestampHandleInputStart >= timestampVsync); 128 assertTrue("AnimationStart happened before HandleInputStart", 129 timestampAnimationStart >= timestampHandleInputStart); 130 assertTrue("PerformTraversalsStart happened before AnimationStart", 131 timestampPerformTraversalsStart >= timestampAnimationStart); 132 assertTrue("DrawStart happened before PerformTraversalsStart", 133 timestampDrawStart >= timestampPerformTraversalsStart); 134 assertTrue("SyncQueued happened before DrawStart", 135 timestampSyncQueued >= timestampDrawStart); 136 assertTrue("SyncStart happened before SyncQueued", 137 timestampSyncStart >= timestampSyncQueued); 138 assertTrue("IssueDrawCommandsStart happened before SyncStart", 139 timestampIssueDrawCommandsStart >= timestampSyncStart); 140 assertTrue("SwapBuffers happened before IssueDrawCommandsStart", 141 timestampSwapBuffers >= timestampIssueDrawCommandsStart); 142 assertTrue("FrameCompleted happened before SwapBuffers", 143 timestampFrameCompleted >= timestampSwapBuffers); 144 145 // total duration is from IntendedVsync to FrameCompleted 146 long totalDuration = timestampFrameCompleted - timestampIntendedVsync; 147 assertTrue("Frame did not take a positive amount of time to process", 148 totalDuration > 0); 149 assertTrue("Bogus frame duration, exceeds 100 seconds", 150 totalDuration < TimeUnit.SECONDS.toNanos(100)); 151 foundAtLeastOneRow = true; 152 } 153 } 154 assertTrue(foundAtLeastOneRow); 155 } 156 } 157