Add the framerate catpure tool. The change
introduce two new keywords - StartCaptureFramerate and EndCaptureFramerate. This will call the adb shell call service call SurfaceFlinger 1013 to get the actual fps. The system property - viewancestor.profile_rendering must be set to true before running this test. Change-Id: I0fd1940ac94c77fc2bbf3c8048d7d5d68571590e
This commit is contained in:
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.commands.monkey;
|
||||||
|
|
||||||
|
import android.app.IActivityManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.IWindowManager;
|
||||||
|
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events for running a special shell command to capture the frame rate.
|
||||||
|
* To run this test, the system property viewancestor.profile_rendering
|
||||||
|
* must be set to true to force the currently focused window to render at
|
||||||
|
* 60 Hz.
|
||||||
|
*/
|
||||||
|
public class MonkeyGetFrameRateEvent extends MonkeyEvent {
|
||||||
|
|
||||||
|
private String GET_FRAMERATE_CMD = "service call SurfaceFlinger 1013";
|
||||||
|
private String mStatus;
|
||||||
|
private static long mStartTime; // in millisecond
|
||||||
|
private static long mEndTime; // in millisecond
|
||||||
|
private static float mDuration; // in seconds
|
||||||
|
private static String mTestCaseName = null;
|
||||||
|
private static int mStartFrameNo;
|
||||||
|
private static int mEndFrameNo;
|
||||||
|
|
||||||
|
private static final String TAG = "MonkeyGetFrameRateEvent";
|
||||||
|
private static final String LOG_FILE = "/sdcard/avgFrameRateOut.txt";
|
||||||
|
|
||||||
|
private static final Pattern NO_OF_FRAMES_PATTERN =
|
||||||
|
Pattern.compile(".*\\(([a-f[A-F][0-9]].*?)\\s.*\\)");
|
||||||
|
|
||||||
|
public MonkeyGetFrameRateEvent(String status, String testCaseName) {
|
||||||
|
super(EVENT_TYPE_ACTIVITY);
|
||||||
|
mStatus = status;
|
||||||
|
mTestCaseName = testCaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonkeyGetFrameRateEvent(String status) {
|
||||||
|
super(EVENT_TYPE_ACTIVITY);
|
||||||
|
mStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calculate the average frame rate
|
||||||
|
private float getAverageFrameRate(int totalNumberOfFrame, float duration) {
|
||||||
|
float avgFrameRate = 0;
|
||||||
|
if (duration > 0) {
|
||||||
|
avgFrameRate = (totalNumberOfFrame / duration);
|
||||||
|
}
|
||||||
|
return avgFrameRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the frame rate and write the output to a file on the SD card.
|
||||||
|
*/
|
||||||
|
private void writeAverageFrameRate() {
|
||||||
|
FileWriter writer = null;
|
||||||
|
float avgFrameRate;
|
||||||
|
int totalNumberOfFrame = 0;
|
||||||
|
try {
|
||||||
|
writer = new FileWriter(LOG_FILE, true); // true = append
|
||||||
|
totalNumberOfFrame = mEndFrameNo - mStartFrameNo;
|
||||||
|
avgFrameRate = getAverageFrameRate(totalNumberOfFrame, mDuration);
|
||||||
|
writer.write(String.format("%s:%.2f\n",mTestCaseName,avgFrameRate));
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, "Can't write sdcard log file", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (writer != null) writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "IOException " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the output of the surfaceFlinge shell command call
|
||||||
|
private String getNumberOfFrames(String input){
|
||||||
|
String noOfFrames = null;
|
||||||
|
Matcher m = NO_OF_FRAMES_PATTERN.matcher(input);
|
||||||
|
if (m.matches()){
|
||||||
|
noOfFrames = m.group(1);
|
||||||
|
}
|
||||||
|
return noOfFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
|
||||||
|
java.lang.Process p = null;
|
||||||
|
BufferedReader result = null;
|
||||||
|
try {
|
||||||
|
p = Runtime.getRuntime().exec(GET_FRAMERATE_CMD);
|
||||||
|
int status = p.waitFor();
|
||||||
|
if (status != 0) {
|
||||||
|
System.err.println(String.format("// Shell command %s status was %s",
|
||||||
|
GET_FRAMERATE_CMD, status));
|
||||||
|
}
|
||||||
|
result = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||||
|
|
||||||
|
//Only need the first line of the output
|
||||||
|
String output = result.readLine();
|
||||||
|
|
||||||
|
if (output != null) {
|
||||||
|
if (mStatus == "start") {
|
||||||
|
mStartFrameNo = Integer.parseInt(getNumberOfFrames(output), 16);
|
||||||
|
mStartTime = System.currentTimeMillis();
|
||||||
|
} else if (mStatus == "end") {
|
||||||
|
mEndFrameNo = Integer.parseInt(getNumberOfFrames(output), 16);
|
||||||
|
mEndTime = System.currentTimeMillis();
|
||||||
|
long diff = mEndTime - mStartTime;
|
||||||
|
mDuration = (float)(diff/1000.0);
|
||||||
|
writeAverageFrameRate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("// Exception from " + GET_FRAMERATE_CMD + ":");
|
||||||
|
System.err.println(e.toString());
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (result != null) {
|
||||||
|
result.close();
|
||||||
|
}
|
||||||
|
if (p != null) {
|
||||||
|
p.destroy();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MonkeyEvent.INJECT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -117,6 +117,10 @@ public class MonkeySourceScript implements MonkeyEventSource {
|
|||||||
|
|
||||||
private static final String EVENT_KEYWORD_DRAG = "Drag";
|
private static final String EVENT_KEYWORD_DRAG = "Drag";
|
||||||
|
|
||||||
|
private static final String EVENT_KEYWORD_START_FRAMERATE_CAPTURE = "StartCaptureFramerate";
|
||||||
|
|
||||||
|
private static final String EVENT_KEYWORD_END_FRAMERATE_CAPTURE = "EndCaptureFramerate";
|
||||||
|
|
||||||
// a line at the end of the header
|
// a line at the end of the header
|
||||||
private static final String STARTING_DATA_LINE = "start data >>";
|
private static final String STARTING_DATA_LINE = "start data >>";
|
||||||
|
|
||||||
@@ -523,6 +527,21 @@ public class MonkeySourceScript implements MonkeyEventSource {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s.indexOf(EVENT_KEYWORD_START_FRAMERATE_CAPTURE) >= 0) {
|
||||||
|
MonkeyGetFrameRateEvent e = new MonkeyGetFrameRateEvent("start");
|
||||||
|
mQ.addLast(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.indexOf(EVENT_KEYWORD_END_FRAMERATE_CAPTURE) >= 0 && args.length == 1) {
|
||||||
|
String input = args[0];
|
||||||
|
MonkeyGetFrameRateEvent e = new MonkeyGetFrameRateEvent("end", input);
|
||||||
|
mQ.addLast(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user