| /* |
| * Copyright (C) 2012 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.os.Environment; |
| import android.util.Log; |
| import android.view.IWindowManager; |
| |
| import java.lang.Process; |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.BufferedReader; |
| import java.io.InputStreamReader; |
| import java.util.regex.Pattern; |
| import java.util.regex.Matcher; |
| |
| /** |
| * Events for running a special shell command to capture the frame rate for a given app. 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 MonkeyGetAppFrameRateEvent extends MonkeyEvent { |
| |
| private String GET_APP_FRAMERATE_TMPL = "dumpsys gfxinfo %s"; |
| private String mStatus; |
| private static long sStartTime; // in millisecond |
| private static long sEndTime; // in millisecond |
| private static float sDuration; // in seconds |
| private static String sActivityName = null; |
| private static String sTestCaseName = null; |
| private static int sStartFrameNo; |
| private static int sEndFrameNo; |
| |
| private static final String TAG = "MonkeyGetAppFrameRateEvent"; |
| private static final String LOG_FILE = new File(Environment.getExternalStorageDirectory(), |
| "avgAppFrameRateOut.txt").getAbsolutePath(); |
| private static final Pattern NO_OF_FRAMES_PATTERN = |
| Pattern.compile(".* ([0-9]*) frames rendered"); |
| |
| public MonkeyGetAppFrameRateEvent(String status, String activityName, String testCaseName) { |
| super(EVENT_TYPE_ACTIVITY); |
| mStatus = status; |
| sActivityName = activityName; |
| sTestCaseName = testCaseName; |
| } |
| |
| public MonkeyGetAppFrameRateEvent(String status, String activityName) { |
| super(EVENT_TYPE_ACTIVITY); |
| mStatus = status; |
| sActivityName = activityName; |
| } |
| |
| public MonkeyGetAppFrameRateEvent(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 { |
| Log.w(TAG, "file: " +LOG_FILE); |
| writer = new FileWriter(LOG_FILE, true); // true = append |
| totalNumberOfFrame = sEndFrameNo - sStartFrameNo; |
| avgFrameRate = getAverageFrameRate(totalNumberOfFrame, sDuration); |
| writer.write(String.format("%s:%.2f\n", sTestCaseName, avgFrameRate)); |
| } 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 dumpsys shell command call |
| private String getNumberOfFrames(BufferedReader reader) throws IOException { |
| String noOfFrames = null; |
| String line = null; |
| while((line = reader.readLine()) != null) { |
| Matcher m = NO_OF_FRAMES_PATTERN.matcher(line); |
| if (m.matches()) { |
| noOfFrames = m.group(1); |
| break; |
| } |
| } |
| return noOfFrames; |
| } |
| |
| @Override |
| public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { |
| Process p = null; |
| BufferedReader result = null; |
| String cmd = String.format(GET_APP_FRAMERATE_TMPL, sActivityName); |
| try { |
| p = Runtime.getRuntime().exec(cmd); |
| int status = p.waitFor(); |
| if (status != 0) { |
| Logger.err.println(String.format("// Shell command %s status was %s", |
| cmd, status)); |
| } |
| result = new BufferedReader(new InputStreamReader(p.getInputStream())); |
| |
| String output = getNumberOfFrames(result); |
| |
| if (output != null) { |
| if ("start".equals(mStatus)) { |
| sStartFrameNo = Integer.parseInt(output); |
| sStartTime = System.currentTimeMillis(); |
| } else if ("end".equals(mStatus)) { |
| sEndFrameNo = Integer.parseInt(output); |
| sEndTime = System.currentTimeMillis(); |
| long diff = sEndTime - sStartTime; |
| sDuration = (float) (diff / 1000.0); |
| writeAverageFrameRate(); |
| } |
| } |
| } catch (Exception e) { |
| Logger.err.println("// Exception from " + cmd + ":"); |
| Logger.err.println(e.toString()); |
| } finally { |
| try { |
| if (result != null) { |
| result.close(); |
| } |
| if (p != null) { |
| p.destroy(); |
| } |
| } catch (IOException e) { |
| Logger.err.println(e.toString()); |
| } |
| } |
| return MonkeyEvent.INJECT_SUCCESS; |
| } |
| } |