+++ /dev/null
-#
-# 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.
-#
-MONKEYRUNNER_LOCAL_DIR := $(call my-dir)
-include $(MONKEYRUNNER_LOCAL_DIR)/etc/Android.mk
-include $(MONKEYRUNNER_LOCAL_DIR)/src/Android.mk
-include $(MONKEYRUNNER_LOCAL_DIR)/test/Android.mk
+++ /dev/null
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
+++ /dev/null
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := monkeyrunner
-include $(BUILD_HOST_PREBUILT)
+++ /dev/null
-Main-Class: com.android.monkeyrunner.MonkeyRunnerStarter
+++ /dev/null
-#!/bin/sh
-# Copyright 2005-2007, 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=monkeyrunner.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/tools/lib
- libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/framework
- libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- echo `basename "$prog"`": can't find $jarfile"
- exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
- # add this in for debugging
- java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
- shift 1
-else
- java_debug=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
- jarpath=`cygpath -w "$frameworkdir/$jarfile"`
- progdir=`cygpath -w "$progdir"`
-else
- jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "$@"
+++ /dev/null
-#!/usr/bin/python2.4
-#
-# Copyright 2010, 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.
-
-"""Test cases for com.android.monkeyrunner.MonkeyRunner."""
-
-import time
-import unittest
-
-from com.android.monkeyrunner import MonkeyRunner
-
-
-class TestMonkeyRunnerArgParsing(unittest.TestCase):
- """Test ArgParsing for the MonkeyRunner methods."""
- def testWaitForConnectionNoArgs(self):
- MonkeyRunner.waitForConnection()
-
- def testWaitForConnectionSingleArg(self):
- MonkeyRunner.waitForConnection(2)
-
- def testWaitForConnectionDoubleArg(self):
- MonkeyRunner.waitForConnection(2, '*')
-
- def testWaitForConnectionKeywordArg(self):
- MonkeyRunner.waitForConnection(timeout=2, deviceId='foo')
-
- def testWaitForConnectionKeywordArgTooMany(self):
- try:
- MonkeyRunner.waitForConnection(timeout=2, deviceId='foo', extra='fail')
- except TypeError:
- return
- self.fail('Should have raised TypeError')
-
- def testSleep(self):
- start = time.time()
- MonkeyRunner.sleep(1.5)
- end = time.time()
-
- self.assertTrue(end - start >= 1.5)
-
-if __name__ == '__main__':
- unittest.main()
+++ /dev/null
-#!/usr/bin/python2.4
-#
-# Copyright 2010, 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.
-
-"""Test runner to run all the tests in this package."""
-
-import os
-import re
-import sys
-import unittest
-
-
-TESTCASE_RE = re.compile('_test\.py$')
-
-
-def AllTestFilesInDir(path):
- """Finds all the unit test files in the given path."""
- return filter(TESTCASE_RE.search, os.listdir(path))
-
-
-def suite(loader=unittest.defaultTestLoader):
- """Creates the all_tests TestSuite."""
- script_parent_path = os.path.abspath(os.path.dirname(sys.argv[0]))
- # Find all the _test.py files in the same directory we are in
- test_files = AllTestFilesInDir(script_parent_path)
- # Convert them into module names
- module_names = [os.path.splitext(f)[0] for f in test_files]
- # And import them
- modules = map(__import__, module_names)
- # And create the test suite for all these modules
- return unittest.TestSuite([loader.loadTestsFromModule(m) for m in modules])
-
-if __name__ == '__main__':
- result = unittest.TextTestRunner().run(suite())
- if not result.wasSuccessful():
- # On failure return an error code
- sys.exit(1)
+++ /dev/null
-#!/usr/bin/env monkeyrunner
-# Copyright 2010, 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.
-from com.android.monkeyrunner import MonkeyRunner as mr
-
-import os
-import sys
-
-supported_formats = ['html', 'text']
-
-if len(sys.argv) != 3:
- print 'help.py: format output'
- sys.exit(1)
-
-(format, saveto_path) = sys.argv[1:]
-
-if not format.lower() in supported_formats:
- print 'format %s is not a supported format' % format
- sys.exit(2)
-
-output = mr.help(format=format)
-if not output:
- print 'Error generating help format'
- sys.exit(3)
-
-dirname = os.path.dirname(saveto_path)
-try:
- os.makedirs(dirname)
-except:
- print 'oops'
- pass # It already existed
-
-fp = open(saveto_path, 'w')
-fp.write(output)
-fp.close()
-
-sys.exit(0)
+++ /dev/null
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
- ddmlib \
- jython \
- guavalib \
- clearsilver
-LOCAL_SHARED_LIBRARIES := libclearsilver-jni
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_MODULE := monkeyrunner
-
-include $(BUILD_HOST_JAVA_LIBRARY)
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.ImmutableMap.Builder;
-
-import com.android.monkeyrunner.doc.MonkeyRunnerExported;
-
-import org.python.core.ArgParser;
-import org.python.core.Py;
-import org.python.core.PyDictionary;
-import org.python.core.PyFloat;
-import org.python.core.PyInteger;
-import org.python.core.PyList;
-import org.python.core.PyNone;
-import org.python.core.PyObject;
-import org.python.core.PyString;
-import org.python.core.PyTuple;
-
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Collection of useful utilities function for interacting with the Jython interpreter.
- */
-public final class JythonUtils {
- private static final Logger LOG = Logger.getLogger(JythonUtils.class.getCanonicalName());
- private JythonUtils() { }
-
- /**
- * Mapping of PyObject classes to the java class we want to convert them to.
- */
- private static final Map<Class<? extends PyObject>, Class<?>> PYOBJECT_TO_JAVA_OBJECT_MAP;
- static {
- Builder<Class<? extends PyObject>, Class<?>> builder = ImmutableMap.builder();
-
- builder.put(PyString.class, String.class);
- // What python calls float, most people call double
- builder.put(PyFloat.class, Double.class);
- builder.put(PyInteger.class, Integer.class);
-
- PYOBJECT_TO_JAVA_OBJECT_MAP = builder.build();
- }
-
- /**
- * Utility method to be called from Jython bindings to give proper handling of keyword and
- * positional arguments.
- *
- * @param args the PyObject arguments from the binding
- * @param kws the keyword arguments from the binding
- * @return an ArgParser for this binding, or null on error
- */
- public static ArgParser createArgParser(PyObject[] args, String[] kws) {
- StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
- // Up 2 levels in the current stack to give us the calling function
- StackTraceElement element = stackTrace[2];
-
- String methodName = element.getMethodName();
- String className = element.getClassName();
-
- Class<?> clz;
- try {
- clz = Class.forName(className);
- } catch (ClassNotFoundException e) {
- LOG.log(Level.SEVERE, "Got exception: ", e);
- return null;
- }
-
- Method m;
-
- try {
- m = clz.getMethod(methodName, PyObject[].class, String[].class);
- } catch (SecurityException e) {
- LOG.log(Level.SEVERE, "Got exception: ", e);
- return null;
- } catch (NoSuchMethodException e) {
- LOG.log(Level.SEVERE, "Got exception: ", e);
- return null;
- }
-
- MonkeyRunnerExported annotation = m.getAnnotation(MonkeyRunnerExported.class);
- return new ArgParser(methodName, args, kws,
- annotation.args());
- }
-
- /**
- * Get a python floating point value from an ArgParser.
- *
- * @param ap the ArgParser to get the value from.
- * @param position the position in the parser
- * @return the double value
- */
- public static double getFloat(ArgParser ap, int position) {
- PyObject arg = ap.getPyObject(position);
-
- if (Py.isInstance(arg, PyFloat.TYPE)) {
- return ((PyFloat) arg).asDouble();
- }
- if (Py.isInstance(arg, PyInteger.TYPE)) {
- return ((PyInteger) arg).asDouble();
- }
- throw Py.TypeError("Unable to parse argument: " + position);
- }
-
- /**
- * Get a python floating point value from an ArgParser.
- *
- * @param ap the ArgParser to get the value from.
- * @param position the position in the parser
- * @param defaultValue the default value to return if the arg isn't specified.
- * @return the double value
- */
- public static double getFloat(ArgParser ap, int position, double defaultValue) {
- PyObject arg = ap.getPyObject(position, new PyFloat(defaultValue));
-
- if (Py.isInstance(arg, PyFloat.TYPE)) {
- return ((PyFloat) arg).asDouble();
- }
- if (Py.isInstance(arg, PyInteger.TYPE)) {
- return ((PyInteger) arg).asDouble();
- }
- throw Py.TypeError("Unable to parse argument: " + position);
- }
-
- /**
- * Get a list of arguments from an ArgParser.
- *
- * @param ap the ArgParser
- * @param position the position in the parser to get the argument from
- * @return a list of those items
- */
- @SuppressWarnings("unchecked")
- public static List<Object> getList(ArgParser ap, int position) {
- PyObject arg = ap.getPyObject(position, Py.None);
- if (Py.isInstance(arg, PyNone.TYPE)) {
- return Collections.emptyList();
- }
-
- List<Object> ret = Lists.newArrayList();
- PyList array = (PyList) arg;
- for (int x = 0; x < array.__len__(); x++) {
- PyObject item = array.__getitem__(x);
-
- Class<?> javaClass = PYOBJECT_TO_JAVA_OBJECT_MAP.get(item.getClass());
- if (javaClass != null) {
- ret.add(item.__tojava__(javaClass));
- }
- }
- return ret;
- }
-
- /**
- * Get a dictionary from an ArgParser. For ease of use, key types are always coerced to
- * strings. If key type cannot be coeraced to string, an exception is raised.
- *
- * @param ap the ArgParser to work with
- * @param position the position in the parser to get.
- * @return a Map mapping the String key to the value
- */
- public static Map<String, Object> getMap(ArgParser ap, int position) {
- PyObject arg = ap.getPyObject(position, Py.None);
- if (Py.isInstance(arg, PyNone.TYPE)) {
- return Collections.emptyMap();
- }
-
- Map<String, Object> ret = Maps.newHashMap();
- // cast is safe as getPyObjectbyType ensures it
- PyDictionary dict = (PyDictionary) arg;
- PyList items = dict.items();
- for (int x = 0; x < items.__len__(); x++) {
- // It's a list of tuples
- PyTuple item = (PyTuple) items.__getitem__(x);
- // We call str(key) on the key to get the string and then convert it to the java string.
- String key = (String) item.__getitem__(0).__str__().__tojava__(String.class);
- PyObject value = item.__getitem__(1);
-
- // Look up the conversion type and convert the value
- Class<?> javaClass = PYOBJECT_TO_JAVA_OBJECT_MAP.get(value.getClass());
- if (javaClass != null) {
- ret.put(key, value.__tojava__(javaClass));
- }
- }
- return ret;
- }
-
- private static PyObject convertObject(Object o) {
- if (o instanceof String) {
- return new PyString((String) o);
- } else if (o instanceof Double) {
- return new PyFloat((Double) o);
- } else if (o instanceof Integer) {
- return new PyInteger((Integer) o);
- } else if (o instanceof Float) {
- float f = (Float) o;
- return new PyFloat(f);
- }
- return Py.None;
- }
-
- /**
- * Convert the given Java Map into a PyDictionary.
- *
- * @param map the map to convert
- * @return the python dictionary
- */
- public static PyDictionary convertMapToDict(Map<String, Object> map) {
- Map<PyObject, PyObject> resultMap = Maps.newHashMap();
-
- for (Entry<String, Object> entry : map.entrySet()) {
- resultMap.put(new PyString(entry.getKey()),
- convertObject(entry.getValue()));
- }
- return new PyDictionary(resultMap);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Functions;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-
-import com.android.monkeyrunner.doc.MonkeyRunnerExported;
-
-import org.python.core.ArgParser;
-import org.python.core.Py;
-import org.python.core.PyDictionary;
-import org.python.core.PyException;
-import org.python.core.PyObject;
-import org.python.core.PyTuple;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-/*
- * Abstract base class that represents a single connected Android
- * Device and provides MonkeyRunner API methods for interacting with
- * that device. Each backend will need to create a concrete
- * implementation of this class.
- */
-public abstract class MonkeyDevice {
- /**
- * Create a MonkeyMananger for talking to this device.
- *
- * NOTE: This is not part of the jython API.
- *
- * @return the MonkeyManager
- */
- public abstract MonkeyManager getManager();
-
- /**
- * Dispose of any native resoureces this device may have taken hold of.
- *
- * NOTE: This is not part of the jython API.
- */
- public abstract void dispose();
-
- @MonkeyRunnerExported(doc = "Fetch the screenbuffer from the device and return it.",
- returns = "The captured snapshot.")
- public abstract MonkeyImage takeSnapshot();
-
- @MonkeyRunnerExported(doc = "Get a MonkeyRunner property (like build.fingerprint)",
- args = {"key"},
- argDocs = {"The key of the property to return"},
- returns = "The value of the property")
- public String getProperty(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- return getProperty(ap.getString(0));
- }
-
- @MonkeyRunnerExported(doc = "Get a system property (returns the same value as getprop).",
- args = {"key"},
- argDocs = {"The key of the property to return"},
- returns = "The value of the property")
- public String getSystemProperty(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
- return getSystemProperty(ap.getString(0));
- }
-
- @MonkeyRunnerExported(doc = "Enumeration of possible touch and press event types. This gets " +
- "passed into a press or touch call to specify the event type.",
- argDocs = {"Indicates the down part of a touch/press event",
- "Indicates the up part of a touch/press event.",
- "Indicates that the monkey should send a down event immediately " +
- "followed by an up event"})
- public enum TouchPressType {
- DOWN, UP, DOWN_AND_UP
- }
-
- @MonkeyRunnerExported(doc = "Send a touch event at the specified location",
- args = { "x", "y", "type" },
- argDocs = { "x coordinate", "y coordinate", "the type of touch event to send"})
- public void touch(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- int x = ap.getInt(0);
- int y = ap.getInt(1);
-
- // Default
- MonkeyDevice.TouchPressType type = MonkeyDevice.TouchPressType.DOWN_AND_UP;
- try {
- PyObject pyObject = ap.getPyObject(2);
- type = (TouchPressType) pyObject.__tojava__(MonkeyDevice.TouchPressType.class);
- } catch (PyException e) {
- // bad stuff was passed in, just use the already specified default value
- type = MonkeyDevice.TouchPressType.DOWN_AND_UP;
- }
- touch(x, y, type);
- }
-
- @MonkeyRunnerExported(doc = "Simulate a drag on the screen.",
- args = { "start", "end", "duration", "steps"},
- argDocs = { "The starting point for the drag (a tuple of x,y)",
- "The end point for the drag (a tuple of x,y)",
- "How long (in seconds) should the drag take (default is 1.0 seconds)",
- "The number of steps to take when interpolating points. (default is 10)"})
- public void drag(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- PyObject startObject = ap.getPyObject(0);
- if (!(startObject instanceof PyTuple)) {
- throw Py.TypeError("Agrument 0 is not a tuple");
- }
- PyObject endObject = ap.getPyObject(1);
- if (!(endObject instanceof PyTuple)) {
- throw Py.TypeError("Agrument 1 is not a tuple");
- }
-
- PyTuple start = (PyTuple) startObject;
- PyTuple end = (PyTuple) endObject;
-
- int startx = (Integer) start.__getitem__(0).__tojava__(Integer.class);
- int starty = (Integer) start.__getitem__(1).__tojava__(Integer.class);
- int endx = (Integer) end.__getitem__(0).__tojava__(Integer.class);
- int endy = (Integer) end.__getitem__(1).__tojava__(Integer.class);
-
- double seconds = JythonUtils.getFloat(ap, 2, 1.0);
- long ms = (long) (seconds * 1000.0);
-
- int steps = ap.getInt(3, 10);
-
- drag(startx, starty, endx, endy, steps, ms);
- }
-
- @MonkeyRunnerExported(doc = "Send a key press event to the specified button",
- args = { "name", "type" },
- argDocs = { "the name of the key to press", "the type of touch event to send"})
- public void press(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String name = ap.getString(0);
-
- // Default
- MonkeyDevice.TouchPressType type = MonkeyDevice.TouchPressType.DOWN_AND_UP;
- try {
- PyObject pyObject = ap.getPyObject(1);
- type = (TouchPressType) pyObject.__tojava__(MonkeyDevice.TouchPressType.class);
- } catch (PyException e) {
- // bad stuff was passed in, just use the already specified default value
- type = MonkeyDevice.TouchPressType.DOWN_AND_UP;
- }
- press(name, type);
- }
-
- @MonkeyRunnerExported(doc = "Type the specified string on the keyboard.",
- args = { "message" },
- argDocs = { "the message to type." })
- public void type(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String message = ap.getString(0);
- type(message);
- }
-
- @MonkeyRunnerExported(doc = "Execute the given command on the shell.",
- args = { "cmd"},
- argDocs = { "The command to execute" },
- returns = "The output of the command")
- public String shell(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String cmd = ap.getString(0);
- return shell(cmd);
- }
-
- @MonkeyRunnerExported(doc = "Reboot the specified device",
- args = { "into" },
- argDocs = { "the bootloader to reboot into (bootloader, recovery, or None)"})
- public void reboot(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String into = ap.getString(0, null);
-
- reboot(into);
- }
-
- @MonkeyRunnerExported(doc = "Install the specified apk onto the device.",
- args = { "path" },
- argDocs = { "The path on the host filesystem to the APK to install." },
- returns = "True if install succeeded")
- public boolean installPackage(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String path = ap.getString(0);
- return installPackage(path);
- }
-
- @MonkeyRunnerExported(doc = "Remove the specified package from the device.",
- args = { "package"},
- argDocs = { "The name of the package to uninstall"},
- returns = "'True if remove succeeded")
- public boolean removePackage(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String packageName = ap.getString(0);
- return removePackage(packageName);
- }
-
- @MonkeyRunnerExported(doc = "Start the Activity specified by the intent.",
- args = { "uri", "action", "data", "mimetype", "categories", "extras",
- "component", "flags" },
- argDocs = { "The URI for the intent",
- "The action for the intent",
- "The data URI for the intent",
- "The mime type for the intent",
- "The list of category names for the intent",
- "A dictionary of extras to add to the intent. Types of these extras " +
- "are inferred from the python types of the values",
- "The component of the intent",
- "A list of flags for the intent" })
- public void startActivity(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String uri = ap.getString(0, null);
- String action = ap.getString(1, null);
- String data = ap.getString(2, null);
- String mimetype = ap.getString(3, null);
- Collection<String> categories = Collections2.transform(JythonUtils.getList(ap, 4),
- Functions.toStringFunction());
- Map<String, Object> extras = JythonUtils.getMap(ap, 5);
- String component = ap.getString(6, null);
- int flags = ap.getInt(7, 0);
-
- startActivity(uri, action, data, mimetype, categories, extras, component, flags);
- }
-
- @MonkeyRunnerExported(doc = "Start the specified broadcast intent on the device.",
- args = { "uri", "action", "data", "mimetype", "categories", "extras",
- "component", "flags" },
- argDocs = { "The URI for the intent",
- "The action for the intent",
- "The data URI for the intent",
- "The mime type for the intent",
- "The list of category names for the intent",
- "A dictionary of extras to add to the intent. Types of these extras " +
- "are inferred from the python types of the values",
- "The component of the intent",
- "A list of flags for the intent" })
- public void broadcastIntent(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String uri = ap.getString(0, null);
- String action = ap.getString(1, null);
- String data = ap.getString(2, null);
- String mimetype = ap.getString(3, null);
- Collection<String> categories = Collections2.transform(JythonUtils.getList(ap, 4),
- Functions.toStringFunction());
- Map<String, Object> extras = JythonUtils.getMap(ap, 5);
- String component = ap.getString(6, null);
- int flags = ap.getInt(7, 0);
-
- broadcastIntent(uri, action, data, mimetype, categories, extras, component, flags);
- }
-
- @MonkeyRunnerExported(doc = "Instrument the specified package and return the results from it.",
- args = { "className", "args" },
- argDocs = { "The class name to instrument (like com.android.test/.TestInstrument)",
- "A Map of String to Objects for the aruments to pass to this " +
- "instrumentation (default value is None)" },
- returns = "A map of string to objects for the results this instrumentation returned")
- public PyDictionary instrument(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String packageName = ap.getString(0);
- Map<String, Object> instrumentArgs = JythonUtils.getMap(ap, 1);
- if (instrumentArgs == null) {
- instrumentArgs = Collections.emptyMap();
- }
-
- Map<String, Object> result = instrument(packageName, instrumentArgs);
- return JythonUtils.convertMapToDict(result);
- }
-
- @MonkeyRunnerExported(doc = "Wake up the screen on the device")
- public void wake(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- wake();
- }
-
- /**
- * Reboot the device.
- *
- * @param into which bootloader to boot into. Null means default reboot.
- */
- protected abstract void reboot(@Nullable String into);
-
- protected abstract String getProperty(String key);
- protected abstract String getSystemProperty(String key);
- protected abstract void touch(int x, int y, TouchPressType type);
- protected abstract void press(String keyName, TouchPressType type);
- protected abstract void drag(int startx, int starty, int endx, int endy, int steps, long ms);
- protected abstract void type(String string);
- protected abstract String shell(String cmd);
- protected abstract boolean installPackage(String path);
- protected abstract boolean removePackage(String packageName);
- protected abstract void startActivity(@Nullable String uri, @Nullable String action,
- @Nullable String data, @Nullable String mimetype,
- Collection<String> categories, Map<String, Object> extras, @Nullable String component,
- int flags);
- protected abstract void broadcastIntent(@Nullable String uri, @Nullable String action,
- @Nullable String data, @Nullable String mimetype,
- Collection<String> categories, Map<String, Object> extras, @Nullable String component,
- int flags);
- protected abstract Map<String, Object> instrument(String packageName,
- Map<String, Object> args);
- protected abstract void wake();
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.collect.Maps;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Map;
-import java.util.logging.Formatter;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-/*
- * Custom Logging Formatter for MonkeyRunner that generates all log
- * messages on a single line.
- */
-public class MonkeyFormatter extends Formatter {
- public static final Formatter DEFAULT_INSTANCE = new MonkeyFormatter();
-
- private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyMMdd HH:mm:ss.SSS");
-
- private static Map<Level, String> LEVEL_TO_STRING_CACHE = Maps.newHashMap();
-
- private static final String levelToString(Level level) {
- String levelName = LEVEL_TO_STRING_CACHE.get(level);
- if (levelName == null) {
- levelName = level.getName().substring(0, 1);
- LEVEL_TO_STRING_CACHE.put(level, levelName);
- }
- return levelName;
- }
-
- private static String getHeader(LogRecord record) {
- StringBuilder sb = new StringBuilder();
-
- sb.append(FORMAT.format(new Date(record.getMillis()))).append(":");
- sb.append(levelToString(record.getLevel())).append(" ");
-
- sb.append("[").append(Thread.currentThread().getName()).append("] ");
-
- String loggerName = record.getLoggerName();
- if (loggerName != null) {
- sb.append("[").append(loggerName).append("]");
- }
- return sb.toString();
- }
-
- private class PrintWriterWithHeader extends PrintWriter {
- private final ByteArrayOutputStream out;
- private final String header;
-
- public PrintWriterWithHeader(String header) {
- this(header, new ByteArrayOutputStream());
- }
-
- public PrintWriterWithHeader(String header, ByteArrayOutputStream out) {
- super(out, true);
- this.header = header;
- this.out = out;
- }
-
- @Override
- public void println(Object x) {
- print(header);
- super.println(x);
- }
-
- @Override
- public void println(String x) {
- print(header);
- super.println(x);
- }
-
- @Override
- public String toString() {
- return out.toString();
- }
- }
-
- @Override
- public String format(LogRecord record) {
- Throwable thrown = record.getThrown();
- String header = getHeader(record);
-
- StringBuilder sb = new StringBuilder();
- sb.append(header);
- sb.append(" ").append(formatMessage(record));
- sb.append("\n");
-
- // Print the exception here if we caught it
- if (thrown != null) {
-
- PrintWriter pw = new PrintWriterWithHeader(header);
- thrown.printStackTrace(pw);
- sb.append(pw.toString());
- }
-
- return sb.toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Preconditions;
-
-import com.android.monkeyrunner.doc.MonkeyRunnerExported;
-
-import org.python.core.ArgParser;
-import org.python.core.PyInteger;
-import org.python.core.PyObject;
-import org.python.core.PyTuple;
-
-import java.awt.Graphics;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.util.Iterator;
-
-import javax.imageio.ImageIO;
-import javax.imageio.ImageWriter;
-import javax.imageio.stream.ImageOutputStream;
-
-/**
- * Jython object to encapsulate images that have been taken.
- */
-public abstract class MonkeyImage {
- /**
- * Convert the MonkeyImage into a BufferedImage.
- *
- * @return a BufferedImage for this MonkeyImage.
- */
- public abstract BufferedImage createBufferedImage();
-
- // Cache the BufferedImage so we don't have to generate it every time.
- private WeakReference<BufferedImage> cachedBufferedImage = null;
-
- /**
- * Utility method to handle getting the BufferedImage and managing the cache.
- *
- * @return the BufferedImage for this image.
- */
- private BufferedImage getBufferedImage() {
- // Check the cache first
- if (cachedBufferedImage != null) {
- BufferedImage img = cachedBufferedImage.get();
- if (img != null) {
- return img;
- }
- }
-
- // Not in the cache, so create it and cache it.
- BufferedImage img = createBufferedImage();
- cachedBufferedImage = new WeakReference<BufferedImage>(img);
- return img;
- }
-
- @MonkeyRunnerExported(doc = "Encode the image into a format and return the bytes.",
- args = {"format"},
- argDocs = { "The (optional) format in which to encode the image (PNG for example)" },
- returns = "A String containing the bytes.")
- public byte[] convertToBytes(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String format = ap.getString(0, "png");
-
- BufferedImage argb = convertSnapshot();
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- try {
- ImageIO.write(argb, format, os);
- } catch (IOException e) {
- return new byte[0];
- }
- return os.toByteArray();
- }
-
- @MonkeyRunnerExported(doc = "Write out the file to the specified location. If no " +
- "format is specified, this function tries to guess at the output format " +
- "depending on the file extension given. If unable to determine, it uses PNG.",
- args = {"path", "format"},
- argDocs = {"Where to write out the file",
- "The format in which to encode the image (PNG for example)"},
- returns = "True if writing succeeded.")
- public boolean writeToFile(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String path = ap.getString(0);
- String format = ap.getString(1, null);
-
- if (format != null) {
- return writeToFile(path, format);
- }
- int offset = path.lastIndexOf('.');
- if (offset < 0) {
- return writeToFile(path, "png");
- }
- String ext = path.substring(offset + 1);
- Iterator<ImageWriter> writers = ImageIO.getImageWritersBySuffix(ext);
- if (!writers.hasNext()) {
- return writeToFile(path, "png");
- }
- ImageWriter writer = writers.next();
- BufferedImage image = getBufferedImage();
- try {
- File f = new File(path);
- f.delete();
-
- ImageOutputStream outputStream = ImageIO.createImageOutputStream(f);
- writer.setOutput(outputStream);
-
- try {
- writer.write(image);
- } finally {
- writer.dispose();
- outputStream.flush();
- }
- } catch (IOException e) {
- return false;
- }
- return true;
- }
-
- @MonkeyRunnerExported(doc = "Get a single ARGB pixel from the image",
- args = { "x", "y" },
- argDocs = { "the x offset of the pixel", "the y offset of the pixel" },
- returns = "A tuple of (A, R, G, B) for the pixel")
- public PyObject getRawPixel(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- int x = ap.getInt(0);
- int y = ap.getInt(1);
- int pixel = getPixel(x, y);
- PyInteger a = new PyInteger((pixel & 0xFF000000) >> 24);
- PyInteger r = new PyInteger((pixel & 0x00FF0000) >> 16);
- PyInteger g = new PyInteger((pixel & 0x0000FF00) >> 8);
- PyInteger b = new PyInteger((pixel & 0x000000FF) >> 0);
- return new PyTuple(a, r, g ,b);
- }
-
- @MonkeyRunnerExported(doc = "Get a single ARGB pixel from the image",
- args = { "x", "y" },
- argDocs = { "the x offset of the pixel", "the y offset of the pixel" },
- returns = "An integer for the ARGB pixel")
- public int getRawPixelInt(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- int x = ap.getInt(0);
- int y = ap.getInt(1);
- return getPixel(x, y);
- }
-
- private int getPixel(int x, int y) {
- BufferedImage image = getBufferedImage();
- return image.getRGB(x, y);
- }
-
- private BufferedImage convertSnapshot() {
- BufferedImage image = getBufferedImage();
-
- // Convert the image to ARGB so ImageIO writes it out nicely
- BufferedImage argb = new BufferedImage(image.getWidth(), image.getHeight(),
- BufferedImage.TYPE_INT_ARGB);
- Graphics g = argb.createGraphics();
- g.drawImage(image, 0, 0, null);
- g.dispose();
- return argb;
- }
-
- public boolean writeToFile(String path, String format) {
- BufferedImage argb = convertSnapshot();
-
- try {
- ImageIO.write(argb, format, new File(path));
- } catch (IOException e) {
- return false;
- }
- return true;
- }
-
- @MonkeyRunnerExported(doc = "Compare this image to the other image.",
- args = {"other", "percent"},
- argDocs = {"The other image.",
- "A float from 0.0 to 1.0 indicating the percentage " +
- "of pixels that need to be the same. Defaults to 1.0"},
- returns = "True if they are the same image.")
- public boolean sameAs(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- PyObject otherObject = ap.getPyObject(0);
- MonkeyImage other = (MonkeyImage) otherObject.__tojava__(MonkeyImage.class);
-
- double percent = JythonUtils.getFloat(ap, 1, 1.0);
-
- BufferedImage otherImage = other.getBufferedImage();
- BufferedImage myImage = getBufferedImage();
-
- // Easy size check
- if (otherImage.getWidth() != myImage.getWidth()) {
- return false;
- }
- if (otherImage.getHeight() != myImage.getHeight()) {
- return false;
- }
-
- int[] otherPixel = new int[1];
- int[] myPixel = new int[1];
-
- int width = myImage.getWidth();
- int height = myImage.getHeight();
-
- int numDiffPixels = 0;
- // Now, go through pixel-by-pixel and check that the images are the same;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- if (myImage.getRGB(x, y) != otherImage.getRGB(x, y)) {
- numDiffPixels++;
- }
- }
- }
- double numberPixels = (height * width);
- double diffPercent = numDiffPixels / numberPixels;
- return percent <= 1.0 - diffPercent;
- }
-
- private static class BufferedImageMonkeyImage extends MonkeyImage {
- private final BufferedImage image;
-
- public BufferedImageMonkeyImage(BufferedImage image) {
- this.image = image;
- }
-
- @Override
- public BufferedImage createBufferedImage() {
- return image;
- }
-
- }
-
- @MonkeyRunnerExported(doc = "Get a sub-image of this image.",
- args = {"rect"},
- argDocs = {"A Tuple of (x, y, w, h) representing the area of the image to extract."},
- returns = "The newly extracted image.")
- public MonkeyImage getSubImage(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- PyTuple rect = (PyTuple) ap.getPyObjectByType(0, PyTuple.TYPE);
- int x = rect.__getitem__(0).asInt();
- int y = rect.__getitem__(1).asInt();
- int w = rect.__getitem__(2).asInt();
- int h = rect.__getitem__(3).asInt();
-
- BufferedImage image = getBufferedImage();
- return new BufferedImageMonkeyImage(image.getSubimage(x, y, w, h));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.collect.Lists;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.Socket;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Provides a nicer interface to interacting with the low-level network access protocol for talking
- * to the monkey.
- *
- * This class is thread-safe and can handle being called from multiple threads.
- */
-public class MonkeyManager {
- private static Logger LOG = Logger.getLogger(MonkeyManager.class.getName());
-
- private Socket monkeySocket;
- private BufferedWriter monkeyWriter;
- private BufferedReader monkeyReader;
-
- /**
- * Create a new MonkeyMananger to talk to the specified device.
- *
- * @param monkeySocket the already connected socket on which to send protocol messages.
- */
- public MonkeyManager(Socket monkeySocket) {
- try {
- this.monkeySocket = monkeySocket;
- monkeyWriter = new BufferedWriter(new OutputStreamWriter(monkeySocket.getOutputStream()));
- monkeyReader = new BufferedReader(new InputStreamReader(monkeySocket.getInputStream()));
- } catch(IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Send a touch down event at the specified location.
- *
- * @param x the x coordinate of where to click
- * @param y the y coordinate of where to click
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean touchDown(int x, int y) throws IOException {
- return sendMonkeyEvent("touch down " + x + " " + y);
- }
-
- /**
- * Send a touch down event at the specified location.
- *
- * @param x the x coordinate of where to click
- * @param y the y coordinate of where to click
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean touchUp(int x, int y) throws IOException {
- return sendMonkeyEvent("touch up " + x + " " + y);
- }
-
- /**
- * Send a touch move event at the specified location.
- *
- * @param x the x coordinate of where to click
- * @param y the y coordinate of where to click
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean touchMove(int x, int y) throws IOException {
- return sendMonkeyEvent("touch move " + x + " " + y);
- }
-
- /**
- * Send a touch (down and then up) event at the specified location.
- *
- * @param x the x coordinate of where to click
- * @param y the y coordinate of where to click
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean touch(int x, int y) throws IOException {
- return sendMonkeyEvent("tap " + x + " " + y);
- }
-
- /**
- * Press a physical button on the device.
- *
- * @param name the name of the button (As specified in the protocol)
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean press(String name) throws IOException {
- return sendMonkeyEvent("press " + name);
- }
-
- /**
- * Send a Key Down event for the specified button.
- *
- * @param name the name of the button (As specified in the protocol)
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean keyDown(String name) throws IOException {
- return sendMonkeyEvent("key down " + name);
- }
-
- /**
- * Send a Key Up event for the specified button.
- *
- * @param name the name of the button (As specified in the protocol)
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean keyUp(String name) throws IOException {
- return sendMonkeyEvent("key up " + name);
- }
-
- /**
- * Press a physical button on the device.
- *
- * @param button the button to press
- * @return success or not
- * @throws IOException on error communicating with the device
- */
- public boolean press(PhysicalButton button) throws IOException {
- return press(button.getKeyName());
- }
-
- /**
- * 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
- * @return the (unparsed) response returned from the monkey.
- */
- private String sendMonkeyEventAndGetResponse(String command) throws IOException {
- command = command.trim();
- LOG.info("Monkey Command: " + command + ".");
-
- // send a single command and get the response
- monkeyWriter.write(command + "\n");
- monkeyWriter.flush();
- return monkeyReader.readLine();
- }
-
- /**
- * Parse a monkey response string to see if the command succeeded or not.
- *
- * @param monkeyResponse the response
- * @return true if response code indicated success.
- */
- private boolean parseResponseForSuccess(String monkeyResponse) {
- if (monkeyResponse == null) {
- return false;
- }
- // return on ok
- if(monkeyResponse.startsWith("OK")) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Parse a monkey response string to get the extra data returned.
- *
- * @param monkeyResponse the response
- * @return any extra data that was returned, or empty string if there was nothing.
- */
- private String parseResponseForExtra(String monkeyResponse) {
- int offset = monkeyResponse.indexOf(':');
- if (offset < 0) {
- return "";
- }
- return monkeyResponse.substring(offset + 1);
- }
-
- /**
- * 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.
- *
- * @param command the monkey command to send to the device
- * @return true on success.
- */
- private boolean sendMonkeyEvent(String command) throws IOException {
- synchronized (this) {
- String monkeyResponse = sendMonkeyEventAndGetResponse(command);
- return parseResponseForSuccess(monkeyResponse);
- }
- }
-
- /**
- * Close all open resources related to this device.
- */
- public void close() {
- try {
- monkeySocket.close();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to close monkeySocket", e);
- }
- try {
- monkeyReader.close();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to close monkeyReader", e);
- }
- try {
- monkeyWriter.close();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to close monkeyWriter", e);
- }
- }
-
- /**
- * Function to get a static variable from the device.
- *
- * @param name name of static variable to get
- * @return the value of the variable, or null if there was an error
- */
- public String getVariable(String name) throws IOException {
- synchronized (this) {
- String response = sendMonkeyEventAndGetResponse("getvar " + name);
- if (!parseResponseForSuccess(response)) {
- return null;
- }
- return parseResponseForExtra(response);
- }
- }
-
- /**
- * Function to get the list of static variables from the device.
- */
- public Collection<String> listVariable() throws IOException {
- synchronized (this) {
- String response = sendMonkeyEventAndGetResponse("listvar");
- if (!parseResponseForSuccess(response)) {
- Collections.emptyList();
- }
- String extras = parseResponseForExtra(response);
- return Lists.newArrayList(extras.split(" "));
- }
- }
-
- /**
- * Tells the monkey that we are done for this session.
- * @throws IOException
- */
- public void done() throws IOException {
- // this command just drops the connection, so handle it here
- synchronized (this) {
- sendMonkeyEventAndGetResponse("done");
- }
- }
-
- /**
- * Tells the monkey that we are done forever.
- * @throws IOException
- */
- public void quit() throws IOException {
- // this command drops the connection, so handle it here
- synchronized (this) {
- sendMonkeyEventAndGetResponse("quit");
- }
- }
-
- /**
- * Send a tap event at the specified location.
- *
- * @param x the x coordinate of where to click
- * @param y the y coordinate of where to click
- * @return success or not
- * @throws IOException
- * @throws IOException on error communicating with the device
- */
- public boolean tap(int x, int y) throws IOException {
- return sendMonkeyEvent("tap " + x + " " + y);
- }
-
- /**
- * Type the following string to the monkey.
- *
- * @param text the string to type
- * @return success
- * @throws IOException
- */
- public boolean type(String text) throws IOException {
- // The network protocol can't handle embedded line breaks, so we have to handle it
- // here instead
- StringTokenizer tok = new StringTokenizer(text, "\n", true);
- while (tok.hasMoreTokens()) {
- String line = tok.nextToken();
- if ("\n".equals(line)) {
- boolean success = press(PhysicalButton.ENTER);
- if (!success) {
- return false;
- }
- } else {
- boolean success = sendMonkeyEvent("type " + line);
- if (!success) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Type the character to the monkey.
- *
- * @param keyChar the character to type.
- * @return success
- * @throws IOException
- */
- public boolean type(char keyChar) throws IOException {
- return type(Character.toString(keyChar));
- }
-
- /**
- * Wake the device up from sleep.
- * @throws IOException
- */
- public void wake() throws IOException {
- sendMonkeyEvent("wake");
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Functions;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-
-import com.android.monkeyrunner.doc.MonkeyRunnerExported;
-
-import org.python.core.ArgParser;
-import org.python.core.PyException;
-import org.python.core.PyObject;
-
-import java.util.Collection;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.JOptionPane;
-
-/**
- * This is the main interface class into the jython bindings.
- */
-public class MonkeyRunner {
- private static final Logger LOG = Logger.getLogger(MonkeyRunner.class.getCanonicalName());
- private static MonkeyRunnerBackend backend;
-
- /**
- * Set the backend MonkeyRunner is using.
- *
- * @param backend the backend to use.
- */
- /* package */ static void setBackend(MonkeyRunnerBackend backend) {
- MonkeyRunner.backend = backend;
- }
-
- @MonkeyRunnerExported(doc = "Wait for the specified device to connect.",
- args = {"timeout", "deviceId"},
- argDocs = {"The timeout in seconds to wait for the device to connect. (default " +
- "is to wait forever)",
- "A regular expression that specifies the device of for valid devices" +
- " to wait for."},
- returns = "A MonkeyDevice representing the connected device.")
- public static MonkeyDevice waitForConnection(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- long timeoutMs;
- try {
- double timeoutInSecs = JythonUtils.getFloat(ap, 0);
- timeoutMs = (long) (timeoutInSecs * 1000.0);
- } catch (PyException e) {
- timeoutMs = Long.MAX_VALUE;
- }
-
- return backend.waitForConnection(timeoutMs,
- ap.getString(1, ".*"));
- }
-
- @MonkeyRunnerExported(doc = "Pause script processing for the specified number of seconds",
- args = {"seconds"},
- argDocs = {"The number of seconds to pause processing"})
- public static void sleep(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- double seconds = JythonUtils.getFloat(ap, 0);
-
- long ms = (long) (seconds * 1000.0);
-
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- LOG.log(Level.SEVERE, "Error sleeping", e);
- }
- }
-
- @MonkeyRunnerExported(doc = "Simple help command to dump the MonkeyRunner supported " +
- "commands",
- args = { "format" },
- argDocs = {"The format to return the help text in. (default is text)"},
- returns = "The help text")
- public static String help(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String format = ap.getString(0, "text");
-
- return MonkeyRunnerHelp.helpString(format);
- }
-
- @MonkeyRunnerExported(doc = "Put up an alert dialog to inform the user of something that " +
- "happened. This is modal dialog and will stop processing of " +
- "the script until the user acknowledges the alert message",
- args = { "message", "title", "okTitle" },
- argDocs = {
- "The contents of the message of the dialog box",
- "The title to display for the dialog box. (default value is \"Alert\")",
- "The title to use for the acknowledgement button (default value is \"OK\")"
- })
- public static void alert(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String message = ap.getString(0);
- String title = ap.getString(1, "Alert");
- String buttonTitle = ap.getString(2, "OK");
-
- alert(message, title, buttonTitle);
- }
-
- @MonkeyRunnerExported(doc = "Put up an input dialog that allows the user to input a string." +
- " This is a modal dialog that will stop processing of the script until the user " +
- "inputs the requested information.",
- args = {"message", "initialValue", "title", "okTitle", "cancelTitle"},
- argDocs = {
- "The message to display for the input.",
- "The initial value to supply the user (default is empty string)",
- "The title of the dialog box to display. (default is \"Input\")"
- },
- returns = "The test entered by the user, or None if the user canceled the input;"
- )
- public static String input(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String message = ap.getString(0);
- String initialValue = ap.getString(1, "");
- String title = ap.getString(2, "Input");
-
- return input(message, initialValue, title);
- }
-
- @MonkeyRunnerExported(doc = "Put up a choice dialog that allows the user to select a single " +
- "item from a list of items that were presented.",
- args = {"message", "choices", "title"},
- argDocs = {
- "The message to display for the input.",
- "The list of choices to display.",
- "The title of the dialog box to display. (default is \"Input\")" },
- returns = "The numeric offset of the choice selected.")
- public static int choice(PyObject[] args, String kws[]) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
-
- String message = ap.getString(0);
- Collection<String> choices = Collections2.transform(JythonUtils.getList(ap, 1),
- Functions.toStringFunction());
- String title = ap.getString(2, "Input");
-
- return choice(message, title, choices);
- }
-
- /**
- * Display an alert dialog.
- *
- * @param message the message to show.
- * @param title the title of the dialog box.
- * @param okTitle the title of the button.
- */
- private static void alert(String message, String title, String okTitle) {
- Object[] options = { okTitle };
- JOptionPane.showOptionDialog(null, message, title, JOptionPane.DEFAULT_OPTION,
- JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
- }
-
- /**
- * Display a dialog allow the user to pick a choice from a list of choices.
- *
- * @param message the message to show.
- * @param title the title of the dialog box.
- * @param choices the list of the choices to display.
- * @return the index of the selected choice, or -1 if nothing was chosen.
- */
- private static int choice(String message, String title, Collection<String> choices) {
- Object[] possibleValues = choices.toArray();
- Object selectedValue = JOptionPane.showInputDialog(null, message, title,
- JOptionPane.QUESTION_MESSAGE, null, possibleValues, possibleValues[0]);
-
- for (int x = 0; x < possibleValues.length; x++) {
- if (possibleValues[x].equals(selectedValue)) {
- return x;
- }
- }
- // Error
- return -1;
- }
-
- /**
- * Display a dialog that allows the user to input a text string.
- *
- * @param message the message to show.
- * @param initialValue the initial value to display in the dialog
- * @param title the title of the dialog box.
- * @return the entered string, or null if cancelled
- */
- private static String input(String message, String initialValue, String title) {
- return (String) JOptionPane.showInputDialog(null, message, title,
- JOptionPane.QUESTION_MESSAGE, null, null, initialValue);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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;
-
-/**
- * Interface between MonkeyRunner common code and the MonkeyRunner backend. The backend is
- * responsible for communicating between the host and the device.
- */
-public interface MonkeyRunnerBackend {
- /**
- * Wait for a device to connect to the backend.
- *
- * @param timeoutMs how long (in ms) to wait
- * @param deviceIdRegex the regular expression to specify which device to wait for.
- * @return the connected device (or null if timeout);
- */
- MonkeyDevice waitForConnection(long timeoutMs, String deviceIdRegex);
-
- /**
- * Shutdown the backend and cleanup any resources it was using.
- */
- void shutdown();
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.io.Resources;
-
-import com.android.monkeyrunner.doc.MonkeyRunnerExported;
-
-import org.clearsilver.CS;
-import org.clearsilver.CSFileLoader;
-import org.clearsilver.HDF;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Utility class for generating inline help documentation
- */
-public final class MonkeyRunnerHelp {
- private MonkeyRunnerHelp() { }
-
- private static final String HELP = "help";
- private static final String NAME = "name";
- private static final String DOC = "doc";
- private static final String ARGUMENT = "argument";
- private static final String RETURNS = "returns";
- private static final String TYPE = "type";
-
- // Enum used to describe documented types.
- private enum Type {
- ENUM, FIELD, METHOD
- }
-
- private static void getAllExportedClasses(Set<Field> fields,
- Set<Method> methods,
- Set<Constructor<?>> constructors,
- Set<Class<?>> enums) {
- final Set<Class<?>> classesVisited = Sets.newHashSet();
- Set<Class<?>> classesToVisit = Sets.newHashSet();
- classesToVisit.add(MonkeyRunner.class);
-
- Predicate<Class<?>> haventSeen = new Predicate<Class<?>>() {
- public boolean apply(Class<?> clz) {
- return !classesVisited.contains(clz);
- }
- };
-
- while (!classesToVisit.isEmpty()) {
- classesVisited.addAll(classesToVisit);
-
- List<Class<?>> newClasses = Lists.newArrayList();
- for (Class<?> clz : classesToVisit) {
- // See if the class itself is annotated and is an enum
- if (clz.isEnum() && clz.isAnnotationPresent(MonkeyRunnerExported.class)) {
- enums.add(clz);
- }
-
- // Constructors
- for (Constructor<?> c : clz.getConstructors()) {
- newClasses.addAll(Collections2.filter(Arrays.asList(c.getParameterTypes()),
- haventSeen));
- if (c.isAnnotationPresent(MonkeyRunnerExported.class)) {
- constructors.add(c);
- }
- }
-
- // Fields
- for (Field f : clz.getFields()) {
- if (haventSeen.apply(f.getClass())) {
- newClasses.add(f.getClass());
- }
- if (f.isAnnotationPresent(MonkeyRunnerExported.class)) {
- fields.add(f);
- }
- }
-
- // Methods
- for (Method m : clz.getMethods()) {
- newClasses.addAll(Collections2.filter(Arrays.asList(m.getParameterTypes()),
- haventSeen));
- if (haventSeen.apply(m.getReturnType())) {
- newClasses.add(m.getReturnType());
- }
-
- if (m.isAnnotationPresent(MonkeyRunnerExported.class)) {
- methods.add(m);
- }
- }
-
- // Containing classes
- for (Class<?> toAdd : clz.getClasses()) {
- if (haventSeen.apply(toAdd)) {
- newClasses.add(toAdd);
- }
- }
- }
-
- classesToVisit.clear();
- classesToVisit.addAll(newClasses);
- }
- }
-
- private static Comparator<Member> MEMBER_SORTER = new Comparator<Member>() {
- public int compare(Member o1, Member o2) {
- return o1.getName().compareTo(o2.getName());
- }
- };
-
- private static Comparator<Class<?>> CLASS_SORTER = new Comparator<Class<?>>() {
- public int compare(Class<?> o1, Class<?> o2) {
- return o1.getName().compareTo(o2.getName());
- }
- };
-
- public static String helpString(String format) {
- // Quick check for support formats
- if ("html".equals(format) || "text".equals(format)) {
- HDF hdf = buildHelpHdf();
- CS clearsilver = new CS(hdf);
- // Set a custom file loader to load requested files from resources relative to this class.
- clearsilver.setFileLoader(new CSFileLoader() {
- public String load(HDF hdf, String filename) throws IOException {
- return Resources.toString(Resources.getResource(MonkeyRunnerHelp.class, filename),
- Charset.defaultCharset());
- }
- });
-
- // Load up the CS template file
- clearsilver.parseFile(format.toLowerCase() + ".cs");
- // And render the output
- return clearsilver.render();
- } else if ("hdf".equals(format)) {
- HDF hdf = buildHelpHdf();
- return hdf.writeString();
- }
- return "";
- }
-
- private static HDF buildHelpHdf() {
- HDF hdf = new HDF();
-
- int outputItemCount = 0;
-
- Set<Field> fields = Sets.newTreeSet(MEMBER_SORTER);
- Set<Method> methods = Sets.newTreeSet(MEMBER_SORTER);
- Set<Constructor<?>> constructors = Sets.newTreeSet(MEMBER_SORTER);
- Set<Class<?>> classes = Sets.newTreeSet(CLASS_SORTER);
- getAllExportedClasses(fields, methods, constructors, classes);
-
- for (Class<?> clz : classes) {
- String prefix = HELP + "." + outputItemCount + ".";
-
- hdf.setValue(prefix + NAME, clz.getCanonicalName());
- MonkeyRunnerExported annotation = clz.getAnnotation(MonkeyRunnerExported.class);
- hdf.setValue(prefix + DOC, annotation.doc());
- hdf.setValue(prefix + TYPE, Type.ENUM.name());
-
- // Now go through the enumeration constants
- Object[] constants = clz.getEnumConstants();
- String[] argDocs = annotation.argDocs();
- if (constants.length > 0) {
- for (int x = 0; x < constants.length; x++) {
- String argPrefix = prefix + ARGUMENT + "." + x + ".";
- hdf.setValue(argPrefix + NAME, constants[x].toString());
- if (argDocs.length > x) {
- hdf.setValue(argPrefix + DOC, argDocs[x]);
- }
- }
- }
- outputItemCount++;
- }
-
- for (Method m : methods) {
- String prefix = HELP + "." + outputItemCount + ".";
-
- MonkeyRunnerExported annotation = m.getAnnotation(MonkeyRunnerExported.class);
- String className = m.getDeclaringClass().getCanonicalName();
- String methodName = className + "." + m.getName();
- hdf.setValue(prefix + NAME, methodName);
- hdf.setValue(prefix + DOC, annotation.doc());
- if (annotation.args().length > 0) {
- String[] argDocs = annotation.argDocs();
- String[] aargs = annotation.args();
- for (int x = 0; x < aargs.length; x++) {
- String argPrefix = prefix + ARGUMENT + "." + x + ".";
-
- hdf.setValue(argPrefix + NAME, aargs[x]);
- if (argDocs.length > x) {
- hdf.setValue(argPrefix + DOC, argDocs[x]);
- }
- }
- }
- if (!"".equals(annotation.returns())) {
- hdf.setValue(prefix + RETURNS, annotation.returns());
- }
- outputItemCount++;
- }
-
- return hdf;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.collect.ImmutableList;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class MonkeyRunnerOptions {
- private static final Logger LOG = Logger.getLogger(MonkeyRunnerOptions.class.getName());
- private static String DEFAULT_MONKEY_SERVER_ADDRESS = "127.0.0.1";
- private static int DEFAULT_MONKEY_PORT = 12345;
-
- private final int port;
- private final String hostname;
- private final File scriptFile;
- private final String backend;
- private final Collection<File> plugins;
- private final Collection<String> arguments;
-
- private MonkeyRunnerOptions(String hostname, int port, File scriptFile, String backend,
- Collection<File> plugins, Collection<String> arguments) {
- this.hostname = hostname;
- this.port = port;
- this.scriptFile = scriptFile;
- this.backend = backend;
- this.plugins = plugins;
- this.arguments = arguments;
- }
-
- public int getPort() {
- return port;
- }
-
- public String getHostname() {
- return hostname;
- }
-
- public File getScriptFile() {
- return scriptFile;
- }
-
- public String getBackendName() {
- return backend;
- }
-
- public Collection<File> getPlugins() {
- return plugins;
- }
-
- public Collection<String> getArguments() {
- return arguments;
- }
-
- private static void printUsage(String message) {
- 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("");
- }
-
- /**
- * Process the command-line options
- *
- * @return the parsed options, or null if there was an error.
- */
- public static MonkeyRunnerOptions processOptions(String[] args) {
- // parse command line parameters.
- int index = 0;
-
- String hostname = DEFAULT_MONKEY_SERVER_ADDRESS;
- File scriptFile = null;
- int port = DEFAULT_MONKEY_PORT;
- String backend = "adb";
-
- ImmutableList.Builder<File> pluginListBuilder = ImmutableList.builder();
- ImmutableList.Builder<String> argumentBuilder = ImmutableList.builder();
- while (index < args.length) {
- String argument = args[index++];
-
- if ("-s".equals(argument)) {
- if (index == args.length) {
- printUsage("Missing Server after -s");
- return null;
- }
- hostname = args[index++];
-
- } else if ("-p".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsage("Missing Server port after -p");
- return null;
- }
- port = Integer.parseInt(args[index++]);
-
- } else if ("-v".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsage("Missing Log Level after -v");
- return null;
- }
-
- Level level = Level.parse(args[index++]);
- LOG.setLevel(level);
- level = LOG.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 ("-be".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsage("Missing backend name after -be");
- return null;
- }
- backend = args[index++];
- } else if ("-plugin".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsage("Missing plugin path after -plugin");
- return null;
- }
- File plugin = new File(args[index++]);
- if (!plugin.exists()) {
- printUsage("Plugin file doesn't exist");
- return null;
- }
-
- if (!plugin.canRead()) {
- printUsage("Can't read plugin file");
- return null;
- }
-
- pluginListBuilder.add(plugin);
- } else if (argument.startsWith("-") &&
- // Once we have the scriptfile, the rest of the arguments go to jython.
- scriptFile == null) {
- // we have an unrecognized argument.
- printUsage("Unrecognized argument: " + argument + ".");
- return null;
- } else {
- if (scriptFile == null) {
- // get the filepath of the script to run. This will be the last undashed argument.
- scriptFile = new File(argument);
- if (!scriptFile.exists()) {
- printUsage("Can't open specified script file");
- return null;
- }
- if (!scriptFile.canRead()) {
- printUsage("Can't open specified script file");
- return null;
- }
- } else {
- argumentBuilder.add(argument);
- }
- }
- };
-
- return new MonkeyRunnerOptions(hostname, port, scriptFile, backend,
- pluginListBuilder.build(), argumentBuilder.build());
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-
-import com.android.monkeyrunner.adb.AdbBackend;
-import com.android.monkeyrunner.stub.StubBackend;
-
-import org.python.util.PythonInterpreter;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.logging.Formatter;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-
-/**
- * MonkeyRunner is a host side application to control a monkey instance on a
- * device. MonkeyRunner provides some useful helper functions to control the
- * device as well as various other methods to help script tests. This class bootstraps
- * MonkeyRunner.
- */
-public class MonkeyRunnerStarter {
- private static final Logger LOG = Logger.getLogger(MonkeyRunnerStarter.class.getName());
- private static final String MONKEY_RUNNER_MAIN_MANIFEST_NAME = "MonkeyRunnerStartupRunner";
-
- private final MonkeyRunnerBackend backend;
- private final MonkeyRunnerOptions options;
-
- public MonkeyRunnerStarter(MonkeyRunnerOptions options) {
- this.options = options;
- this.backend = MonkeyRunnerStarter.createBackendByName(options.getBackendName());
- if (this.backend == null) {
- throw new RuntimeException("Unknown backend");
- }
- }
-
-
- /**
- * Creates a specific backend by name.
- *
- * @param backendName the name of the backend to create
- * @return the new backend, or null if none were found.
- */
- public static MonkeyRunnerBackend createBackendByName(String backendName) {
- if ("adb".equals(backendName)) {
- return new AdbBackend();
- } else if ("stub".equals(backendName)) {
- return new StubBackend();
- } else {
- return null;
- }
- }
-
- private int run() {
- MonkeyRunner.setBackend(backend);
- Map<String, Predicate<PythonInterpreter>> plugins = handlePlugins();
- if (options.getScriptFile() == null) {
- ScriptRunner.console();
- return 0;
- } else {
- int error = ScriptRunner.run(options.getScriptFile().getAbsolutePath(),
- options.getArguments(), plugins);
- backend.shutdown();
- MonkeyRunner.setBackend(null);
- return error;
- }
- }
-
- private Predicate<PythonInterpreter> handlePlugin(File f) {
- JarFile jarFile;
- try {
- jarFile = new JarFile(f);
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to open plugin file. Is it a jar file? " +
- f.getAbsolutePath(), e);
- return Predicates.alwaysFalse();
- }
- Manifest manifest;
- try {
- manifest = jarFile.getManifest();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to get manifest file from jar: " +
- f.getAbsolutePath(), e);
- return Predicates.alwaysFalse();
- }
- Attributes mainAttributes = manifest.getMainAttributes();
- String pluginClass = mainAttributes.getValue(MONKEY_RUNNER_MAIN_MANIFEST_NAME);
- if (pluginClass == null) {
- // No main in this plugin, so it always succeeds.
- return Predicates.alwaysTrue();
- }
- URL url;
- try {
- url = f.toURI().toURL();
- } catch (MalformedURLException e) {
- LOG.log(Level.SEVERE, "Unable to convert file to url " + f.getAbsolutePath(),
- e);
- return Predicates.alwaysFalse();
- }
- URLClassLoader classLoader = new URLClassLoader(new URL[] { url },
- ClassLoader.getSystemClassLoader());
- Class<?> clz;
- try {
- clz = Class.forName(pluginClass, true, classLoader);
- } catch (ClassNotFoundException e) {
- LOG.log(Level.SEVERE, "Unable to load the specified plugin: " + pluginClass, e);
- return Predicates.alwaysFalse();
- }
- Object loadedObject;
- try {
- loadedObject = clz.newInstance();
- } catch (InstantiationException e) {
- LOG.log(Level.SEVERE, "Unable to load the specified plugin: " + pluginClass, e);
- return Predicates.alwaysFalse();
- } catch (IllegalAccessException e) {
- LOG.log(Level.SEVERE, "Unable to load the specified plugin " +
- "(did you make it public?): " + pluginClass, e);
- return Predicates.alwaysFalse();
- }
- // Cast it to the right type
- if (loadedObject instanceof Runnable) {
- final Runnable run = (Runnable) loadedObject;
- return new Predicate<PythonInterpreter>() {
- public boolean apply(PythonInterpreter i) {
- run.run();
- return true;
- }
- };
- } else if (loadedObject instanceof Predicate<?>) {
- return (Predicate<PythonInterpreter>) loadedObject;
- } else {
- LOG.severe("Unable to coerce object into correct type: " + pluginClass);
- return Predicates.alwaysFalse();
- }
- }
-
- private Map<String, Predicate<PythonInterpreter>> handlePlugins() {
- ImmutableMap.Builder<String, Predicate<PythonInterpreter>> builder = ImmutableMap.builder();
- for (File f : options.getPlugins()) {
- builder.put(f.getAbsolutePath(), handlePlugin(f));
- }
- return builder.build();
- }
-
-
-
- private static final void replaceAllLogFormatters(Formatter form) {
- LogManager mgr = LogManager.getLogManager();
- Enumeration<String> loggerNames = mgr.getLoggerNames();
- while (loggerNames.hasMoreElements()) {
- String loggerName = loggerNames.nextElement();
- Logger logger = mgr.getLogger(loggerName);
- for (Handler handler : logger.getHandlers()) {
- handler.setFormatter(form);
- handler.setLevel(Level.INFO);
- }
- }
- }
-
- public static void main(String[] args) {
- MonkeyRunnerOptions options = MonkeyRunnerOptions.processOptions(args);
-
- // logging property files are difficult
- replaceAllLogFormatters(MonkeyFormatter.DEFAULT_INSTANCE);
-
- if (options == null) {
- return;
- }
-
- MonkeyRunnerStarter runner = new MonkeyRunnerStarter(options);
- int error = runner.run();
-
- // This will kill any background threads as well.
- System.exit(error);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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;
-
-public enum PhysicalButton {
- HOME("home"),
- SEARCH("search"),
- MENU("menu"),
- BACK("back"),
- DPAD_UP("DPAD_UP"),
- DPAD_DOWN("DPAD_DOWN"),
- DPAD_LEFT("DPAD_LEFT"),
- DPAD_RIGHT("DPAD_RIGHT"),
- DPAD_CENTER("DPAD_CENTER"),
- ENTER("enter");
-
- private String keyName;
-
- private PhysicalButton(String keyName) {
- this.keyName = keyName;
- }
-
- public String getKeyName() {
- return keyName;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.ImmutableMap.Builder;
-
-import org.python.core.Py;
-import org.python.core.PyException;
-import org.python.core.PyObject;
-import org.python.util.InteractiveConsole;
-import org.python.util.JLineConsole;
-import org.python.util.PythonInterpreter;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-
-/**
- * Runs Jython based scripts.
- */
-public class ScriptRunner {
- private static final Logger LOG = Logger.getLogger(MonkeyRunnerOptions.class.getName());
-
- /** The "this" scope object for scripts. */
- private final Object scope;
- private final String variable;
-
- /** Private constructor. */
- private ScriptRunner(Object scope, String variable) {
- this.scope = scope;
- this.variable = variable;
- }
-
- /** Creates a new instance for the given scope object. */
- public static ScriptRunner newInstance(Object scope, String variable) {
- return new ScriptRunner(scope, variable);
- }
-
- /**
- * Runs the specified Jython script. First runs the initialization script to
- * preload the appropriate client library version.
- *
- * @param scriptfilename the name of the file to run.
- * @param args the arguments passed in (excluding the filename).
- * @param plugins a list of plugins to load.
- * @return the error code from running the script.
- */
- public static int run(String scriptfilename, Collection<String> args,
- Map<String, Predicate<PythonInterpreter>> plugins) {
- // Add the current directory of the script to the python.path search path.
- File f = new File(scriptfilename);
-
- // Adjust the classpath so jython can access the classes in the specified classpath.
- Collection<String> classpath = Lists.newArrayList(f.getParent());
- classpath.addAll(plugins.keySet());
-
- String[] argv = new String[args.size() + 1];
- argv[0] = f.getAbsolutePath();
- int x = 1;
- for (String arg : args) {
- argv[x++] = arg;
- }
-
- initPython(classpath, argv);
-
- PythonInterpreter python = new PythonInterpreter();
-
- // Now let the mains run.
- for (Map.Entry<String, Predicate<PythonInterpreter>> entry : plugins.entrySet()) {
- boolean success;
- try {
- success = entry.getValue().apply(python);
- } catch (Exception e) {
- LOG.log(Level.SEVERE, "Plugin Main through an exception.", e);
- continue;
- }
- if (!success) {
- LOG.severe("Plugin Main returned error for: " + entry.getKey());
- }
- }
-
- // Bind __name__ to __main__ so mains will run
- python.set("__name__", "__main__");
-
- try {
- python.execfile(scriptfilename);
- } catch (PyException e) {
- if (Py.SystemExit.equals(e.type)) {
- // Then recover the error code so we can pass it on
- return (Integer) e.value.__tojava__(Integer.class);
- }
- // Then some other kind of exception was thrown. Log it and return error;
- LOG.log(Level.SEVERE, "Script terminated due to an exception", e);
- return 1;
- }
- return 0;
- }
-
- public static void runString(String script) {
- initPython();
- PythonInterpreter python = new PythonInterpreter();
- python.exec(script);
- }
-
- public static Map<String, PyObject> runStringAndGet(String script, String... names) {
- return runStringAndGet(script, Arrays.asList(names));
- }
-
- public static Map<String, PyObject> runStringAndGet(String script, Collection<String> names) {
- initPython();
- final PythonInterpreter python = new PythonInterpreter();
- python.exec(script);
-
- Builder<String, PyObject> builder = ImmutableMap.builder();
- for (String name : names) {
- builder.put(name, python.get(name));
- }
- return builder.build();
- }
-
- private static void initPython() {
- List<String> arg = Collections.emptyList();
- initPython(arg, new String[] {""});
- }
-
- private static void initPython(Collection<String> pythonPath,
- String[] argv) {
- Properties props = new Properties();
-
- // Build up the python.path
- StringBuilder sb = new StringBuilder();
- sb.append(System.getProperty("java.class.path"));
- for (String p : pythonPath) {
- sb.append(":").append(p);
- }
- props.setProperty("python.path", sb.toString());
-
- /** Initialize the python interpreter. */
- // Default is 'message' which displays sys-package-mgr bloat
- // Choose one of error,warning,message,comment,debug
- props.setProperty("python.verbose", "error");
-
- PythonInterpreter.initialize(System.getProperties(), props, argv);
- }
-
- /**
- * Start an interactive python interpreter.
- */
- public static void console() {
- initPython();
- InteractiveConsole python = new JLineConsole();
- python.interact();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-import com.google.common.collect.Lists;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.monkeyrunner.MonkeyDevice;
-import com.android.monkeyrunner.MonkeyRunnerBackend;
-
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Pattern;
-
-/**
- * Backend implementation that works over ADB to talk to the device.
- */
-public class AdbBackend implements MonkeyRunnerBackend {
- private static Logger LOG = Logger.getLogger(AdbBackend.class.getCanonicalName());
- // How long to wait each time we check for the device to be connected.
- private static final int CONNECTION_ITERATION_TIMEOUT_MS = 200;
- private final List<AdbMonkeyDevice> devices = Lists.newArrayList();
-
- private final AndroidDebugBridge bridge;
-
- public AdbBackend() {
- AndroidDebugBridge.init(false /* debugger support */);
-
- bridge = AndroidDebugBridge.createBridge(
- "adb", true /* forceNewBridge */);
- }
-
- /**
- * Checks the attached devices looking for one whose device id matches the specified regex.
- *
- * @param deviceIdRegex the regular expression to match against
- * @return the Device (if found), or null (if not found).
- */
- private IDevice findAttacedDevice(String deviceIdRegex) {
- Pattern pattern = Pattern.compile(deviceIdRegex);
- for (IDevice device : bridge.getDevices()) {
- String serialNumber = device.getSerialNumber();
- if (pattern.matcher(serialNumber).matches()) {
- return device;
- }
- }
- return null;
- }
-
- public MonkeyDevice waitForConnection() {
- return waitForConnection(Integer.MAX_VALUE, ".*");
- }
-
- public MonkeyDevice waitForConnection(long timeoutMs, String deviceIdRegex) {
- do {
- IDevice device = findAttacedDevice(deviceIdRegex);
- if (device != null) {
- AdbMonkeyDevice amd = new AdbMonkeyDevice(device);
- devices.add(amd);
- return amd;
- }
-
- try {
- Thread.sleep(CONNECTION_ITERATION_TIMEOUT_MS);
- } catch (InterruptedException e) {
- LOG.log(Level.SEVERE, "Error sleeping", e);
- }
- timeoutMs -= CONNECTION_ITERATION_TIMEOUT_MS;
- } while (timeoutMs > 0);
-
- // Timeout. Give up.
- return null;
- }
-
- public void shutdown() {
- for (AdbMonkeyDevice device : devices) {
- device.dispose();
- }
- AndroidDebugBridge.terminate();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.InstallException;
-import com.android.ddmlib.ShellCommandUnresponsiveException;
-import com.android.ddmlib.TimeoutException;
-import com.android.ddmlib.AdbCommandRejectedException;
-import com.android.monkeyrunner.MonkeyDevice;
-import com.android.monkeyrunner.MonkeyImage;
-import com.android.monkeyrunner.MonkeyManager;
-import com.android.monkeyrunner.adb.LinearInterpolator.Point;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
-
-public class AdbMonkeyDevice extends MonkeyDevice {
- private static final Logger LOG = Logger.getLogger(AdbMonkeyDevice.class.getName());
-
- private static final String[] ZERO_LENGTH_STRING_ARRAY = new String[0];
- private static final long MANAGER_CREATE_TIMEOUT_MS = 5 * 1000; // 5 seconds
-
- private final ExecutorService executor = Executors.newCachedThreadPool();
-
- private final IDevice device;
- private MonkeyManager manager;
-
- public AdbMonkeyDevice(IDevice device) {
- this.device = device;
- this.manager = createManager("127.0.0.1", 12345);
-
- Preconditions.checkNotNull(this.manager);
- }
-
- @Override
- public MonkeyManager getManager() {
- return manager;
- }
-
- @Override
- public void dispose() {
- try {
- manager.quit();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error getting the manager to quit", e);
- }
- manager = null;
- }
-
- private void executeAsyncCommand(final String command,
- final LoggingOutputReceiver logger) {
- executor.submit(new Runnable() {
- public void run() {
- try {
- device.executeShellCommand(command, logger);
- } catch (TimeoutException e) {
- LOG.log(Level.SEVERE, "Error starting command: " + command, e);
- throw new RuntimeException(e);
- } catch (AdbCommandRejectedException e) {
- LOG.log(Level.SEVERE, "Error starting command: " + command, e);
- throw new RuntimeException(e);
- } catch (ShellCommandUnresponsiveException e) {
- LOG.log(Level.SEVERE, "Error starting command: " + command, e);
- throw new RuntimeException(e);
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error starting command: " + command, e);
- throw new RuntimeException(e);
- }
- }
- });
- }
-
- private MonkeyManager createManager(String address, int port) {
- try {
- device.createForward(port, port);
- } catch (TimeoutException e) {
- LOG.log(Level.SEVERE, "Timeout creating adb port forwarding", e);
- return null;
- } catch (AdbCommandRejectedException e) {
- LOG.log(Level.SEVERE, "Adb rejected adb port forwarding command: " + e.getMessage(), e);
- return null;
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to create adb port forwarding: " + e.getMessage(), e);
- return null;
- }
-
- String command = "monkey --port " + port;
- executeAsyncCommand(command, new LoggingOutputReceiver(LOG, Level.FINE));
-
- // Sleep for a second to give the command time to execute.
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- LOG.log(Level.SEVERE, "Unable to sleep", e);
- }
-
- InetAddress addr;
- try {
- addr = InetAddress.getByName(address);
- } catch (UnknownHostException e) {
- LOG.log(Level.SEVERE, "Unable to convert address into InetAddress: " + address, e);
- return null;
- }
-
- // We have a tough problem to solve here. "monkey" on the device gives us no indication
- // when it has started up and is ready to serve traffic. If you try too soon, commands
- // will fail. To remedy this, we will keep trying until a single command (in this case,
- // wake) succeeds.
- boolean success = false;
- MonkeyManager mm = null;
- long start = System.currentTimeMillis();
-
- while (!success) {
- long now = System.currentTimeMillis();
- long diff = now - start;
- if (diff > MANAGER_CREATE_TIMEOUT_MS) {
- LOG.severe("Timeout while trying to create monkey mananger");
- return null;
- }
-
- Socket monkeySocket;
- try {
- monkeySocket = new Socket(addr, port);
- } catch (IOException e) {
- LOG.log(Level.FINE, "Unable to connect socket", e);
- success = false;
- continue;
- }
-
- mm = new MonkeyManager(monkeySocket);
-
- try {
- mm.wake();
- } catch (IOException e) {
- LOG.log(Level.FINE, "Unable to wake up device", e);
- success = false;
- continue;
- }
- success = true;
- }
-
- return mm;
- }
-
- @Override
- public MonkeyImage takeSnapshot() {
- try {
- return new AdbMonkeyImage(device.getScreenshot());
- } catch (TimeoutException e) {
- LOG.log(Level.SEVERE, "Unable to take snapshot", e);
- return null;
- } catch (AdbCommandRejectedException e) {
- LOG.log(Level.SEVERE, "Unable to take snapshot", e);
- return null;
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to take snapshot", e);
- return null;
- }
- }
-
- @Override
- protected String getSystemProperty(String key) {
- return device.getProperty(key);
- }
-
- @Override
- protected String getProperty(String key) {
- try {
- return manager.getVariable(key);
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to get variable: " + key, e);
- return null;
- }
- }
-
- @Override
- protected void wake() {
- try {
- manager.wake();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to wake device (too sleepy?)", e);
- }
- }
-
- private String shell(String... args) {
- StringBuilder cmd = new StringBuilder();
- for (String arg : args) {
- cmd.append(arg).append(" ");
- }
- return shell(cmd.toString());
- }
-
- @Override
- protected String shell(String cmd) {
- CommandOutputCapture capture = new CommandOutputCapture();
- try {
- device.executeShellCommand(cmd, capture);
- } catch (TimeoutException e) {
- LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
- return null;
- } catch (ShellCommandUnresponsiveException e) {
- LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
- return null;
- } catch (AdbCommandRejectedException e) {
- LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
- return null;
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
- return null;
- }
- return capture.toString();
- }
-
- @Override
- protected boolean installPackage(String path) {
- try {
- String result = device.installPackage(path, true);
- if (result != null) {
- LOG.log(Level.SEVERE, "Got error installing package: "+ result);
- return false;
- }
- return true;
- } catch (InstallException e) {
- LOG.log(Level.SEVERE, "Error installing package: " + path, e);
- return false;
- }
- }
-
- @Override
- protected boolean removePackage(String packageName) {
- try {
- String result = device.uninstallPackage(packageName);
- if (result != null) {
- LOG.log(Level.SEVERE, "Got error uninstalling package "+ packageName + ": " +
- result);
- return false;
- }
- return true;
- } catch (InstallException e) {
- LOG.log(Level.SEVERE, "Error installing package: " + packageName, e);
- return false;
- }
- }
-
- @Override
- protected void press(String keyName, TouchPressType type) {
- try {
- switch (type) {
- case DOWN_AND_UP:
- manager.press(keyName);
- break;
- case DOWN:
- manager.keyDown(keyName);
- break;
- case UP:
- manager.keyUp(keyName);
- break;
- }
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error sending press event: " + keyName + " " + type, e);
- }
- }
-
- @Override
- protected void type(String string) {
- try {
- manager.type(string);
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error Typing: " + string, e);
- }
- }
-
- @Override
- protected void touch(int x, int y, TouchPressType type) {
- try {
- switch (type) {
- case DOWN:
- manager.touchDown(x, y);
- break;
- case UP:
- manager.touchUp(x, y);
- break;
- case DOWN_AND_UP:
- manager.tap(x, y);
- break;
- }
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error sending touch event: " + x + " " + y + " " + type, e);
- }
- }
-
- @Override
- protected void reboot(String into) {
- try {
- device.reboot(into);
- } catch (TimeoutException e) {
- LOG.log(Level.SEVERE, "Unable to reboot device", e);
- } catch (AdbCommandRejectedException e) {
- LOG.log(Level.SEVERE, "Unable to reboot device", e);
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Unable to reboot device", e);
- }
- }
-
- @Override
- protected void startActivity(String uri, String action, String data, String mimetype,
- Collection<String> categories, Map<String, Object> extras, String component,
- int flags) {
- List<String> intentArgs = buildIntentArgString(uri, action, data, mimetype, categories,
- extras, component, flags);
- shell(Lists.asList("am", "start",
- intentArgs.toArray(ZERO_LENGTH_STRING_ARRAY)).toArray(ZERO_LENGTH_STRING_ARRAY));
- }
-
- @Override
- protected void broadcastIntent(String uri, String action, String data, String mimetype,
- Collection<String> categories, Map<String, Object> extras, String component,
- int flags) {
- List<String> intentArgs = buildIntentArgString(uri, action, data, mimetype, categories,
- extras, component, flags);
- shell(Lists.asList("am", "broadcast",
- intentArgs.toArray(ZERO_LENGTH_STRING_ARRAY)).toArray(ZERO_LENGTH_STRING_ARRAY));
- }
-
- private static boolean isNullOrEmpty(@Nullable String string) {
- return string == null || string.length() == 0;
- }
-
- private List<String> buildIntentArgString(String uri, String action, String data, String mimetype,
- Collection<String> categories, Map<String, Object> extras, String component,
- int flags) {
- List<String> parts = Lists.newArrayList();
-
- // from adb docs:
- //<INTENT> specifications include these flags:
- // [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
- // [-c <CATEGORY> [-c <CATEGORY>] ...]
- // [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
- // [--esn <EXTRA_KEY> ...]
- // [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
- // [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
- // [-n <COMPONENT>] [-f <FLAGS>]
- // [<URI>]
-
- if (!isNullOrEmpty(action)) {
- parts.add("-a");
- parts.add(action);
- }
-
- if (!isNullOrEmpty(data)) {
- parts.add("-d");
- parts.add(data);
- }
-
- if (!isNullOrEmpty(mimetype)) {
- parts.add("-t");
- parts.add(mimetype);
- }
-
- // Handle categories
- for (String category : categories) {
- parts.add("-c");
- parts.add(category);
- }
-
- // Handle extras
- for (Entry<String, Object> entry : extras.entrySet()) {
- // Extras are either boolean, string, or int. See which we have
- Object value = entry.getValue();
- String valueString;
- String arg;
- if (value instanceof Integer) {
- valueString = Integer.toString((Integer) value);
- arg = "--ei";
- } else if (value instanceof Boolean) {
- valueString = Boolean.toString((Boolean) value);
- arg = "--ez";
- } else {
- // treat is as a string.
- valueString = value.toString();
- arg = "--esmake";
- }
- parts.add(arg);
- parts.add(valueString);
- }
-
- if (!isNullOrEmpty(component)) {
- parts.add("-n");
- parts.add(component);
- }
-
- if (flags != 0) {
- parts.add("-f");
- parts.add(Integer.toString(flags));
- }
-
- if (!isNullOrEmpty(uri)) {
- parts.add(uri);
- }
-
- return parts;
- }
-
- @Override
- protected Map<String, Object> instrument(String packageName, Map<String, Object> args) {
- List<String> shellCmd = Lists.newArrayList("am", "instrument", "-w", "-r", packageName);
- String result = shell(shellCmd.toArray(ZERO_LENGTH_STRING_ARRAY));
- return convertInstrumentResult(result);
- }
-
- /**
- * Convert the instrumentation result into it's Map representation.
- *
- * @param result the result string
- * @return the new map
- */
- @VisibleForTesting
- /* package */ static Map<String, Object> convertInstrumentResult(String result) {
- Map<String, Object> map = Maps.newHashMap();
- Pattern pattern = Pattern.compile("^INSTRUMENTATION_(\\w+): ", Pattern.MULTILINE);
- Matcher matcher = pattern.matcher(result);
-
- int previousEnd = 0;
- String previousWhich = null;
-
- while (matcher.find()) {
- if ("RESULT".equals(previousWhich)) {
- String resultLine = result.substring(previousEnd, matcher.start()).trim();
- // Look for the = in the value, and split there
- int splitIndex = resultLine.indexOf("=");
- String key = resultLine.substring(0, splitIndex);
- String value = resultLine.substring(splitIndex + 1);
-
- map.put(key, value);
- }
-
- previousEnd = matcher.end();
- previousWhich = matcher.group(1);
- }
- if ("RESULT".equals(previousWhich)) {
- String resultLine = result.substring(previousEnd, matcher.start()).trim();
- // Look for the = in the value, and split there
- int splitIndex = resultLine.indexOf("=");
- String key = resultLine.substring(0, splitIndex);
- String value = resultLine.substring(splitIndex + 1);
-
- map.put(key, value);
- }
- return map;
- }
-
- @Override
- protected void drag(int startx, int starty, int endx, int endy, int steps, long ms) {
- final long iterationTime = ms / steps;
-
- LinearInterpolator lerp = new LinearInterpolator(steps);
- LinearInterpolator.Point start = new LinearInterpolator.Point(startx, starty);
- LinearInterpolator.Point end = new LinearInterpolator.Point(endx, endy);
- lerp.interpolate(start, end, new LinearInterpolator.Callback() {
- public void step(Point point) {
- try {
- manager.touchMove(point.getX(), point.getY());
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error sending drag start event", e);
- }
-
- try {
- Thread.sleep(iterationTime);
- } catch (InterruptedException e) {
- LOG.log(Level.SEVERE, "Error sleeping", e);
- }
- }
-
- public void start(Point point) {
- try {
- manager.touchDown(point.getX(), point.getY());
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error sending drag start event", e);
- }
-
- try {
- Thread.sleep(iterationTime);
- } catch (InterruptedException e) {
- LOG.log(Level.SEVERE, "Error sleeping", e);
- }
- }
-
- public void end(Point point) {
- try {
- manager.touchUp(point.getX(), point.getY());
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error sending drag end event", e);
- }
- }
- });
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-import com.android.ddmlib.RawImage;
-import com.android.monkeyrunner.MonkeyImage;
-import com.android.monkeyrunner.adb.image.ImageUtils;
-
-import java.awt.image.BufferedImage;
-
-/**
- * ADB implementation of the MonkeyImage class.
- */
-public class AdbMonkeyImage extends MonkeyImage {
- private final RawImage image;
-
- /**
- * Create a new AdbMonkeyImage.
- *
- * @param image the image from adb.
- */
- AdbMonkeyImage(RawImage image) {
- this.image = image;
- }
-
- @Override
- public BufferedImage createBufferedImage() {
- return ImageUtils.convertImage(image);
- }
-
- public RawImage getRawImage() {
- return image;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-import com.android.ddmlib.IShellOutputReceiver;
-
-/**
- * Shell Output Receiver that captures shell output into a String for
- * later retrieval.
- */
-public class CommandOutputCapture implements IShellOutputReceiver {
- private final StringBuilder builder = new StringBuilder();
-
- public void flush() { }
-
- public boolean isCancelled() {
- return false;
- }
-
- public void addOutput(byte[] data, int offset, int length) {
- String message = new String(data, offset, length);
- builder.append(message);
- }
-
- @Override
- public String toString() {
- return builder.toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-
-
-/**
- * Linear Interpolation class.
- */
-public class LinearInterpolator {
- private final int steps;
-
- /**
- * Use our own Point class so we don't pull in java.awt.* just for this simple class.
- */
- public static class Point {
- private final int x;
- private final int y;
-
- public Point(int x, int y) {
- this.x = x;
- this.y = y;
- }
-
- @Override
- public String toString() {
- return new StringBuilder().
- append("(").
- append(x).
- append(",").
- append(y).
- append(")").toString();
- }
-
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Point) {
- Point that = (Point) obj;
- return this.x == that.x && this.y == that.y;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return 0x43125315 + x + y;
- }
-
- public int getX() {
- return x;
- }
-
- public int getY() {
- return y;
- }
- }
-
- /**
- * Callback interface to recieve interpolated points.
- */
- public interface Callback {
- /**
- * Called once to inform of the start point.
- */
- void start(Point point);
- /**
- * Called once to inform of the end point.
- */
- void end(Point point);
- /**
- * Called at every step in-between start and end.
- */
- void step(Point point);
- }
-
- /**
- * Create a new linear Interpolator.
- *
- * @param steps How many steps should be in a single run. This counts the intervals
- * in-between points, so the actual number of points generated will be steps + 1.
- */
- public LinearInterpolator(int steps) {
- this.steps = steps;
- }
-
- // Copied from android.util.MathUtils since we couldn't link it in on the host.
- private static float lerp(float start, float stop, float amount) {
- return start + (stop - start) * amount;
- }
-
- /**
- * Calculate the interpolated points.
- *
- * @param start The starting point
- * @param end The ending point
- * @param callback the callback to call with each calculated points.
- */
- public void interpolate(Point start, Point end, Callback callback) {
- int xDistance = Math.abs(end.getX() - start.getX());
- int yDistance = Math.abs(end.getY() - start.getY());
- float amount = (float) (1.0 / steps);
-
-
- callback.start(start);
- for (int i = 1; i < steps; i++) {
- float newX = lerp(start.getX(), end.getX(), amount * i);
- float newY = lerp(start.getY(), end.getY(), amount * i);
-
- callback.step(new Point(Math.round(newX), Math.round(newY)));
- }
- // Generate final point
- callback.end(end);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-import com.android.ddmlib.IShellOutputReceiver;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Shell Output Receiver that sends shell output to a Logger.
- */
-public class LoggingOutputReceiver implements IShellOutputReceiver {
- private final Logger log;
- private final Level level;
-
- public LoggingOutputReceiver(Logger log, Level level) {
- this.log = log;
- this.level = level;
- }
-
- public void addOutput(byte[] data, int offset, int length) {
- String message = new String(data, offset, length);
- for (String line : message.split("\n")) {
- log.log(level, line);
- }
- }
-
- public void flush() { }
-
- public boolean isCancelled() {
- return false;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb.image;
-
-import com.android.ddmlib.RawImage;
-import com.android.monkeyrunner.MonkeyDevice;
-import com.android.monkeyrunner.adb.AdbBackend;
-import com.android.monkeyrunner.adb.AdbMonkeyImage;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-/**
- * Utility program to capture raw and converted images from a device and write them to a file.
- * This is used to generate the test data for ImageUtilsTest.
- */
-public class CaptureRawAndConvertedImage {
- public static class MonkeyRunnerRawImage implements Serializable {
- public int version;
- public int bpp;
- public int size;
- public int width;
- public int height;
- public int red_offset;
- public int red_length;
- public int blue_offset;
- public int blue_length;
- public int green_offset;
- public int green_length;
- public int alpha_offset;
- public int alpha_length;
-
- public byte[] data;
-
- public MonkeyRunnerRawImage(RawImage rawImage) {
- version = rawImage.version;
- bpp = rawImage.bpp;
- size = rawImage.size;
- width = rawImage.width;
- height = rawImage.height;
- red_offset = rawImage.red_offset;
- red_length = rawImage.red_length;
- blue_offset = rawImage.blue_offset;
- blue_length = rawImage.blue_length;
- green_offset = rawImage.green_offset;
- green_length = rawImage.green_length;
- alpha_offset = rawImage.alpha_offset;
- alpha_length = rawImage.alpha_length;
-
- data = rawImage.data;
- }
-
- public RawImage toRawImage() {
- RawImage rawImage = new RawImage();
-
- rawImage.version = version;
- rawImage.bpp = bpp;
- rawImage.size = size;
- rawImage.width = width;
- rawImage.height = height;
- rawImage.red_offset = red_offset;
- rawImage.red_length = red_length;
- rawImage.blue_offset = blue_offset;
- rawImage.blue_length = blue_length;
- rawImage.green_offset = green_offset;
- rawImage.green_length = green_length;
- rawImage.alpha_offset = alpha_offset;
- rawImage.alpha_length = alpha_length;
-
- rawImage.data = data;
- return rawImage;
- }
- }
-
- private static void writeOutImage(RawImage screenshot, String name) throws IOException {
- ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(name));
- out.writeObject(new MonkeyRunnerRawImage(screenshot));
- out.close();
- }
-
- public static void main(String[] args) throws IOException {
- AdbBackend backend = new AdbBackend();
- MonkeyDevice device = backend.waitForConnection();
- AdbMonkeyImage snapshot = (AdbMonkeyImage) device.takeSnapshot();
-
- // write out to a file
- snapshot.writeToFile("output.png", "png");
- writeOutImage(snapshot.getRawImage(), "output.raw");
- System.exit(0);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb.image;
-
-import com.android.ddmlib.RawImage;
-
-import java.awt.Point;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.PixelInterleavedSampleModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.util.Hashtable;
-/**
- * Useful image related functions.
- */
-public class ImageUtils {
- // Utility class
- private ImageUtils() { }
-
- private static Hashtable<?,?> EMPTY_HASH = new Hashtable();
- private static int[] BAND_OFFSETS_32 = { 0, 1, 2, 3 };
- private static int[] BAND_OFFSETS_16 = { 0, 1 };
-
- /**
- * Convert a raw image into a buffered image.
- *
- * @param rawImage the raw image to convert
- * @param image the old image to (possibly) recycle
- * @return the converted image
- */
- public static BufferedImage convertImage(RawImage rawImage, BufferedImage image) {
- switch (rawImage.bpp) {
- case 16:
- return rawImage16toARGB(image, rawImage);
- case 32:
- return rawImage32toARGB(rawImage);
- }
- return null;
- }
-
- /**
- * Convert a raw image into a buffered image.
- *
- * @param rawImage the image to convert.
- * @return the converted image.
- */
- public static BufferedImage convertImage(RawImage rawImage) {
- return convertImage(rawImage, null);
- }
-
- static int getMask(int length) {
- int res = 0;
- for (int i = 0 ; i < length ; i++) {
- res = (res << 1) + 1;
- }
-
- return res;
- }
-
- private static BufferedImage rawImage32toARGB(RawImage rawImage) {
- // Do as much as we can to not make an extra copy of the data. This is just a bunch of
- // classes that wrap's the raw byte array of the image data.
- DataBufferByte dataBuffer = new DataBufferByte(rawImage.data, rawImage.size);
-
- PixelInterleavedSampleModel sampleModel =
- new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, rawImage.width, rawImage.height,
- 4, rawImage.width * 4, BAND_OFFSETS_32);
- WritableRaster raster = Raster.createWritableRaster(sampleModel, dataBuffer,
- new Point(0, 0));
- return new BufferedImage(new ThirtyTwoBitColorModel(rawImage), raster, false, EMPTY_HASH);
- }
-
- private static BufferedImage rawImage16toARGB(BufferedImage image, RawImage rawImage) {
- // Do as much as we can to not make an extra copy of the data. This is just a bunch of
- // classes that wrap's the raw byte array of the image data.
- DataBufferByte dataBuffer = new DataBufferByte(rawImage.data, rawImage.size);
-
- PixelInterleavedSampleModel sampleModel =
- new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, rawImage.width, rawImage.height,
- 2, rawImage.width * 2, BAND_OFFSETS_16);
- WritableRaster raster = Raster.createWritableRaster(sampleModel, dataBuffer,
- new Point(0, 0));
- return new BufferedImage(new SixteenBitColorModel(rawImage), raster, false, EMPTY_HASH);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb.image;
-
-import com.android.ddmlib.RawImage;
-
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-
-/**
- * Internal color model used to do conversion of 16bpp RawImages.
- */
-class SixteenBitColorModel extends ColorModel {
- private static final int[] BITS = {
- 8, 8, 8, 8
- };
- public SixteenBitColorModel(RawImage rawImage) {
- super(32
- , BITS, ColorSpace.getInstance(ColorSpace.CS_sRGB),
- true, false, Transparency.TRANSLUCENT,
- DataBuffer.TYPE_BYTE);
- }
-
- @Override
- public boolean isCompatibleRaster(Raster raster) {
- return true;
- }
-
- private int getPixel(Object inData) {
- byte[] data = (byte[]) inData;
- int value = data[0] & 0x00FF;
- value |= (data[1] << 8) & 0x0FF00;
-
- return value;
- }
-
- @Override
- public int getAlpha(Object inData) {
- return 0xff;
- }
-
- @Override
- public int getBlue(Object inData) {
- int pixel = getPixel(inData);
- return ((pixel >> 0) & 0x01F) << 3;
- }
-
- @Override
- public int getGreen(Object inData) {
- int pixel = getPixel(inData);
- return ((pixel >> 5) & 0x03F) << 2;
- }
-
- @Override
- public int getRed(Object inData) {
- int pixel = getPixel(inData);
- return ((pixel >> 11) & 0x01F) << 3;
- }
-
- @Override
- public int getAlpha(int pixel) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getBlue(int pixel) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getGreen(int pixel) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getRed(int pixel) {
- throw new UnsupportedOperationException();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb.image;
-
-import com.android.ddmlib.RawImage;
-
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-
-/**
- * Internal color model used to do conversion of 32bpp RawImages.
- */
-class ThirtyTwoBitColorModel extends ColorModel {
- private static final int[] BITS = {
- 8, 8, 8, 8,
- };
- private final int alphaLength;
- private final int alphaMask;
- private final int alphaOffset;
- private final int blueMask;
- private final int blueLength;
- private final int blueOffset;
- private final int greenMask;
- private final int greenLength;
- private final int greenOffset;
- private final int redMask;
- private final int redLength;
- private final int redOffset;
-
- public ThirtyTwoBitColorModel(RawImage rawImage) {
- super(32, BITS, ColorSpace.getInstance(ColorSpace.CS_sRGB),
- true, false, Transparency.TRANSLUCENT,
- DataBuffer.TYPE_BYTE);
-
- redOffset = rawImage.red_offset;
- redLength = rawImage.red_length;
- redMask = ImageUtils.getMask(redLength);
- greenOffset = rawImage.green_offset;
- greenLength = rawImage.green_length;
- greenMask = ImageUtils.getMask(greenLength);
- blueOffset = rawImage.blue_offset;
- blueLength = rawImage.blue_length;
- blueMask = ImageUtils.getMask(blueLength);
- alphaLength = rawImage.alpha_length;
- alphaOffset = rawImage.alpha_offset;
- alphaMask = ImageUtils.getMask(alphaLength);
- }
-
- @Override
- public boolean isCompatibleRaster(Raster raster) {
- return true;
- }
-
- private int getPixel(Object inData) {
- byte[] data = (byte[]) inData;
- int value = data[0] & 0x00FF;
- value |= (data[1] & 0x00FF) << 8;
- value |= (data[2] & 0x00FF) << 16;
- value |= (data[3] & 0x00FF) << 24;
-
- return value;
- }
-
- @Override
- public int getAlpha(Object inData) {
- int pixel = getPixel(inData);
- if(alphaLength == 0) {
- return 0xff;
- }
- return ((pixel >>> alphaOffset) & alphaMask) << (8 - alphaLength);
- }
-
- @Override
- public int getBlue(Object inData) {
- int pixel = getPixel(inData);
- return ((pixel >>> blueOffset) & blueMask) << (8 - blueLength);
- }
-
- @Override
- public int getGreen(Object inData) {
- int pixel = getPixel(inData);
- return ((pixel >>> greenOffset) & greenMask) << (8 - greenLength);
- }
-
- @Override
- public int getRed(Object inData) {
- int pixel = getPixel(inData);
- return ((pixel >>> redOffset) & redMask) << (8 - redLength);
- }
-
- @Override
- public int getAlpha(int pixel) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getBlue(int pixel) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getGreen(int pixel) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getRed(int pixel) {
- throw new UnsupportedOperationException();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.controller;
-
-import com.android.monkeyrunner.MonkeyDevice;
-import com.android.monkeyrunner.adb.AdbBackend;
-
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.util.logging.Logger;
-
-import javax.swing.JFrame;
-import javax.swing.SwingUtilities;
-
-/**
- * Application that can control an attached device using the network monkey. It has a window
- * that shows what the current screen looks like and allows the user to click in it. Clicking in
- * the window sends touch events to the attached device. It also supports keyboard input for
- * typing and has buttons to press to simulate physical buttons on the device.
- */
-public class MonkeyController extends JFrame {
- private static final Logger LOG = Logger.getLogger(MonkeyController.class.getName());
-
- public static void main(String[] args) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- AdbBackend adb = new AdbBackend();
- final MonkeyDevice device = adb.waitForConnection();
- MonkeyControllerFrame mf = new MonkeyControllerFrame(device);
- mf.setVisible(true);
- mf.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosed(WindowEvent e) {
- device.dispose();
- }
- });
- }
- });
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.controller;
-
-import com.android.monkeyrunner.MonkeyDevice;
-import com.android.monkeyrunner.MonkeyImage;
-import com.android.monkeyrunner.MonkeyManager;
-import com.android.monkeyrunner.PhysicalButton;
-
-import java.awt.KeyEventDispatcher;
-import java.awt.KeyboardFocusManager;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.util.logging.Logger;
-
-import javax.swing.AbstractAction;
-import javax.swing.BoxLayout;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JToolBar;
-import javax.swing.SwingUtilities;
-import javax.swing.Timer;
-
-/**
- * Main window for MonkeyController.
- */
-public class MonkeyControllerFrame extends JFrame {
- private static final Logger LOG = Logger.getLogger(MonkeyControllerFrame.class.getName());
-
- private final JButton refreshButton = new JButton("Refresh");
- private final JButton variablesButton = new JButton("Variable");
- private final JLabel imageLabel = new JLabel();
- private final VariableFrame variableFrame;
-
- private MonkeyManager monkeyManager;
- private BufferedImage currentImage;
-
- private final Timer timer = new Timer(1000, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- updateScreen();
- }
- });
-
- private final MonkeyDevice device;
-
- private class PressAction extends AbstractAction {
- private final PhysicalButton button;
-
- public PressAction(PhysicalButton button) {
- this.button = button;
- }
- public void actionPerformed(ActionEvent event) {
- try {
- monkeyManager.press(button);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- updateScreen();
- }
- }
-
- private JButton createToolbarButton(PhysicalButton hardButton) {
- JButton button = new JButton(new PressAction(hardButton));
- button.setText(hardButton.getKeyName());
- return button;
- }
-
- public MonkeyControllerFrame(MonkeyDevice device) {
- super("MonkeyController");
- this.device = device;
-
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
- setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
- JToolBar toolbar = new JToolBar();
-
- toolbar.add(createToolbarButton(PhysicalButton.HOME));
- toolbar.add(createToolbarButton(PhysicalButton.BACK));
- toolbar.add(createToolbarButton(PhysicalButton.SEARCH));
- toolbar.add(createToolbarButton(PhysicalButton.MENU));
-
- add(toolbar);
- add(refreshButton);
- add(variablesButton);
- add(imageLabel);
-
- refreshButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- updateScreen();
- }
- });
-
- variableFrame = new VariableFrame();
- variablesButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- variableFrame.setVisible(true);
- }
- });
-
- imageLabel.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent event) {
- try {
- monkeyManager.touch(event.getX(), event.getY());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- updateScreen();
- }
-
- });
-
- KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- focusManager.addKeyEventDispatcher(new KeyEventDispatcher() {
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (KeyEvent.KEY_TYPED == event.getID()) {
- try {
- monkeyManager.type(event.getKeyChar());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- return false;
- }
- });
-
- SwingUtilities.invokeLater(new Runnable(){
- public void run() {
- init();
- variableFrame.init(monkeyManager);
- }
- });
-
- pack();
- }
-
- private void updateScreen() {
- MonkeyImage snapshot = device.takeSnapshot();
- currentImage = snapshot.createBufferedImage();
- imageLabel.setIcon(new ImageIcon(currentImage));
-
- pack();
- }
-
- private void init() {
- monkeyManager = device.getManager();
- if (monkeyManager == null) {
- throw new RuntimeException("Unable to create monkey manager");
- }
- updateScreen();
- timer.start();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.controller;
-
-import com.google.common.collect.Sets;
-
-import com.android.monkeyrunner.MonkeyManager;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.BoxLayout;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JTable;
-import javax.swing.SwingUtilities;
-import javax.swing.WindowConstants;
-import javax.swing.event.TableModelEvent;
-import javax.swing.event.TableModelListener;
-import javax.swing.table.AbstractTableModel;
-
-/**
- * Swing Frame that displays all the variables that the monkey exposes on the device.
- */
-public class VariableFrame extends JFrame {
- private static final Logger LOG = Logger.getLogger(VariableFrame.class.getName());
- private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
- private MonkeyManager monkeyManager;
-
- private static class VariableHolder implements Comparable<VariableHolder> {
- private final String key;
- private final String value;
-
- public VariableHolder(String key, String value) {
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public String getValue() {
- return value;
- }
-
- public int compareTo(VariableHolder o) {
- return key.compareTo(o.key);
- }
- }
-
- private static <E> E getNthElement(Set<E> set, int offset) {
- int current = 0;
- for (E elem : set) {
- if (current == offset) {
- return elem;
- }
- current++;
- }
- return null;
- }
-
- private class VariableTableModel extends AbstractTableModel {
- private final TreeSet<VariableHolder> set = Sets.newTreeSet();
-
- public void refresh() {
- Collection<String> variables;
- try {
- variables = monkeyManager.listVariable();
- } catch (IOException e) {
- LOG.log(Level.SEVERE, "Error getting list of variables", e);
- return;
- }
- for (final String variable : variables) {
- EXECUTOR.execute(new Runnable() {
- public void run() {
- String value;
- try {
- value = monkeyManager.getVariable(variable);
- } catch (IOException e) {
- LOG.log(Level.SEVERE,
- "Error getting variable value for " + variable, e);
- return;
- }
- if (value == null) {
- value = "";
- }
- synchronized (set) {
- set.add(new VariableHolder(variable, value));
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- VariableTableModel.this.fireTableDataChanged();
- }
- });
-
- }
- }
- });
- }
- }
-
- public int getColumnCount() {
- return 2;
- }
-
- public int getRowCount() {
- synchronized (set) {
- return set.size();
- }
- }
-
- public Object getValueAt(int rowIndex, int columnIndex) {
- VariableHolder nthElement;
- synchronized (set) {
- nthElement = getNthElement(set, rowIndex);
- }
- if (columnIndex == 0) {
- return nthElement.getKey();
- }
- return nthElement.getValue();
- }
- }
-
- public VariableFrame() {
- super("Variables");
- setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
- setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
-
- final VariableTableModel tableModel = new VariableTableModel();
-
- JButton refreshButton = new JButton("Refresh");
- add(refreshButton);
- refreshButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- tableModel.refresh();
- }
- });
-
-
- JTable table = new JTable(tableModel);
- add(table);
-
- tableModel.addTableModelListener(new TableModelListener() {
- public void tableChanged(TableModelEvent e) {
- pack();
- }
- });
-
- this.addWindowListener(new WindowAdapter() {
- @Override
- public void windowOpened(WindowEvent e) {
- tableModel.refresh();
- }
- });
-
- pack();
- }
-
- public void init(MonkeyManager monkeyManager) {
- this.monkeyManager = monkeyManager;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.doc;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates that the annotated method is a public API to expose to the
- * scripting interface. Can be used to generate documentation of what
- * methods are exposed and also can be used to enforce visibility of
- * these methods in the scripting environment.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE })
-public @interface MonkeyRunnerExported {
- /**
- * A documentation string for this method.
- */
- String doc();
-
- /**
- * The list of names for the keywords in this method in their proper positional order.
- *
- * For example:
- *
- * @MonkeyRunnerExported(args={"one", "two"})
- * public void foo();
- *
- * would allow calls like this:
- * foo(one=1, two=2)
- * foo(1, 2)
- */
- String[] args() default {};
-
- /**
- * The list of documentation for the arguments.
- */
- String[] argDocs() default {};
-
- /**
- * The documentation for the return type of this method.
- */
- String returns() default "returns nothing.";
-}
\ No newline at end of file
+++ /dev/null
-package com.android.monkeyrunner.exceptions;
-
-/**
- * Base exception class for all MonkeyRunner Exceptions.
- */
-public class MonkeyRunnerException extends Exception {
- public MonkeyRunnerException(String message) {
- super(message);
- }
-
- public MonkeyRunnerException(Throwable e) {
- super(e);
- }
-
- public MonkeyRunnerException(String message, Throwable e) {
- super(message, e);
- }
-}
+++ /dev/null
-package com.android.monkeyrunner.stub;
-
-import com.android.monkeyrunner.MonkeyDevice;
-import com.android.monkeyrunner.MonkeyManager;
-import com.android.monkeyrunner.MonkeyRunnerBackend;
-
-public class StubBackend implements MonkeyRunnerBackend {
-
- public MonkeyManager createManager(String address, int port) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public MonkeyDevice waitForConnection(long timeout, String deviceId) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public void shutdown() {
- // We're stub - we've got nothing to do.
- }
-}
+++ /dev/null
-<html>
-<body>
-<h1>MonkeyRunner Help<h1>
-<h2>Table of Contents</h2>
-<ul>
-<?cs each:item = help ?>
-<li><a href="#<?cs name:item ?>"><?cs var:item.name ?></a></li>
-<?cs /each ?>
-</ul>
-<?cs each:item = help ?>
-<h2><a name="<?cs name:item ?>"><?cs var:item.name ?></a></h2>
- <p><?cs var:item.doc ?></p>
- <?cs if:subcount(item.argument) ?>
-<h3>Args</h3>
-<ul>
- <?cs each:arg = item.argument ?>
- <li><?cs var:arg.name ?> - <?cs var:arg.doc ?></li>
- <?cs /each ?>
-</ul>
-<h3>Returns</h3>
-<p><?cs var:item.returns ?></p>
-<?cs /if ?>
-<?cs /each ?>
-</body>
-</html>
+++ /dev/null
-MonkeyRunner help
-<?cs each:item = help ?>
-<?cs var:item.name ?>
- <?cs var:item.doc ?>
-
-<?cs if:subcount(item.argument) ?> Args:<?cs each:arg = item.argument ?>
- <?cs var:arg.name ?> - <?cs var:arg.doc ?><?cs /each ?>
-<?cs /if ?> Returns: <?cs var:item.returns ?>
-<?cs /each ?>
+++ /dev/null
-#
-# Copyright (C) 2010 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := MonkeyRunnerTest
-LOCAL_JAVA_LIBRARIES := junit monkeyrunner ddmlib guavalib jython
-
-include $(BUILD_HOST_JAVA_LIBRARY)
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.android.monkeyrunner.adb.AdbMonkeyDeviceTest;
-import com.android.monkeyrunner.adb.LinearInterpolatorTest;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
-
-/**
- * Test suite to run all the tests for MonkeyRunner.
- */
-public class AllTests {
- public static Test suite(Class<? extends TestCase>... classes) {
- TestSuite suite = new TestSuite();
- for (Class<? extends TestCase> clz : classes) {
- suite.addTestSuite(clz);
- }
- return suite;
- }
-
- public static void main(String args[]) {
- TestRunner tr = new TestRunner();
- TestResult result = tr.doRun(AllTests.suite(ImageUtilsTest.class, JythonUtilsTest.class,
- MonkeyRunnerOptionsTest.class, LinearInterpolatorTest.class,
- AdbMonkeyDeviceTest.class));
- if (result.wasSuccessful()) {
- System.exit(0);
- } else {
- System.exit(1);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.android.ddmlib.RawImage;
-import com.android.monkeyrunner.adb.image.CaptureRawAndConvertedImage;
-import com.android.monkeyrunner.adb.image.ImageUtils;
-import com.android.monkeyrunner.adb.image.CaptureRawAndConvertedImage.MonkeyRunnerRawImage;
-
-import junit.framework.TestCase;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-
-import javax.imageio.ImageIO;
-
-public class ImageUtilsTest extends TestCase {
- private static BufferedImage createBufferedImage(String name) throws IOException {
- InputStream is = ImageUtilsTest.class.getResourceAsStream(name);
- BufferedImage img = ImageIO.read(is);
- is.close();
- return img;
- }
-
- private static RawImage createRawImage(String name) throws IOException, ClassNotFoundException {
- ObjectInputStream is =
- new ObjectInputStream(ImageUtilsTest.class.getResourceAsStream(name));
- CaptureRawAndConvertedImage.MonkeyRunnerRawImage wrapper = (MonkeyRunnerRawImage) is.readObject();
- is.close();
- return wrapper.toRawImage();
- }
-
- /**
- * Check that the two images will draw the same (ie. have the same pixels). This is different
- * that BufferedImage.equals(), which also wants to check that they have the same ColorModel
- * and other parameters.
- *
- * @param i1 the first image
- * @param i2 the second image
- * @return true if both images will draw the same (ie. have same pixels).
- */
- private static boolean checkImagesHaveSamePixels(BufferedImage i1, BufferedImage i2) {
- if (i1.getWidth() != i2.getWidth()) {
- return false;
- }
- if (i1.getHeight() != i2.getHeight()) {
- return false;
- }
-
- for (int y = 0; y < i1.getHeight(); y++) {
- for (int x = 0; x < i1.getWidth(); x++) {
- int p1 = i1.getRGB(x, y);
- int p2 = i2.getRGB(x, y);
- if (p1 != p2) {
- WritableRaster r1 = i1.getRaster();
- WritableRaster r2 = i2.getRaster();
- return false;
- }
- }
- }
-
- return true;
- }
-
- public void testImageConversionOld() throws IOException, ClassNotFoundException {
- RawImage rawImage = createRawImage("image1.raw");
- BufferedImage convertedImage = ImageUtils.convertImage(rawImage);
- BufferedImage correctConvertedImage = createBufferedImage("image1.png");
-
- assertTrue(checkImagesHaveSamePixels(convertedImage, correctConvertedImage));
- }
-
- public void testImageConversionNew() throws IOException, ClassNotFoundException {
- RawImage rawImage = createRawImage("image2.raw");
- BufferedImage convertedImage = ImageUtils.convertImage(rawImage);
- BufferedImage correctConvertedImage = createBufferedImage("image2.png");
-
- assertTrue(checkImagesHaveSamePixels(convertedImage, correctConvertedImage));
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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 com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-
-import com.android.monkeyrunner.doc.MonkeyRunnerExported;
-
-import junit.framework.TestCase;
-
-import org.python.core.ArgParser;
-import org.python.core.PyDictionary;
-import org.python.core.PyException;
-import org.python.core.PyObject;
-import org.python.core.PyString;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for the JythonUtils class.
- */
-public class JythonUtilsTest extends TestCase {
- private static final String PACKAGE_NAME = JythonUtilsTest.class.getPackage().getName();
- private static final String CLASS_NAME = JythonUtilsTest.class.getSimpleName();
-
- private static boolean called = false;
- private static double floatValue = 0.0;
- private static List<Object> listValue = null;
- private static Map<String, Object> mapValue;
-
- @MonkeyRunnerExported(doc = "", args = {"value"})
- public static void floatTest(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
- called = true;
-
- floatValue = JythonUtils.getFloat(ap, 0);
- }
-
- @MonkeyRunnerExported(doc = "", args = {"value"})
- public static void listTest(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
- called = true;
-
- listValue = JythonUtils.getList(ap, 0);
- }
-
- @MonkeyRunnerExported(doc = "", args = {"value"})
- public static void mapTest(PyObject[] args, String[] kws) {
- ArgParser ap = JythonUtils.createArgParser(args, kws);
- Preconditions.checkNotNull(ap);
- called = true;
-
- mapValue = JythonUtils.getMap(ap, 0);
- }
-
- @MonkeyRunnerExported(doc = "")
- public static PyDictionary convertMapTest(PyObject[] args, String[] kws) {
- Map<String, Object> map = Maps.newHashMap();
- map.put("string", "value");
- map.put("integer", 1);
- map.put("double", 3.14);
- return JythonUtils.convertMapToDict(map);
- }
-
- @Override
- protected void setUp() throws Exception {
- called = false;
- floatValue = 0.0;
- }
-
- private static PyObject call(String method) {
- return call(method, new String[]{ });
- }
- private static PyObject call(String method, String... args) {
- StringBuilder sb = new StringBuilder();
- sb.append("from ").append(PACKAGE_NAME);
- sb.append(" import ").append(CLASS_NAME).append("\n");
-
- // Exec line
- sb.append("result = ");
- sb.append(CLASS_NAME).append(".").append(method);
- sb.append("(");
- for (String arg : args) {
- sb.append(arg).append(",");
- }
- sb.append(")");
-
- return ScriptRunner.runStringAndGet(sb.toString(), "result").get("result");
- }
-
- public void testSimpleCall() {
- call("floatTest", "0.0");
- assertTrue(called);
- }
-
- public void testMissingFloatArg() {
- try {
- call("floatTest");
- } catch(PyException e) {
- return;
- }
- fail("Should have thrown exception");
- }
-
- public void testBadFloatArgType() {
- try {
- call("floatTest", "\'foo\'");
- } catch(PyException e) {
- return;
- }
- fail("Should have thrown exception");
- }
-
- public void testFloatParse() {
- call("floatTest", "103.2");
- assertTrue(called);
- assertEquals(floatValue, 103.2);
- }
-
- public void testFloatParseInteger() {
- call("floatTest", "103");
- assertTrue(called);
- assertEquals(floatValue, 103.0);
- }
-
- public void testParseStringList() {
- call("listTest", "['a', 'b', 'c']");
- assertTrue(called);
- assertEquals(3, listValue.size());
- assertEquals("a", listValue.get(0));
- assertEquals("b", listValue.get(1));
- assertEquals("c", listValue.get(2));
- }
-
- public void testParseIntList() {
- call("listTest", "[1, 2, 3]");
- assertTrue(called);
- assertEquals(3, listValue.size());
- assertEquals(new Integer(1), listValue.get(0));
- assertEquals(new Integer(2), listValue.get(1));
- assertEquals(new Integer(3), listValue.get(2));
- }
-
- public void testParseMixedList() {
- call("listTest", "['a', 1, 3.14]");
- assertTrue(called);
- assertEquals(3, listValue.size());
- assertEquals("a", listValue.get(0));
- assertEquals(new Integer(1), listValue.get(1));
- assertEquals(new Double(3.14), listValue.get(2));
- }
-
- public void testParseOptionalList() {
- call("listTest");
- assertTrue(called);
- assertEquals(0, listValue.size());
- }
-
- public void testParsingNotAList() {
- try {
- call("listTest", "1.0");
- } catch (PyException e) {
- return;
- }
- fail("Should have thrown an exception");
- }
-
- public void testParseMap() {
- call("mapTest", "{'a': 0, 'b': 'bee', 3: 'cee'}");
- assertTrue(called);
- assertEquals(3, mapValue.size());
- assertEquals(new Integer(0), mapValue.get("a"));
- assertEquals("bee", mapValue.get("b"));
- // note: coerced key type
- assertEquals("cee", mapValue.get("3"));
- }
-
- public void testParsingNotAMap() {
- try {
- call("mapTest", "1.0");
- } catch (PyException e) {
- return;
- }
- fail("Should have thrown an exception");
- }
-
- public void testParseOptionalMap() {
- call("mapTest");
- assertTrue(called);
- assertEquals(0, mapValue.size());
- }
-
- public void testConvertMap() {
- PyDictionary result = (PyDictionary) call("convertMapTest");
- PyObject stringPyObject = result.__getitem__(new PyString("string"));
- String string = (String) stringPyObject.__tojava__(String.class);
- assertEquals("value", string);
-
- PyObject intPyObject = result.__getitem__(new PyString("integer"));
- int i = (Integer) intPyObject.__tojava__(Integer.class);
- assertEquals(i, 1);
-
- PyObject doublePyObject = result.__getitem__(new PyString("double"));
- double d = (Double) doublePyObject.__tojava__(Double.class);
- assertEquals(3.14, d);
- }
-}
+++ /dev/null
-// Copyright 2010 Google Inc. All Rights Reserved.
-
-package com.android.monkeyrunner;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.util.Iterator;
-
-/**
- * Unit Tests to test command line argument parsing.
- */
-public class MonkeyRunnerOptionsTest extends TestCase {
- // We need to use a file that actually exists
- private static final String FILENAME = "/etc/passwd";
-
- public void testSimpleArgs() {
- MonkeyRunnerOptions options =
- MonkeyRunnerOptions.processOptions(new String[] { FILENAME });
- assertEquals(options.getScriptFile(), new File(FILENAME));
- }
-
- public void testParsingArgsBeforeScriptName() {
- MonkeyRunnerOptions options =
- MonkeyRunnerOptions.processOptions(new String[] { "-be", "stub", FILENAME});
- assertEquals("stub", options.getBackendName());
- assertEquals(options.getScriptFile(), new File(FILENAME));
- }
-
- public void testParsingScriptArgument() {
- MonkeyRunnerOptions options =
- MonkeyRunnerOptions.processOptions(new String[] { FILENAME, "arg1", "arg2" });
- assertEquals(options.getScriptFile(), new File(FILENAME));
- Iterator<String> i = options.getArguments().iterator();
- assertEquals("arg1", i.next());
- assertEquals("arg2", i.next());
- }
-
- public void testParsingScriptArgumentWithDashes() {
- MonkeyRunnerOptions options =
- MonkeyRunnerOptions.processOptions(new String[] { FILENAME, "--arg1" });
- assertEquals(options.getScriptFile(), new File(FILENAME));
- assertEquals("--arg1", options.getArguments().iterator().next());
- }
-
- public void testMixedArgs() {
- MonkeyRunnerOptions options =
- MonkeyRunnerOptions.processOptions(new String[] { "-be", "stub", FILENAME,
- "arg1", "--debug=True"});
- assertEquals("stub", options.getBackendName());
- assertEquals(options.getScriptFile(), new File(FILENAME));
- Iterator<String> i = options.getArguments().iterator();
- assertEquals("arg1", i.next());
- assertEquals("--debug=True", i.next());
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2010 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.adb;
-
-import com.google.common.collect.Lists;
-
-import com.android.monkeyrunner.adb.LinearInterpolator.Point;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-
-/**
- * Unit tests for the LinerInterpolator class.S
- */
-public class LinearInterpolatorTest extends TestCase {
- private static class Collector implements LinearInterpolator.Callback {
- private final List<LinearInterpolator.Point> points = Lists.newArrayList();
-
- public List<LinearInterpolator.Point> getPoints() {
- return points;
- }
-
- public void end(Point input) {
- points.add(input);
- }
-
- public void start(Point input) {
- points.add(input);
- }
-
- public void step(Point input) {
- points.add(input);
- }
- }
-
- List<Integer> STEP_POINTS = Lists.newArrayList(0, 100, 200, 300, 400, 500, 600, 700, 800, 900,
- 1000);
- List<Integer> REVERSE_STEP_POINTS = Lists.newArrayList(1000, 900, 800, 700, 600, 500, 400, 300,
- 200, 100, 0);
-
- public void testLerpRight() {
- LinearInterpolator lerp = new LinearInterpolator(10);
- Collector collector = new Collector();
- lerp.interpolate(new LinearInterpolator.Point(0, 100),
- new LinearInterpolator.Point(1000, 100),
- collector);
-
- List<LinearInterpolator.Point> points = collector.getPoints();
- assertEquals(11, points.size());
- for (int x = 0; x < points.size(); x++) {
- assertEquals(new Point(STEP_POINTS.get(x), 100), points.get(x));
- }
- }
-
- public void testLerpLeft() {
- LinearInterpolator lerp = new LinearInterpolator(10);
- Collector collector = new Collector();
- lerp.interpolate(new LinearInterpolator.Point(1000, 100),
- new LinearInterpolator.Point(0, 100),
- collector);
-
- List<LinearInterpolator.Point> points = collector.getPoints();
- assertEquals(11, points.size());
- for (int x = 0; x < points.size(); x++) {
- assertEquals(new Point(REVERSE_STEP_POINTS.get(x), 100), points.get(x));
- }
- }
-
- public void testLerpUp() {
- LinearInterpolator lerp = new LinearInterpolator(10);
- Collector collector = new Collector();
- lerp.interpolate(new LinearInterpolator.Point(100, 1000),
- new LinearInterpolator.Point(100, 0),
- collector);
-
- List<LinearInterpolator.Point> points = collector.getPoints();
- assertEquals(11, points.size());
- for (int x = 0; x < points.size(); x++) {
- assertEquals(new Point(100, REVERSE_STEP_POINTS.get(x)), points.get(x));
- }
- }
-
- public void testLerpDown() {
- LinearInterpolator lerp = new LinearInterpolator(10);
- Collector collector = new Collector();
- lerp.interpolate(new LinearInterpolator.Point(100, 0),
- new LinearInterpolator.Point(100, 1000),
- collector);
-
- List<LinearInterpolator.Point> points = collector.getPoints();
- assertEquals(11, points.size());
- for (int x = 0; x < points.size(); x++) {
- assertEquals(new Point(100, STEP_POINTS.get(x)), points.get(x));
- }
- }
-
- public void testLerpNW() {
- LinearInterpolator lerp = new LinearInterpolator(10);
- Collector collector = new Collector();
- lerp.interpolate(new LinearInterpolator.Point(0, 0),
- new LinearInterpolator.Point(1000, 1000),
- collector);
-
- List<LinearInterpolator.Point> points = collector.getPoints();
- assertEquals(11, points.size());
- for (int x = 0; x < points.size(); x++) {
- assertEquals(new Point(STEP_POINTS.get(x), STEP_POINTS.get(x)), points.get(x));
- }
- }
-
- public void testLerpNE() {
- LinearInterpolator lerp = new LinearInterpolator(10);
- Collector collector = new Collector();
- lerp.interpolate(new LinearInterpolator.Point(1000, 1000),
- new LinearInterpolator.Point(0, 0),
- collector);
-
- List<LinearInterpolator.Point> points = collector.getPoints();
- assertEquals(11, points.size());
- for (int x = 0; x < points.size(); x++) {
- assertEquals(new Point(REVERSE_STEP_POINTS.get(x), REVERSE_STEP_POINTS.get(x)), points.get(x));
- }
- }
-}