merge from donut-gms
This commit is contained in:
@@ -291,6 +291,13 @@ See test_defs.xsd for more information.
|
||||
coverage_target="framework"
|
||||
cts="true" />
|
||||
|
||||
<test name="cts-webkit"
|
||||
build_path="cts/tests/tests/webkit"
|
||||
package="com.android.cts.webkit"
|
||||
runner="android.test.InstrumentationCtsTestRunner"
|
||||
coverage_target="framework"
|
||||
cts="true" />
|
||||
|
||||
<test name="cts-widget"
|
||||
build_path="cts/tests"
|
||||
package="com.android.cts.widget"
|
||||
|
||||
@@ -21,9 +21,31 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
LOCAL_JAR_MANIFEST := ../etc/manifest.txt
|
||||
LOCAL_JAVA_LIBRARIES := \
|
||||
ddmlib \
|
||||
jython
|
||||
jython \
|
||||
xmlwriter
|
||||
|
||||
|
||||
LOCAL_MODULE := monkeyrunner
|
||||
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||
|
||||
# Build ext.jar
|
||||
# ============================================================
|
||||
|
||||
ext_dirs := ../../../../external/xmlwriter/src
|
||||
|
||||
ext_src_files := $(call all-java-files-under,$(ext_dirs))
|
||||
|
||||
# ==== the library =========================================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(ext_src_files)
|
||||
|
||||
LOCAL_NO_STANDARD_LIBRARIES := true
|
||||
#LOCAL_JAVA_LIBRARIES := core
|
||||
#LOCAL_STATIC_JAVA_LIBRARIES := libgoogleclient
|
||||
|
||||
LOCAL_MODULE := xmlwriter
|
||||
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.monkeyrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.jheer.XMLWriter;
|
||||
|
||||
/**
|
||||
* MonkeyRecorder is a host side class that records the output of scripts that are run.
|
||||
* It creates a unique directory, puts in an xml file that records each cmd and result.
|
||||
* It stores every screenshot in this directory.
|
||||
* When finished, it zips this all up.
|
||||
*
|
||||
* Calling Sequence:
|
||||
* mr = new MonkeyRecorder(scriptName);
|
||||
* mr.startCommand();
|
||||
* [mr.addAttribute(name, value);]
|
||||
* ...
|
||||
* [mr.addInput(cmd);]
|
||||
* [mr.addResults(result, filename);] // filename = "" if no screenshot
|
||||
* mr.endCommand();
|
||||
* mr.addComment(comment);
|
||||
* mr.startCommand();
|
||||
* ...
|
||||
* mr.endCommand();
|
||||
* ...
|
||||
* mr.close();
|
||||
*
|
||||
* With MonkeyRunner this should output an xml file, <script_name>-yyyyMMdd-HH:mm:ss.xml, into the
|
||||
* directory out/<script_name>-yyyyMMdd-HH:mm:ss with the contents:
|
||||
*
|
||||
* <?xml version="1.0" encoding='UTF-8'?>
|
||||
* <script_run>
|
||||
* script_name="filename"
|
||||
* monkeyRunnerVersion="0.2"
|
||||
* <!-- Device specific variables -->
|
||||
* <device_var var_name="name" var_value="value" />
|
||||
* <device_var name="build.display" value="opal-userdebug 1.6 DRC79 14207 test-keys"/>
|
||||
* ...
|
||||
* <!-- Script commands -->
|
||||
* <command>
|
||||
* dateTime="20090921-17:08:43"
|
||||
* <input cmd="Pressing: menu"/>
|
||||
* <response result="OK" dateTime="20090921-17:08:43"/>
|
||||
* </command>
|
||||
* ...
|
||||
* <command>
|
||||
* dateTime="20090921-17:09:44"
|
||||
* <input cmd="grabscreen"/>
|
||||
* <response result="OK" dateTime="20090921-17:09:45" screenshot="home_screen-20090921-17:09:45.png"/>
|
||||
* </command>
|
||||
* ...
|
||||
* </script_run>
|
||||
*
|
||||
* And then zip it up with all the screenshots in the file: <script_name>-yyyyMMdd-HH:mm:ss.zip.
|
||||
*/
|
||||
|
||||
public class MonkeyRecorder {
|
||||
|
||||
// xml file to store output results in
|
||||
private static String mXmlFilename;
|
||||
private static FileWriter mXmlFile;
|
||||
private static XMLWriter mXmlWriter;
|
||||
|
||||
// unique subdirectory to put results in (screenshots and xml file)
|
||||
private static String mDirname;
|
||||
private static List<String> mScreenShotNames = new ArrayList<String>();
|
||||
|
||||
// where we store all the results for all the script runs
|
||||
private static final String ROOT_DIR = "out";
|
||||
|
||||
// for getting the date and time in now()
|
||||
private static final SimpleDateFormat SIMPLE_DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
|
||||
|
||||
/**
|
||||
* Create a new MonkeyRecorder that records commands and zips up screenshots for submittal
|
||||
*
|
||||
* @param scriptName filepath of the monkey script we are running
|
||||
*/
|
||||
public MonkeyRecorder(String scriptName) throws IOException {
|
||||
// Create directory structure to store xml file, images and zips
|
||||
File scriptFile = new File(scriptName);
|
||||
scriptName = scriptFile.getName(); // Get rid of path
|
||||
mDirname = ROOT_DIR + "/" + stripType(scriptName) + "-" + now();
|
||||
new File(mDirname).mkdirs();
|
||||
|
||||
// Initialize xml file
|
||||
mXmlFilename = stampFilename(stripType(scriptName) + ".xml");
|
||||
initXmlFile(scriptName);
|
||||
}
|
||||
|
||||
// Get the current date and time in a simple string format (used for timestamping filenames)
|
||||
private static String now() {
|
||||
return SIMPLE_DATE_TIME_FORMAT.format(Calendar.getInstance().getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the xml file writer
|
||||
*
|
||||
* @param scriptName filename (not path) of the monkey script, stored as attribute in the xml file
|
||||
*/
|
||||
private static void initXmlFile(String scriptName) throws IOException {
|
||||
mXmlFile = new FileWriter(mDirname + "/" + mXmlFilename);
|
||||
mXmlWriter = new XMLWriter(mXmlFile);
|
||||
mXmlWriter.begin();
|
||||
mXmlWriter.comment("Monkey Script Results");
|
||||
mXmlWriter.start("script_run");
|
||||
mXmlWriter.addAttribute("script_name", scriptName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment to the xml file.
|
||||
*
|
||||
* @param comment comment to add to the xml file
|
||||
*/
|
||||
public static void addComment(String comment) throws IOException {
|
||||
mXmlWriter.comment(comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin writing a command xml element
|
||||
*/
|
||||
public static void startCommand() throws IOException {
|
||||
mXmlWriter.start("command");
|
||||
mXmlWriter.addAttribute("dateTime", now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a command name attribute in a command xml element.
|
||||
* It's add as a sinlge script command could be multiple monkey commands.
|
||||
*
|
||||
* @param cmd command sent to the monkey
|
||||
*/
|
||||
public static void addInput(String cmd) throws IOException {
|
||||
String name = "cmd";
|
||||
String value = cmd;
|
||||
mXmlWriter.tag("input", name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a response xml element in a command.
|
||||
* Attributes include the monkey result, datetime, and possibly screenshot filename
|
||||
*
|
||||
* @param result response of the monkey to the command
|
||||
* @param filename filename of the screen shot (or other file to be included)
|
||||
*/
|
||||
public static void addResult(String result, String filename) throws IOException {
|
||||
int num_args = 2;
|
||||
String[] names = new String[3];
|
||||
String[] values = new String[3];
|
||||
names[0] = "result";
|
||||
values[0] = result;
|
||||
names[1] = "dateTime";
|
||||
values[1] = now();
|
||||
if (filename.length() != 0) {
|
||||
names[2] = "screenshot";
|
||||
values[2] = stampFilename(filename);
|
||||
addScreenShot(filename);
|
||||
num_args = 3;
|
||||
}
|
||||
mXmlWriter.tag("response", names, values, num_args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an attribut to an xml element. name="escaped_value"
|
||||
*
|
||||
* @param name name of the attribute
|
||||
* @param value value of the attribute
|
||||
*/
|
||||
public static void addAttribute(String name, String value) throws IOException {
|
||||
mXmlWriter.addAttribute(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an xml device variable element. name="escaped_value"
|
||||
*
|
||||
* @param name name of the variable
|
||||
* @param value value of the variable
|
||||
*/
|
||||
public static void addDeviceVar(String name, String value) throws IOException {
|
||||
String[] names = {"name", "value"};
|
||||
String[] values = {name, value};
|
||||
mXmlWriter.tag("device_var", names, values, names.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the screenshot to storage and remember you did it so it can be zipped up later.
|
||||
*
|
||||
* @param filename file name of the screenshot to be stored (Not path name)
|
||||
*/
|
||||
private static void addScreenShot(String filename) {
|
||||
File file = new File(filename);
|
||||
String screenShotName = stampFilename(filename);
|
||||
file.renameTo(new File(mDirname, screenShotName));
|
||||
mScreenShotNames.add(screenShotName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish writing a command xml element
|
||||
*/
|
||||
public static void endCommand() throws IOException {
|
||||
mXmlWriter.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add datetime in front of filetype (the stuff after and including the last infamous '.')
|
||||
*
|
||||
* @param filename path of file to be stamped
|
||||
*/
|
||||
private static String stampFilename(String filename) {
|
||||
//
|
||||
int typeIndex = filename.lastIndexOf('.');
|
||||
if (typeIndex == -1) {
|
||||
return filename + "-" + now();
|
||||
}
|
||||
return filename.substring(0, typeIndex) + "-" + now() + filename.substring(typeIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip out the file type (the stuff after and including the last infamous '.')
|
||||
*
|
||||
* @param filename path of file to be stripped of type information
|
||||
*/
|
||||
private static String stripType(String filename) {
|
||||
//
|
||||
int typeIndex = filename.lastIndexOf('.');
|
||||
if (typeIndex == -1)
|
||||
return filename;
|
||||
return filename.substring(0, typeIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a signature element
|
||||
*
|
||||
* @param filename path of file to be signatured
|
||||
*/
|
||||
private static void addMD5Signature(String filename) throws IOException {
|
||||
String signature = "";
|
||||
// find signature... MD5 sig = new MD5(filename); signature = sig.toString();
|
||||
String[] names = new String[] { "type", "filename", "signature" };
|
||||
String[] values = new String[] { "md5", filename, signature };
|
||||
mXmlWriter.tag("Signature", names, values, values.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the monkeyRecorder by closing the xml file and zipping it up with the screenshots.
|
||||
*
|
||||
* @param filename path of file to be stripped of type information
|
||||
*/
|
||||
public static void close() throws IOException {
|
||||
// zip up xml file and screenshots into ROOT_DIR.
|
||||
byte[] buf = new byte[1024];
|
||||
String zipFileName = mXmlFilename + ".zip";
|
||||
endCommand();
|
||||
mXmlFile.close();
|
||||
FileOutputStream zipFile = new FileOutputStream(ROOT_DIR + "/" + zipFileName);
|
||||
ZipOutputStream out = new ZipOutputStream(zipFile);
|
||||
|
||||
// add the xml file
|
||||
addFileToZip(out, mDirname + "/" + mXmlFilename, buf);
|
||||
|
||||
// Add the screenshots
|
||||
for (String filename : mScreenShotNames) {
|
||||
addFileToZip(out, mDirname + "/" + filename, buf);
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to zip up a file into an open zip archive.
|
||||
*
|
||||
* @param zip the stream of the zip archive
|
||||
* @param filepath the filepath of the file to be added to the zip archive
|
||||
* @param buf storage place to stage reads of file before zipping
|
||||
*/
|
||||
private static void addFileToZip(ZipOutputStream zip, String filepath, byte[] buf) throws IOException {
|
||||
FileInputStream in = new FileInputStream(filepath);
|
||||
zip.putNextEntry(new ZipEntry(filepath));
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
zip.write(buf, 0, len);
|
||||
}
|
||||
zip.closeEntry();
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
@@ -30,11 +30,14 @@ import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@@ -53,24 +56,43 @@ public class MonkeyRunner {
|
||||
|
||||
static BufferedReader monkeyReader;
|
||||
static BufferedWriter monkeyWriter;
|
||||
static String monkeyResponse;
|
||||
|
||||
static MonkeyRecorder monkeyRecorder;
|
||||
|
||||
static String scriptName = null;
|
||||
|
||||
// Obtain a suitable logger.
|
||||
private static Logger logger = Logger.getLogger("com.android.monkeyrunner");
|
||||
|
||||
// delay between key events
|
||||
final static int KEY_INPUT_DELAY = 1000;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// version of monkey runner
|
||||
final static String monkeyRunnerVersion = "0.31";
|
||||
|
||||
// TODO: interface cmd; class xml tags; fix logger; test class/script
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
// haven't figure out how to get below INFO...bad parent. Pass -v INFO to turn on logging
|
||||
logger.setLevel(Level.parse("WARNING"));
|
||||
processOptions(args);
|
||||
|
||||
logger.info("initAdb");
|
||||
initAdbConnection();
|
||||
logger.info("openMonkeyConnection");
|
||||
openMonkeyConnection();
|
||||
|
||||
logger.info("start_script");
|
||||
start_script();
|
||||
|
||||
logger.info("ScriptRunner.run");
|
||||
ScriptRunner.run(scriptName);
|
||||
|
||||
logger.info("end_script");
|
||||
end_script();
|
||||
logger.info("closeMonkeyConnection");
|
||||
closeMonkeyConnection();
|
||||
}
|
||||
|
||||
@@ -166,6 +188,8 @@ public class MonkeyRunner {
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByName(monkeyServer);
|
||||
monkeySocket = new Socket(addr, monkeyPort);
|
||||
monkeyWriter = new BufferedWriter(new OutputStreamWriter(monkeySocket.getOutputStream()));
|
||||
monkeyReader = new BufferedReader(new InputStreamReader(monkeySocket.getInputStream()));
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
} catch(IOException e) {
|
||||
@@ -189,32 +213,46 @@ public class MonkeyRunner {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a house cleaning type routine to run before starting a script. Puts
|
||||
* the device in a known state.
|
||||
* This is a house cleaning routine to run before starting a script. Puts
|
||||
* the device in a known state and starts recording interesting info.
|
||||
*/
|
||||
public static void start_script() {
|
||||
press("menu");
|
||||
press("menu");
|
||||
press("home");
|
||||
public static void start_script() throws IOException {
|
||||
press("menu", false);
|
||||
press("menu", false);
|
||||
press("home", false);
|
||||
|
||||
// Start recording the script output, might want md5 signature of file for completeness
|
||||
monkeyRecorder = new MonkeyRecorder(scriptName);
|
||||
|
||||
// Record what device and version of software we are running on
|
||||
monkeyRecorder.addAttribute("monkeyRunnerVersion", monkeyRunnerVersion);
|
||||
addDeviceVars();
|
||||
monkeyRecorder.addComment("Script commands");
|
||||
}
|
||||
|
||||
public static void end_script() {
|
||||
String command = "END";
|
||||
sendMonkeyEvent(command);
|
||||
/**
|
||||
* This is a house cleaning routine to run after finishing a script.
|
||||
* Puts the monkey server in a known state and closes the recording.
|
||||
*/
|
||||
public static void end_script() throws IOException {
|
||||
String command = "done";
|
||||
sendMonkeyEvent(command, false, false);
|
||||
|
||||
// Stop the recording and zip up the results
|
||||
monkeyRecorder.close();
|
||||
}
|
||||
|
||||
/** This is a method for scripts to launch an activity on the device
|
||||
*
|
||||
* @param name The name of the activity to launch
|
||||
*/
|
||||
public static void launch_activity(String name) {
|
||||
try {
|
||||
public static void launch_activity(String name) throws IOException {
|
||||
System.out.println("Launching: " + name);
|
||||
recordCommand("Launching: " + name);
|
||||
monkeyDevice.executeShellCommand("am start -a android.intent.action.MAIN -n "
|
||||
+ name, new NullOutputReceiver());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// void return, so no response given, just close the command element in the xml file.
|
||||
monkeyRecorder.endCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,14 +260,12 @@ public class MonkeyRunner {
|
||||
*
|
||||
* @param tag filename or tag descriptor of the screenshot
|
||||
*/
|
||||
public static void grabscreen(String tag) {
|
||||
public static void grabscreen(String tag) throws IOException {
|
||||
tag += ".png";
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
getDeviceImage(monkeyDevice, tag, false);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
@@ -239,9 +275,11 @@ public class MonkeyRunner {
|
||||
*
|
||||
* @param msec msecs to sleep for
|
||||
*/
|
||||
public static void sleep(int msec) {
|
||||
public static void sleep(int msec) throws IOException {
|
||||
try {
|
||||
recordCommand("sleep: " + msec);
|
||||
Thread.sleep(msec);
|
||||
recordResponse("OK");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -253,12 +291,10 @@ public class MonkeyRunner {
|
||||
* @param x x-coordinate
|
||||
* @param y y-coordinate
|
||||
*/
|
||||
public static boolean tap(int x, int y) {
|
||||
String command = "touch down " + x + " " + y + "\r\n" +
|
||||
"touch up " + x + " " + y + "\r\n";
|
||||
|
||||
System.out.println("Tapping: " + x + ", " + y);
|
||||
return sendMonkeyEvent(command);
|
||||
public static boolean tap(int x, int y) throws IOException {
|
||||
String command = "tap " + x + " " + y;
|
||||
boolean result = sendMonkeyEvent(command);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,25 +302,33 @@ public class MonkeyRunner {
|
||||
*
|
||||
* @param key key to press
|
||||
*/
|
||||
public static boolean press(String key) {
|
||||
String command = "key down " + key + "\r\n" +
|
||||
"key up " + key + "\r\n";
|
||||
public static boolean press(String key) throws IOException {
|
||||
return press(key, true);
|
||||
}
|
||||
|
||||
System.out.println("Pressing: " + key);
|
||||
return sendMonkeyEvent(command);
|
||||
/**
|
||||
* Press function for scripts to call on a particular button or key
|
||||
*
|
||||
* @param key key to press
|
||||
* @param print whether to send output to user
|
||||
*/
|
||||
private static boolean press(String key, boolean print) throws IOException {
|
||||
String command = "press " + key;
|
||||
boolean result = sendMonkeyEvent(command, print, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* dpad down function
|
||||
*/
|
||||
public static boolean down() {
|
||||
public static boolean down() throws IOException {
|
||||
return press("dpad_down");
|
||||
}
|
||||
|
||||
/**
|
||||
* dpad up function
|
||||
*/
|
||||
public static boolean up() {
|
||||
public static boolean up() throws IOException {
|
||||
return press("dpad_up");
|
||||
}
|
||||
|
||||
@@ -293,69 +337,173 @@ public class MonkeyRunner {
|
||||
*
|
||||
* @param text text to type
|
||||
*/
|
||||
public static boolean type(String text) {
|
||||
System.out.println("Typing: " + text);
|
||||
for (int i=0; i<text.length(); i++) {
|
||||
String command = "key down ";
|
||||
char c = text.charAt(i);
|
||||
if(Character.isDigit(c)) {
|
||||
command += "KEYCODE_" + c + "\n" + "key up KEYCODE_" + c + "\n";
|
||||
} else {
|
||||
command = "key down " + c + "\n" + "key up " + c + "\n";
|
||||
public static boolean type(String text) throws IOException {
|
||||
boolean result = false;
|
||||
// text might have line ends, which signal new monkey command, so we have to eat and reissue
|
||||
String[] lines = text.split("[\\r\\n]+");
|
||||
for (String line: lines) {
|
||||
result = sendMonkeyEvent("type " + line + "\n");
|
||||
}
|
||||
// return last result. Should never fail..?
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!sendMonkeyEvent(command)) {
|
||||
System.out.println("\nERROR: Key not set \n");
|
||||
/**
|
||||
* Function to get a static variable from the device
|
||||
*
|
||||
* @param name name of static variable to get
|
||||
*/
|
||||
public static boolean getvar(String name) throws IOException {
|
||||
return sendMonkeyEvent("getvar " + name + "\n");
|
||||
}
|
||||
|
||||
// lets delay a bit after each input to ensure accuracy
|
||||
try {
|
||||
Thread.sleep(KEY_INPUT_DELAY);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
/**
|
||||
* Function to get the list of static variables from the device
|
||||
*/
|
||||
public static boolean listvar() throws IOException {
|
||||
return sendMonkeyEvent("listvar \n");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is the communication bridge between the host and the device.
|
||||
* It sends monkey events and waits for responses over the adb tcp socket.
|
||||
* This version if for all scripted events so that they get recorded and reported to user.
|
||||
*
|
||||
* @param command the monkey command to send to the device
|
||||
*/
|
||||
private static boolean sendMonkeyEvent(String command) {
|
||||
try {
|
||||
monkeyWriter = new BufferedWriter(
|
||||
new OutputStreamWriter(monkeySocket.getOutputStream()));
|
||||
monkeyWriter.write(command);
|
||||
private static boolean sendMonkeyEvent(String command) throws IOException {
|
||||
return sendMonkeyEvent(command, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows the communication bridge between the host and the device
|
||||
* to be invisible to the script for internal needs.
|
||||
* It splits a command into monkey events and waits for responses for each over an adb tcp socket.
|
||||
* Returns on an error, else continues and sets up last response.
|
||||
*
|
||||
* @param command the monkey command to send to the device
|
||||
* @param print whether to print out the responses to the user
|
||||
* @param record whether to put the command in the xml file that stores test outputs
|
||||
*/
|
||||
private static boolean sendMonkeyEvent(String command, Boolean print, Boolean record) throws IOException {
|
||||
command = command.trim();
|
||||
if (print)
|
||||
System.out.println("MonkeyCommand: " + command);
|
||||
if (record)
|
||||
recordCommand(command);
|
||||
logger.info("Monkey Command: " + command + ".");
|
||||
|
||||
// send a single command and get the response
|
||||
monkeyWriter.write(command + "\n");
|
||||
monkeyWriter.flush();
|
||||
monkeyResponse = monkeyReader.readLine();
|
||||
|
||||
monkeyReader = new BufferedReader(
|
||||
new InputStreamReader(monkeySocket.getInputStream()));
|
||||
String response = monkeyReader.readLine();
|
||||
if(monkeyResponse != null) {
|
||||
// if a command returns with a response
|
||||
if (print)
|
||||
System.out.println("MonkeyServer: " + monkeyResponse);
|
||||
if (record)
|
||||
recordResponse(monkeyResponse);
|
||||
logger.info("Monkey Response: " + monkeyResponse + ".");
|
||||
|
||||
sleep(1000);
|
||||
System.out.println("MonkeyServer: " + response);
|
||||
if(response.equals("OK"))
|
||||
// return on error
|
||||
if (monkeyResponse.startsWith("ERROR"))
|
||||
return false;
|
||||
|
||||
// return on ok
|
||||
if(monkeyResponse.startsWith("OK"))
|
||||
return true;
|
||||
if(response.equals("ERROR"))
|
||||
|
||||
// return on something else?
|
||||
return false;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// didn't get a response...
|
||||
if (print)
|
||||
System.out.println("MonkeyServer: ??no response");
|
||||
if (record)
|
||||
recordResponse("??no response");
|
||||
logger.info("Monkey Response: ??no response.");
|
||||
|
||||
//return on no response
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the command in the xml file
|
||||
*
|
||||
* @param command the command sent to the monkey server
|
||||
*/
|
||||
private static void recordCommand(String command) throws IOException {
|
||||
if (monkeyRecorder != null) { // don't record setup junk
|
||||
monkeyRecorder.startCommand();
|
||||
monkeyRecorder.addInput(command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the response in the xml file
|
||||
*
|
||||
* @param response the response sent by the monkey server
|
||||
*/
|
||||
private static void recordResponse(String response) throws IOException {
|
||||
recordResponse(response, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the response and the filename in the xml file, store the file (to be zipped up later)
|
||||
*
|
||||
* @param response the response sent by the monkey server
|
||||
* @param filename the filename of a file to be time stamped, recorded in the xml file and stored
|
||||
*/
|
||||
private static void recordResponse(String response, String filename) throws IOException {
|
||||
if (monkeyRecorder != null) { // don't record setup junk
|
||||
monkeyRecorder.addResult(response, filename); // ignores file if filename empty
|
||||
monkeyRecorder.endCommand();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the device variables to the xml file in monkeyRecorder.
|
||||
* The results get added as device_var tags in the script_run tag
|
||||
*/
|
||||
private static void addDeviceVars() throws IOException {
|
||||
monkeyRecorder.addComment("Device specific variables");
|
||||
sendMonkeyEvent("listvar \n", false, false);
|
||||
if (monkeyResponse.startsWith("OK:")) {
|
||||
// peel off "OK:" string and get the individual var names
|
||||
String[] varNames = monkeyResponse.substring(3).split("\\s+");
|
||||
// grab all the individual var values
|
||||
for (String name: varNames) {
|
||||
sendMonkeyEvent("getvar " + name, false, false);
|
||||
if(monkeyResponse != null) {
|
||||
if (monkeyResponse.startsWith("OK") ) {
|
||||
if (monkeyResponse.length() > 2) {
|
||||
monkeyRecorder.addDeviceVar(name, monkeyResponse.substring(3));
|
||||
} else {
|
||||
// only got OK - good variable but no value
|
||||
monkeyRecorder.addDeviceVar(name, "null");
|
||||
}
|
||||
} else {
|
||||
// error returned - couldn't get var value for name... include error return
|
||||
monkeyRecorder.addDeviceVar(name, monkeyResponse);
|
||||
}
|
||||
} else {
|
||||
// no monkeyResponse - bad variable with no value
|
||||
monkeyRecorder.addDeviceVar(name, "null");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// it's an error, can't find variable names...
|
||||
monkeyRecorder.addAttribute("listvar", monkeyResponse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the command-line options
|
||||
*
|
||||
* @return Returns true if options were parsed with no apparent errors.
|
||||
*/
|
||||
public static void processOptions(String[] args) {
|
||||
private static void processOptions(String[] args) {
|
||||
// parse command line parameters.
|
||||
int index = 0;
|
||||
|
||||
@@ -364,7 +512,7 @@ public class MonkeyRunner {
|
||||
|
||||
if ("-s".equals(argument)) {
|
||||
if(index == args.length) {
|
||||
printAndExit("Missing Server after -s", false);
|
||||
printUsageAndQuit("Missing Server after -s");
|
||||
}
|
||||
|
||||
monkeyServer = args[index++];
|
||||
@@ -372,18 +520,32 @@ public class MonkeyRunner {
|
||||
} else if ("-p".equals(argument)) {
|
||||
// quick check on the next argument.
|
||||
if (index == args.length) {
|
||||
printAndExit("Missing Server IP after -p", false /* terminate */);
|
||||
printUsageAndQuit("Missing Server port after -p");
|
||||
}
|
||||
|
||||
monkeyPort = Integer.parseInt(args[index++]);
|
||||
} else {
|
||||
// get the filepath of the script to run.
|
||||
scriptName = argument;
|
||||
|
||||
// should not be any other device.
|
||||
//if (index < args.length) {
|
||||
// printAndExit("Too many arguments!", false /* terminate */);
|
||||
//}
|
||||
} else if ("-v".equals(argument)) {
|
||||
// quick check on the next argument.
|
||||
if (index == args.length) {
|
||||
printUsageAndQuit("Missing Log Level after -v");
|
||||
}
|
||||
|
||||
Level level = Level.parse(args[index++]);
|
||||
logger.setLevel(level);
|
||||
level = logger.getLevel();
|
||||
System.out.println("Log level set to: " + level + "(" + level.intValue() + ").");
|
||||
System.out.println("Warning: Log levels below INFO(800) not working currently... parent issues");
|
||||
|
||||
} else if (argument.startsWith("-")) {
|
||||
// we have an unrecognized argument.
|
||||
printUsageAndQuit("Unrecognized argument: " + argument + ".");
|
||||
|
||||
monkeyPort = Integer.parseInt(args[index++]);
|
||||
|
||||
} else {
|
||||
// get the filepath of the script to run. This will be the last undashed argument.
|
||||
scriptName = argument;
|
||||
}
|
||||
} while (index < args.length);
|
||||
}
|
||||
@@ -394,23 +556,30 @@ public class MonkeyRunner {
|
||||
private static void getDeviceImage(IDevice device, String filepath, boolean landscape)
|
||||
throws IOException {
|
||||
RawImage rawImage;
|
||||
recordCommand("grabscreen");
|
||||
System.out.println("Grabbing Screeshot: " + filepath + ".");
|
||||
|
||||
try {
|
||||
rawImage = device.getScreenshot();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
recordResponse("No frame buffer", "");
|
||||
printAndExit("Unable to get frame buffer: " + ioe.getMessage(), true /* terminate */);
|
||||
return;
|
||||
}
|
||||
|
||||
// device/adb not available?
|
||||
if (rawImage == null)
|
||||
if (rawImage == null) {
|
||||
recordResponse("No image", "");
|
||||
return;
|
||||
}
|
||||
|
||||
assert rawImage.bpp == 16;
|
||||
|
||||
BufferedImage image;
|
||||
|
||||
logger.info("Raw Image - height: " + rawImage.height + ", width: " + rawImage.width);
|
||||
|
||||
if (landscape) {
|
||||
// convert raw data to an Image
|
||||
image = new BufferedImage(rawImage.height, rawImage.width,
|
||||
@@ -458,16 +627,20 @@ public class MonkeyRunner {
|
||||
}
|
||||
|
||||
if (!ImageIO.write(image, "png", new File(filepath))) {
|
||||
recordResponse("No png writer", "");
|
||||
throw new IOException("Failed to find png writer");
|
||||
}
|
||||
recordResponse("OK", filepath);
|
||||
}
|
||||
|
||||
private static void printUsageAndQuit() {
|
||||
private static void printUsageAndQuit(String message) {
|
||||
// 80 cols marker: 01234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
System.out.println(message);
|
||||
System.out.println("Usage: monkeyrunner [options] SCRIPT_FILE");
|
||||
System.out.println("");
|
||||
System.out.println(" -s MonkeyServer IP Address.");
|
||||
System.out.println(" -p MonkeyServer TCP Port.");
|
||||
System.out.println(" -v MonkeyServer Logging level (ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF)");
|
||||
System.out.println("");
|
||||
System.out.println("");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user