Home | History | Annotate | Download | only in monkey
      1 /*
      2  * Copyright (C) 2012 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.commands.monkey;
     18 
     19 import android.app.IActivityManager;
     20 import android.os.Environment;
     21 import android.util.Log;
     22 import android.view.IWindowManager;
     23 
     24 import java.lang.Process;
     25 import java.io.File;
     26 import java.io.FileWriter;
     27 import java.io.IOException;
     28 import java.io.BufferedReader;
     29 import java.io.InputStreamReader;
     30 import java.util.regex.Pattern;
     31 import java.util.regex.Matcher;
     32 
     33 /**
     34  * Events for running a special shell command to capture the frame rate for a given app. To run
     35  * this test, the system property viewancestor.profile_rendering must be set to
     36  * true to force the currently focused window to render at 60 Hz.
     37  */
     38 public class MonkeyGetAppFrameRateEvent extends MonkeyEvent {
     39 
     40     private String GET_APP_FRAMERATE_TMPL = "dumpsys gfxinfo %s";
     41     private String mStatus;
     42     private static long sStartTime; // in millisecond
     43     private static long sEndTime; // in millisecond
     44     private static float sDuration; // in seconds
     45     private static String sActivityName = null;
     46     private static String sTestCaseName = null;
     47     private static int sStartFrameNo;
     48     private static int sEndFrameNo;
     49 
     50     private static final String TAG = "MonkeyGetAppFrameRateEvent";
     51     private static final String LOG_FILE = new File(Environment.getExternalStorageDirectory(),
     52             "avgAppFrameRateOut.txt").getAbsolutePath();
     53     private static final Pattern NO_OF_FRAMES_PATTERN =
     54             Pattern.compile(".* ([0-9]*) frames rendered");
     55 
     56     public MonkeyGetAppFrameRateEvent(String status, String activityName, String testCaseName) {
     57         super(EVENT_TYPE_ACTIVITY);
     58         mStatus = status;
     59         sActivityName = activityName;
     60         sTestCaseName = testCaseName;
     61     }
     62 
     63     public MonkeyGetAppFrameRateEvent(String status, String activityName) {
     64         super(EVENT_TYPE_ACTIVITY);
     65         mStatus = status;
     66         sActivityName = activityName;
     67     }
     68 
     69     public MonkeyGetAppFrameRateEvent(String status) {
     70         super(EVENT_TYPE_ACTIVITY);
     71         mStatus = status;
     72     }
     73 
     74     // Calculate the average frame rate
     75     private float getAverageFrameRate(int totalNumberOfFrame, float duration) {
     76         float avgFrameRate = 0;
     77         if (duration > 0) {
     78             avgFrameRate = (totalNumberOfFrame / duration);
     79         }
     80         return avgFrameRate;
     81     }
     82 
     83     /**
     84      * Calculate the frame rate and write the output to a file on the SD card.
     85      */
     86     private void writeAverageFrameRate() {
     87         FileWriter writer = null;
     88         float avgFrameRate;
     89         int totalNumberOfFrame = 0;
     90         try {
     91             Log.w(TAG, "file: " +LOG_FILE);
     92             writer = new FileWriter(LOG_FILE, true); // true = append
     93             totalNumberOfFrame = sEndFrameNo - sStartFrameNo;
     94             avgFrameRate = getAverageFrameRate(totalNumberOfFrame, sDuration);
     95             writer.write(String.format("%s:%.2f\n", sTestCaseName, avgFrameRate));
     96         } catch (IOException e) {
     97             Log.w(TAG, "Can't write sdcard log file", e);
     98         } finally {
     99             try {
    100                 if (writer != null)
    101                     writer.close();
    102             } catch (IOException e) {
    103                 Log.e(TAG, "IOException " + e.toString());
    104             }
    105         }
    106     }
    107 
    108     // Parse the output of the dumpsys shell command call
    109     private String getNumberOfFrames(BufferedReader reader) throws IOException {
    110         String noOfFrames = null;
    111         String line = null;
    112         while((line = reader.readLine()) != null) {
    113             Matcher m = NO_OF_FRAMES_PATTERN.matcher(line);
    114             if (m.matches()) {
    115                 noOfFrames = m.group(1);
    116                 break;
    117             }
    118         }
    119         return noOfFrames;
    120     }
    121 
    122     @Override
    123     public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
    124         Process p = null;
    125         BufferedReader result = null;
    126         String cmd = String.format(GET_APP_FRAMERATE_TMPL, sActivityName);
    127         try {
    128             p = Runtime.getRuntime().exec(cmd);
    129             int status = p.waitFor();
    130             if (status != 0) {
    131                 Logger.err.println(String.format("// Shell command %s status was %s",
    132                         cmd, status));
    133             }
    134             result = new BufferedReader(new InputStreamReader(p.getInputStream()));
    135 
    136             String output = getNumberOfFrames(result);
    137 
    138             if (output != null) {
    139                 if ("start".equals(mStatus)) {
    140                     sStartFrameNo = Integer.parseInt(output);
    141                     sStartTime = System.currentTimeMillis();
    142                 } else if ("end".equals(mStatus)) {
    143                     sEndFrameNo = Integer.parseInt(output);
    144                     sEndTime = System.currentTimeMillis();
    145                     long diff = sEndTime - sStartTime;
    146                     sDuration = (float) (diff / 1000.0);
    147                     writeAverageFrameRate();
    148                 }
    149             }
    150         } catch (Exception e) {
    151             Logger.err.println("// Exception from " + cmd + ":");
    152             Logger.err.println(e.toString());
    153         } finally {
    154             try {
    155                 if (result != null) {
    156                     result.close();
    157                 }
    158                 if (p != null) {
    159                     p.destroy();
    160                 }
    161             } catch (IOException e) {
    162                 Logger.err.println(e.toString());
    163             }
    164         }
    165         return MonkeyEvent.INJECT_SUCCESS;
    166     }
    167 }
    168