├── TestApp
├── bin
│ ├── TestApp.apk
│ ├── classes.dex
│ ├── resources.ap_
│ ├── classes
│ │ └── com
│ │ │ └── example
│ │ │ └── testapp
│ │ │ ├── R.class
│ │ │ ├── R$id.class
│ │ │ ├── R$attr.class
│ │ │ ├── R$dimen.class
│ │ │ ├── R$layout.class
│ │ │ ├── R$menu.class
│ │ │ ├── R$string.class
│ │ │ ├── R$style.class
│ │ │ ├── R$drawable.class
│ │ │ ├── BuildConfig.class
│ │ │ └── MainActivity.class
│ ├── res
│ │ └── crunch
│ │ │ ├── drawable-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── drawable-mdpi
│ │ │ └── ic_launcher.png
│ │ │ └── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ ├── dexedLibs
│ │ └── android-support-v4-1cc17aee38bb349e50ed758e5badfc0b.jar
│ └── AndroidManifest.xml
├── libs
│ └── android-support-v4.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-w820dp
│ │ └── dimens.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── layout
│ │ └── activity_main.xml
├── .settings
│ └── org.eclipse.jdt.core.prefs
├── gen
│ └── com
│ │ └── example
│ │ └── testapp
│ │ ├── BuildConfig.java
│ │ └── R.java
├── .classpath
├── project.properties
├── proguard-project.txt
├── .project
├── AndroidManifest.xml
└── src
│ └── com
│ └── example
│ └── testapp
│ └── MainActivity.java
├── MonkeyPlatform
├── assets
│ ├── key_event.json
│ ├── touch_event.json
│ └── flip_event.json
├── bin
│ ├── classes.dex
│ ├── resources.ap_
│ ├── MonkeyPlatform.apk
│ ├── classes
│ │ └── love
│ │ │ └── juhe
│ │ │ ├── test
│ │ │ ├── R.class
│ │ │ ├── R$attr.class
│ │ │ ├── R$id.class
│ │ │ ├── R$layout.class
│ │ │ ├── R$string.class
│ │ │ ├── TestFuxk.class
│ │ │ ├── BuildConfig.class
│ │ │ ├── R$drawable.class
│ │ │ ├── TestMainActivity.class
│ │ │ ├── ScriptiLogActivity.class
│ │ │ ├── TestMainActivity$1.class
│ │ │ ├── ScriptiLogActivity$1.class
│ │ │ ├── ScriptiLogActivity$2.class
│ │ │ └── script
│ │ │ │ ├── ScriptManager.class
│ │ │ │ └── ScriptReader.class
│ │ │ └── androidmonkey
│ │ │ ├── Monkey.class
│ │ │ ├── MonkeyLog.class
│ │ │ ├── EventObsever.class
│ │ │ ├── MonkeyConfig.class
│ │ │ ├── MonkeyEvent.class
│ │ │ ├── MonkeyKeyEvent.class
│ │ │ ├── MonkeyManager.class
│ │ │ ├── MonkeyEventQueue.class
│ │ │ ├── MonkeyEventSource.class
│ │ │ ├── MonkeyFlipEvent.class
│ │ │ ├── MonkeyMotionEvent.class
│ │ │ ├── MonkeyTouchEvent.class
│ │ │ ├── MonkeyActivityEvent.class
│ │ │ ├── MonkeySourceRandom.class
│ │ │ ├── MonkeyThrottleEvent.class
│ │ │ └── MonkeyTrackballEvent.class
│ ├── res
│ │ └── crunch
│ │ │ ├── drawable-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── drawable-ldpi
│ │ │ └── ic_launcher.png
│ │ │ ├── drawable-mdpi
│ │ │ └── ic_launcher.png
│ │ │ └── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ └── AndroidManifest.xml
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_script_list.xml
│ │ ├── activity_main.xml
│ │ └── content_params_layout.xml
│ └── values
│ │ └── strings.xml
├── gen
│ └── love
│ │ └── juhe
│ │ └── test
│ │ ├── BuildConfig.java
│ │ └── R.java
├── src
│ └── love
│ │ └── juhe
│ │ ├── androidmonkey
│ │ ├── EventObsever.java
│ │ ├── MonkeyConfig.java
│ │ ├── MonkeyLog.java
│ │ ├── MonkeyManager.java
│ │ ├── MonkeyEventSource.java
│ │ ├── MonkeyThrottleEvent.java
│ │ ├── MonkeyEventQueue.java
│ │ ├── MonkeyEvent.java
│ │ ├── MonkeyFlipEvent.java
│ │ ├── MonkeyActivityEvent.java
│ │ ├── MonkeyTrackballEvent.java
│ │ ├── MonkeyTouchEvent.java
│ │ ├── MonkeyKeyEvent.java
│ │ ├── Monkey.java
│ │ ├── MonkeyMotionEvent.java
│ │ └── MonkeySourceRandom.java
│ │ └── test
│ │ ├── script
│ │ ├── ScriptManager.java
│ │ └── ScriptReader.java
│ │ ├── TestFuxk.java
│ │ ├── ScriptiLogActivity.java
│ │ └── TestMainActivity.java
├── .settings
│ └── org.eclipse.jdt.core.prefs
├── .classpath
├── project.properties
├── proguard-project.txt
├── .project
└── AndroidManifest.xml
└── README.md
/TestApp/bin/TestApp.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/TestApp.apk
--------------------------------------------------------------------------------
/TestApp/bin/classes.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes.dex
--------------------------------------------------------------------------------
/MonkeyPlatform/assets/key_event.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | event_type:"flip_event",
4 | event_params:{
5 | }
6 |
7 | }
--------------------------------------------------------------------------------
/TestApp/bin/resources.ap_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/resources.ap_
--------------------------------------------------------------------------------
/MonkeyPlatform/assets/touch_event.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | event_type:"flip_event",
4 | event_params:{
5 | }
6 |
7 | }
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes.dex
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/resources.ap_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/resources.ap_
--------------------------------------------------------------------------------
/MonkeyPlatform/assets/flip_event.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | event_type:"key_event",
4 | event_params:{
5 | key_code:1
6 | }
7 |
8 | }
--------------------------------------------------------------------------------
/TestApp/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/MonkeyPlatform.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/MonkeyPlatform.apk
--------------------------------------------------------------------------------
/TestApp/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TestApp/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TestApp/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/R.class
--------------------------------------------------------------------------------
/MonkeyPlatform/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$id.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/R$attr.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/R$id.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$attr.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$dimen.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$dimen.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$layout.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$layout.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$menu.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$menu.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$string.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$style.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$style.class
--------------------------------------------------------------------------------
/TestApp/bin/res/crunch/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/res/crunch/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TestApp/bin/res/crunch/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/res/crunch/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TestApp/bin/res/crunch/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/res/crunch/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/R$layout.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/R$layout.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/R$string.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/TestFuxk.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/TestFuxk.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/R$drawable.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/BuildConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/BuildConfig.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/R$drawable.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/res/crunch/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/res/crunch/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/res/crunch/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/res/crunch/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/res/crunch/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/res/crunch/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/BuildConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/BuildConfig.class
--------------------------------------------------------------------------------
/TestApp/bin/classes/com/example/testapp/MainActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/classes/com/example/testapp/MainActivity.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/res/crunch/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/res/crunch/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/Monkey.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/Monkey.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/TestMainActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/TestMainActivity.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyLog.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyLog.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/ScriptiLogActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/ScriptiLogActivity.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/TestMainActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/TestMainActivity$1.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/EventObsever.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/EventObsever.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyConfig.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/ScriptiLogActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/ScriptiLogActivity$1.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/ScriptiLogActivity$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/ScriptiLogActivity$2.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/script/ScriptManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/script/ScriptManager.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/test/script/ScriptReader.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/test/script/ScriptReader.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyKeyEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyKeyEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyManager.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyEventQueue.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyEventQueue.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyEventSource.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyEventSource.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyFlipEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyFlipEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyMotionEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyMotionEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyTouchEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyTouchEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyActivityEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyActivityEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeySourceRandom.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeySourceRandom.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyThrottleEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyThrottleEvent.class
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyTrackballEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/MonkeyPlatform/bin/classes/love/juhe/androidmonkey/MonkeyTrackballEvent.class
--------------------------------------------------------------------------------
/TestApp/bin/dexedLibs/android-support-v4-1cc17aee38bb349e50ed758e5badfc0b.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ox7/android_monkey_utils/HEAD/TestApp/bin/dexedLibs/android-support-v4-1cc17aee38bb349e50ed758e5badfc0b.jar
--------------------------------------------------------------------------------
/MonkeyPlatform/gen/love/juhe/test/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package love.juhe.test;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/EventObsever.java:
--------------------------------------------------------------------------------
1 | package love.juhe.androidmonkey;
2 |
3 | import org.json.JSONObject;
4 |
5 | public interface EventObsever {
6 |
7 | public JSONObject getEventInfo();
8 | }
9 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyConfig.java:
--------------------------------------------------------------------------------
1 | package love.juhe.androidmonkey;
2 |
3 | public class MonkeyConfig {
4 |
5 | public static int eventCount = 1000;
6 | public static long eventThrottle = 100l;
7 | }
8 |
--------------------------------------------------------------------------------
/TestApp/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
3 | org.eclipse.jdt.core.compiler.compliance=1.6
4 | org.eclipse.jdt.core.compiler.source=1.6
5 |
--------------------------------------------------------------------------------
/TestApp/gen/com/example/testapp/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.example.testapp;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/MonkeyPlatform/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
3 | org.eclipse.jdt.core.compiler.compliance=1.6
4 | org.eclipse.jdt.core.compiler.source=1.6
5 |
--------------------------------------------------------------------------------
/TestApp/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TestApp/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TestApp
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyLog.java:
--------------------------------------------------------------------------------
1 | package love.juhe.androidmonkey;
2 |
3 | import android.util.Log;
4 |
5 | public class MonkeyLog {
6 |
7 | private final static String TAG = "monkey_log";
8 |
9 | public static void l(String msg) {
10 | Log.i(TAG, msg);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/TestApp/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/TestApp/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/TestApp/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | 64dp
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MonkeyPlatform/res/layout/activity_script_list.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/TestApp/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/test/script/ScriptManager.java:
--------------------------------------------------------------------------------
1 | package love.juhe.test.script;
2 |
3 | import java.io.File;
4 |
5 | public class ScriptManager {
6 |
7 | private static ScriptManager manager;
8 |
9 | public static ScriptManager getInstance() {
10 | if (manager == null) {
11 | manager = new ScriptManager();
12 | }
13 | return manager;
14 | }
15 |
16 | public void onFireScript(File script) {
17 |
18 | }
19 |
20 | private void loadScript(File script) {
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/TestApp/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/MonkeyPlatform/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/TestApp/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-22
15 |
--------------------------------------------------------------------------------
/MonkeyPlatform/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-22
15 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/test/script/ScriptReader.java:
--------------------------------------------------------------------------------
1 | package love.juhe.test.script;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileReader;
6 |
7 | public class ScriptReader {
8 |
9 | private File script;
10 |
11 | public ScriptReader(File script) {
12 | this.script = script;
13 | }
14 |
15 | public void parser(){
16 | FileReader fr = null;
17 | BufferedReader br = null;
18 | try {
19 | fr = new FileReader(script);
20 | br = new BufferedReader(fr);
21 | String line = null;
22 | while ((line = br.readLine()) != null) {
23 | //TODO
24 | }
25 | } catch (Exception e) {
26 | e.printStackTrace();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/MonkeyPlatform/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AutoTestHelper
5 |
6 | Monkey历史记录
7 |
8 | 开始Monkey测试
9 | 是否运行此Monkey脚本测试?
10 | 运行
11 | 改功能暂时关闭
12 | 输入Monkey事件数(正整数)
13 | 输入Monkey事件间隔事件(毫秒单位)
14 |
15 | 开始Monkey测试,请稍候...
16 | 参数配置错误,请修改
17 |
18 |
--------------------------------------------------------------------------------
/TestApp/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/TestApp/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/TestApp/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/MonkeyPlatform/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/MonkeyPlatform/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
22 |
23 |
--------------------------------------------------------------------------------
/TestApp/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TestApp
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/TestApp/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/TestApp/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyManager.java:
--------------------------------------------------------------------------------
1 | package love.juhe.androidmonkey;
2 |
3 | import android.app.Instrumentation;
4 | import android.content.Context;
5 | import android.view.Display;
6 | import android.view.WindowManager;
7 |
8 | public class MonkeyManager {
9 |
10 | private static MonkeyManager manager = null;
11 |
12 | private Monkey monkey;
13 |
14 | public static MonkeyManager getInstance(Instrumentation inst) {
15 | if (manager == null) {
16 | manager = new MonkeyManager(inst);
17 | }
18 | return manager;
19 | }
20 |
21 | private MonkeyManager(Instrumentation inst) {
22 | Display display = ((WindowManager) inst.getContext().getSystemService(
23 | Context.WINDOW_SERVICE)).getDefaultDisplay();
24 | monkey = new Monkey(display, "com.autonavi.minimap", inst, inst
25 | .getContext().getPackageManager(), MonkeyConfig.eventCount,
26 | MonkeyConfig.eventThrottle);
27 | }
28 |
29 | public Monkey getMonkey() {
30 | return monkey;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/MonkeyPlatform/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | MonkeyPlatform
4 |
5 |
6 | TestHost
7 |
8 |
9 |
10 | com.android.ide.eclipse.adt.ResourceManagerBuilder
11 |
12 |
13 |
14 |
15 | com.android.ide.eclipse.adt.PreCompilerBuilder
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javabuilder
21 |
22 |
23 |
24 |
25 | com.android.ide.eclipse.adt.ApkBuilder
26 |
27 |
28 |
29 |
30 |
31 | com.android.ide.eclipse.adt.AndroidNature
32 | org.eclipse.jdt.core.javanature
33 |
34 |
35 |
--------------------------------------------------------------------------------
/TestApp/src/com/example/testapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.testapp;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.Menu;
6 | import android.view.MenuItem;
7 |
8 |
9 | public class MainActivity extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_main);
15 | }
16 |
17 | @Override
18 | public boolean onCreateOptionsMenu(Menu menu) {
19 | // Inflate the menu; this adds items to the action bar if it is present.
20 | getMenuInflater().inflate(R.menu.main, menu);
21 | return true;
22 | }
23 |
24 | @Override
25 | public boolean onOptionsItemSelected(MenuItem item) {
26 | // Handle action bar item clicks here. The action bar will
27 | // automatically handle clicks on the Home/Up button, so long
28 | // as you specify a parent activity in AndroidManifest.xml.
29 | int id = item.getItemId();
30 | if (id == R.id.action_settings) {
31 | return true;
32 | }
33 | return super.onOptionsItemSelected(item);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/test/TestFuxk.java:
--------------------------------------------------------------------------------
1 | package love.juhe.test;
2 |
3 | import love.juhe.androidmonkey.Monkey;
4 | import love.juhe.androidmonkey.MonkeyConfig;
5 | import android.app.Instrumentation;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.test.InstrumentationTestCase;
9 | import android.view.Display;
10 | import android.view.WindowManager;
11 |
12 |
13 | public class TestFuxk extends InstrumentationTestCase {
14 |
15 | Instrumentation inst;
16 | Monkey monkey;
17 |
18 | public void testFuxk() {
19 |
20 | monkey.onFire();
21 | }
22 |
23 | @Override
24 | protected void setUp() throws Exception {
25 | super.setUp();
26 | inst = getInstrumentation();
27 |
28 | Display display = ((WindowManager) inst.getContext().getSystemService(
29 | Context.WINDOW_SERVICE)).getDefaultDisplay();
30 | monkey = new Monkey(display, "com.autonavi.minimap", inst, inst
31 | .getContext().getPackageManager(), MonkeyConfig.eventCount,
32 | MonkeyConfig.eventThrottle);
33 |
34 | Intent i = new Intent();
35 | i.setClassName("com.example.testapp",
36 | "com.example.testapp.MainActivity");
37 | i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
38 | inst.startActivitySync(i);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/MonkeyPlatform/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/MonkeyPlatform/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/MonkeyPlatform/res/layout/content_params_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
27 |
28 |
36 |
37 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyEventSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import love.juhe.androidmonkey.MonkeyEvent;
20 |
21 | /**
22 | * event source interface
23 | */
24 | public interface MonkeyEventSource {
25 | /**
26 | * @return the next monkey event from the source
27 | */
28 | public MonkeyEvent getNextEvent();
29 |
30 | /**
31 | * set verbose to allow different level of log
32 | *
33 | * @param verbose output mode? 1= verbose, 2=very verbose
34 | */
35 | public void setVerbose(int verbose);
36 |
37 | /**
38 | * check whether precondition is satisfied
39 | *
40 | * @return false if something fails, e.g. factor failure in random source or
41 | * file can not open from script source etc
42 | */
43 | public boolean validate();
44 | }
45 |
--------------------------------------------------------------------------------
/MonkeyPlatform/gen/love/juhe/test/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package love.juhe.test;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int ic_launcher=0x7f020000;
15 | }
16 | public static final class id {
17 | public static final int open_his=0x7f050001;
18 | public static final int params_count=0x7f050003;
19 | public static final int params_throttle=0x7f050004;
20 | public static final int run_tS=0x7f050000;
21 | public static final int s_list=0x7f050002;
22 | }
23 | public static final class layout {
24 | public static final int activity_main=0x7f030000;
25 | public static final int activity_script_list=0x7f030001;
26 | public static final int content_params_layout=0x7f030002;
27 | }
28 | public static final class string {
29 | public static final int action_run=0x7f040004;
30 | public static final int action_run_script_test=0x7f040003;
31 | public static final int action_run_test=0x7f040002;
32 | public static final int app_name=0x7f040000;
33 | public static final int tip_close=0x7f040005;
34 | public static final int tip_params_count=0x7f040006;
35 | public static final int tip_params_error=0x7f040009;
36 | public static final int tip_params_throttle=0x7f040007;
37 | public static final int tip_run=0x7f040008;
38 | public static final int title_script_list=0x7f040001;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyThrottleEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import org.json.JSONObject;
20 |
21 | import android.app.Instrumentation;
22 |
23 |
24 | /**
25 | * monkey throttle event
26 | */
27 | public class MonkeyThrottleEvent extends MonkeyEvent {
28 | private long mThrottle;
29 |
30 | public MonkeyThrottleEvent(long throttle) {
31 | super(MonkeyEvent.EVENT_TYPE_THROTTLE);
32 | mThrottle = throttle;
33 | }
34 |
35 | @Override
36 | public int fireEvent(Instrumentation testRuner) {
37 | try {
38 | Thread.sleep(mThrottle);
39 | } catch (InterruptedException e1) {
40 | MonkeyLog.l("** Monkey interrupted in sleep.");
41 | return MonkeyEvent.INJECT_FAIL;
42 | }
43 |
44 | return MonkeyEvent.INJECT_SUCCESS;
45 | }
46 |
47 | @Override
48 | public JSONObject getEventInfo() {
49 | JSONObject json = new JSONObject();
50 | try {
51 | json.put("event_type", "event_throttle");
52 | JSONObject params = new JSONObject();
53 | params.put("e_throttle", mThrottle);
54 | json.put("event_params", params);
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | return json;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyEventQueue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import java.util.LinkedList;
20 | import java.util.Random;
21 |
22 |
23 | /**
24 | * class for keeping a monkey event queue
25 | */
26 | @SuppressWarnings("serial")
27 | public class MonkeyEventQueue extends LinkedList {
28 |
29 | private Random mRandom;
30 | private long mThrottle;
31 | private boolean mRandomizeThrottle;
32 |
33 | public MonkeyEventQueue(Random random, long throttle, boolean randomizeThrottle) {
34 | super();
35 | mRandom = random;
36 | mThrottle = throttle;
37 | mRandomizeThrottle = randomizeThrottle;
38 | }
39 |
40 | @Override
41 | public void addLast(MonkeyEvent e) {
42 | super.add(e);
43 | if (e.isThrottlable()) {
44 | long throttle = mThrottle;
45 | if (mRandomizeThrottle && (mThrottle > 0)) {
46 | throttle = mRandom.nextLong();
47 | if (throttle < 0) {
48 | throttle = -throttle;
49 | }
50 | throttle %= mThrottle;
51 | ++throttle;
52 | }
53 | super.add(new MonkeyThrottleEvent(throttle));
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 |
20 | import android.app.Instrumentation;
21 |
22 | /**
23 | * abstract class for monkey event
24 | */
25 | public abstract class MonkeyEvent implements EventObsever{
26 | protected int eventType;
27 | public static final int EVENT_TYPE_KEY = 0;
28 | public static final int EVENT_TYPE_TOUCH = 1;
29 | public static final int EVENT_TYPE_TRACKBALL = 2;
30 | public static final int EVENT_TYPE_ACTIVITY = 3;
31 | public static final int EVENT_TYPE_FLIP = 4; // Keyboard flip
32 | public static final int EVENT_TYPE_THROTTLE = 5;
33 | public static final int EVENT_TYPE_NOOP = 6;
34 |
35 | public static final int INJECT_SUCCESS = 1;
36 | public static final int INJECT_FAIL = 0;
37 |
38 | // error code for remote exception during injection
39 | public static final int INJECT_ERROR_REMOTE_EXCEPTION = -1;
40 | // error code for security exception during injection
41 | public static final int INJECT_ERROR_SECURITY_EXCEPTION = -2;
42 |
43 | public MonkeyEvent(int type) {
44 | eventType = type;
45 | }
46 |
47 | /**
48 | * @return event type
49 | */
50 | public int getEventType() {
51 | return eventType;
52 | }
53 |
54 | /**
55 | * @return true if it is safe to throttle after this event, and false otherwise.
56 | */
57 | public boolean isThrottlable() {
58 | return true;
59 | }
60 |
61 |
62 | public abstract int fireEvent(Instrumentation inst);
63 | }
64 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/test/ScriptiLogActivity.java:
--------------------------------------------------------------------------------
1 | package love.juhe.test;
2 |
3 | import java.io.File;
4 |
5 | import android.app.Activity;
6 | import android.app.AlertDialog;
7 | import android.content.Context;
8 | import android.content.DialogInterface;
9 | import android.content.DialogInterface.OnClickListener;
10 | import android.os.Bundle;
11 | import android.os.Environment;
12 | import android.view.View;
13 | import android.widget.AdapterView;
14 | import android.widget.AdapterView.OnItemClickListener;
15 | import android.widget.ArrayAdapter;
16 | import android.widget.ListView;
17 | import android.widget.Toast;
18 |
19 | /**
20 | *
21 | * @author roy.zj
22 | *
23 | */
24 | public class ScriptiLogActivity extends Activity {
25 |
26 | Context context;
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_script_list);
32 | context = this;
33 | init();
34 | }
35 |
36 | private void init() {
37 | File[] files = fetchLog();
38 | if (files != null) {
39 | initList(files);
40 | }
41 | }
42 |
43 | private File[] fetchLog() {
44 | if (Environment.getExternalStorageState().equals(
45 | Environment.MEDIA_MOUNTED)) {
46 | File mDir = new File(Environment.getExternalStorageDirectory(),
47 | "monkey_log");
48 | if (mDir.exists()) {
49 | File eventDir = new File(mDir, "event_log");
50 | if (eventDir.exists() && eventDir.listFiles() != null) {
51 | return eventDir.listFiles();
52 | }
53 | }
54 | }
55 | return null;
56 | }
57 |
58 | private void initList(final File[] files) {
59 | ListView listv = (ListView) findViewById(R.id.s_list);
60 |
61 | int l = files.length;
62 | String[] names = new String[l];
63 | for (int i = 0; i < l; i++) {
64 | names[i] = files[i].getName();
65 | }
66 | listv.setAdapter(new ArrayAdapter(this,
67 | android.R.layout.simple_expandable_list_item_1, names));
68 |
69 | listv.setOnItemClickListener(new OnItemClickListener() {
70 |
71 | @Override
72 | public void onItemClick(AdapterView> parent, View view,
73 | int position, long id) {
74 | onFireScript(files[position]);
75 | }
76 | });
77 | }
78 |
79 | private void onFireScript(final File f) {
80 | AlertDialog.Builder ab = new AlertDialog.Builder(context);
81 | ab.setMessage(R.string.action_run_script_test);
82 | ab.setPositiveButton(R.string.action_run, new OnClickListener() {
83 |
84 | @Override
85 | public void onClick(DialogInterface dialog, int which) {
86 | //TODO
87 | Toast.makeText(context, R.string.tip_close, Toast.LENGTH_SHORT).show();
88 | dialog.dismiss();
89 | }
90 | });
91 | ab.show();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyFlipEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import java.io.FileOutputStream;
20 | import java.io.IOException;
21 |
22 | import org.json.JSONObject;
23 |
24 |
25 |
26 | import android.app.Instrumentation;
27 | /**
28 | * monkey keyboard flip event
29 | */
30 | public class MonkeyFlipEvent extends MonkeyEvent {
31 |
32 | // Raw keyboard flip event data
33 | // Works on emulator and dream
34 |
35 | private static final byte[] FLIP_0 = {
36 | 0x7f, 0x06,
37 | 0x00, 0x00,
38 | (byte) 0xe0, 0x39,
39 | 0x01, 0x00,
40 | 0x05, 0x00,
41 | 0x00, 0x00,
42 | 0x01, 0x00,
43 | 0x00, 0x00 };
44 |
45 | private static final byte[] FLIP_1 = {
46 | (byte) 0x85, 0x06,
47 | 0x00, 0x00,
48 | (byte) 0x9f, (byte) 0xa5,
49 | 0x0c, 0x00,
50 | 0x05, 0x00,
51 | 0x00, 0x00,
52 | 0x00, 0x00,
53 | 0x00, 0x00 };
54 |
55 | private final boolean mKeyboardOpen;
56 |
57 | public MonkeyFlipEvent(boolean keyboardOpen) {
58 | super(EVENT_TYPE_FLIP);
59 | mKeyboardOpen = keyboardOpen;
60 | }
61 |
62 | @Override
63 | public int fireEvent(Instrumentation testRuner) {
64 | MonkeyLog.l(":Sending Flip keyboardOpen=" + mKeyboardOpen);
65 |
66 | // inject flip event
67 | try {
68 | FileOutputStream f = new FileOutputStream("/dev/input/event0");
69 | f.write(mKeyboardOpen ? FLIP_0 : FLIP_1);
70 | f.close();
71 | return MonkeyEvent.INJECT_SUCCESS;
72 | } catch (IOException e) {
73 | MonkeyLog.l("Got IOException performing flip" + e);
74 | return MonkeyEvent.INJECT_FAIL;
75 | }
76 | }
77 |
78 | @Override
79 | public JSONObject getEventInfo() {
80 | JSONObject json = new JSONObject();
81 | try {
82 | json.put("event_type", "event_flip");
83 | JSONObject params = new JSONObject();
84 | json.put("event_params", params);
85 | } catch (Exception e) {
86 | e.printStackTrace();
87 | }
88 | return json;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/TestApp/gen/com/example/testapp/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.example.testapp;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class dimen {
14 | /** Default screen margins, per the Android Design guidelines.
15 |
16 | Example customization of dimensions originally defined in res/values/dimens.xml
17 | (such as screen margins) for screens with more than 820dp of available width. This
18 | would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
19 |
20 | */
21 | public static final int activity_horizontal_margin=0x7f040000;
22 | public static final int activity_vertical_margin=0x7f040001;
23 | }
24 | public static final class drawable {
25 | public static final int ic_launcher=0x7f020000;
26 | }
27 | public static final class id {
28 | public static final int action_settings=0x7f080000;
29 | }
30 | public static final class layout {
31 | public static final int activity_main=0x7f030000;
32 | }
33 | public static final class menu {
34 | public static final int main=0x7f070000;
35 | }
36 | public static final class string {
37 | public static final int action_settings=0x7f050002;
38 | public static final int app_name=0x7f050000;
39 | public static final int hello_world=0x7f050001;
40 | }
41 | public static final class style {
42 | /**
43 | Base application theme, dependent on API level. This theme is replaced
44 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
45 |
46 |
47 | Theme customizations available in newer API levels can go in
48 | res/values-vXX/styles.xml, while customizations related to
49 | backward-compatibility can go here.
50 |
51 |
52 | Base application theme for API 11+. This theme completely replaces
53 | AppBaseTheme from res/values/styles.xml on API 11+ devices.
54 |
55 | API 11 theme customizations can go here.
56 |
57 | Base application theme for API 14+. This theme completely replaces
58 | AppBaseTheme from BOTH res/values/styles.xml and
59 | res/values-v11/styles.xml on API 14+ devices.
60 |
61 | API 14 theme customizations can go here.
62 | */
63 | public static final int AppBaseTheme=0x7f060000;
64 | /** Application theme.
65 | All customizations that are NOT specific to a particular API-level can go here.
66 | */
67 | public static final int AppTheme=0x7f060001;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # android_monkey_utils
2 |
3 | 一个monkey+instrumentaion构成的自动化monkey测试工具
4 |
5 | ---
6 |
7 | ## **Keyword**
8 |
9 | - monkey
10 | - instrument
11 |
12 | ---
13 |
14 | #### **Monkey简介**
15 |
16 | > The Monkey is a program that runs on your emulator or device and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner.
17 |
18 | 通常来说,Monkey我们一般用于测试APP的稳定性。至于用法可详见Google的Monkey文档: [UI/Application Exerciser Monkey](http://developer.android.com/tools/help/monkey.html)
19 |
20 | #### **Monkey分析**
21 |
22 | 废话不多说,言简意赅的总结一下(时间限制,不细说Monkey整体类结构等,只简单阐述关键点):
23 |
24 | 通过分析Monkey源码,Monkey的事务流程如下:
25 |
26 | 
27 |
28 | - 伪随机事件生成(包括点击、拖拽、缩放、键盘Menu等)
29 | - 伪随机事件注入
30 | - 目标APP行为监控
31 |
32 | 因为Monkey是一个拥有系统级权限的命令行工具,所以其伪随机事件注入和APP行为事件监控是调用系统的内部隐藏api实现的。非系统级权限和Root权限无法正常访问。
33 |
34 | 注入部分逻辑分为两个阶段,早期版本使用系统
35 |
36 | ```java
37 | android.view.IWindowManager;
38 | android.app.IActivityManager;
39 | ```
40 | 两个内部类实现事件的注入。后期Android系统的
41 |
42 | ```java
43 | android.hardware.input.InputManager;
44 | ```
45 | 地位大幅提升,统一接管了事件注入等一系列输入逻辑。
46 |
47 |
48 | APP监控是通过内部类
49 | ```java
50 | android.app.ActivityManagerNative;
51 | android.app.IActivityController;
52 | ```
53 | 来实现页面跳转、Crash、ANR等一系列事件的监控。
54 |
55 |
56 | #### **Monkey特点**
57 |
58 | - 独立进程运行与目标APP完全隔离
59 | - 通过系统内部api,调用注入事件与监听Log服务
60 | - 最小化影响目标APP运行状况
61 | - 命令行运行,不需要root权限
62 |
63 | #### **android_monkey_utils方案**
64 |
65 | 基于Monkey这些特点,Monkey整体的改造方案选择Instrumentation + Monkey。
66 |
67 | 简单的讲,保留Monkey的伪随机事件生成层,将注入层改为基于Android Instrumentation框架实现事件的注入。
68 |
69 | 在保留Monkey大部分优点的同时,将Monkey封装成一个Android Instrumentation test case,脱离命令行,可以包装进一个Apk,实现手机端自主运行。
70 |
71 | 一些特殊注意点:
72 | - 项目打包的测试apk,必须与目标待测试apk保持签名一致,同debug,或同release签名。
73 | - 目前暂时关闭了事件回放(在处理几十万、百万级事件回放时需要更好的方案,待之后版本优化)
74 | - 目前暂时关闭事件Crash截屏
75 |
76 | #### **Monkey Apk使用**
77 |
78 | - IDE直接以Android JUnit Test运行,此模式可以Debug等
79 | - 打包成Apk安装到手机运行,此模式不同的手机第一次启动时会有卡顿,稍等片刻即可。
80 |
81 |
82 |
83 | ### License
84 | ```java
85 | /*
86 | * Copyright (C) 2015 lymph team
87 | *
88 | * Licensed under the Apache License, Version 2.0 (the "License");
89 | * you may not use this file except in compliance with the License.
90 | * You may obtain a copy of the License at
91 | *
92 | * http://www.apache.org/licenses/LICENSE-2.0
93 | *
94 | * Unless required by applicable law or agreed to in writing, software
95 | * distributed under the License is distributed on an "AS IS" BASIS,
96 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97 | * See the License for the specific language governing permissions and
98 | * limitations under the License.
99 | */
100 | ```
101 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyActivityEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import org.json.JSONObject;
20 |
21 | import android.annotation.SuppressLint;
22 | import android.app.Instrumentation;
23 | import android.app.Instrumentation.ActivityMonitor;
24 | import android.content.ComponentName;
25 | import android.content.Intent;
26 | import android.content.IntentFilter;
27 | import android.os.Bundle;
28 |
29 | /**
30 | * monkey activity event
31 | */
32 | public class MonkeyActivityEvent extends MonkeyEvent {
33 | private ComponentName mApp;
34 | long mAlarmTime = 0;
35 |
36 | public MonkeyActivityEvent(ComponentName app) {
37 | super(EVENT_TYPE_ACTIVITY);
38 | mApp = app;
39 | }
40 |
41 | public MonkeyActivityEvent(ComponentName app, long arg) {
42 | super(EVENT_TYPE_ACTIVITY);
43 | mApp = app;
44 | mAlarmTime = arg;
45 | }
46 |
47 | /**
48 | * @return Intent for the new activity
49 | */
50 | private Intent getEvent() {
51 | Intent intent = new Intent(Intent.ACTION_MAIN);
52 | intent.addCategory(Intent.CATEGORY_LAUNCHER);
53 | intent.setComponent(mApp);
54 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
55 | return intent;
56 | }
57 |
58 | @SuppressLint("NewApi")
59 | @Override
60 | public int fireEvent(Instrumentation testRuner) {
61 | Intent intent = getEvent();
62 | MonkeyLog.l(":Switch: " + intent.toUri(0));
63 |
64 | if (mAlarmTime != 0) {
65 | Bundle args = new Bundle();
66 | args.putLong("alarmTime", mAlarmTime);
67 | intent.putExtras(args);
68 | }
69 | try {
70 | // IntentFilter filter = new IntentFilter(getEvent().getAction());
71 | // ActivityMonitor monitor = testRuner.addMonitor(filter, null, true);
72 | testRuner.startActivitySync(intent);
73 | // testRuner.waitForMonitorWithTimeout(monitor, 10);
74 |
75 | } catch (SecurityException e) {
76 | MonkeyLog.l("** Permissions error starting activity "
77 | + intent.toUri(0));
78 | return MonkeyEvent.INJECT_ERROR_SECURITY_EXCEPTION;
79 | }
80 | return MonkeyEvent.INJECT_SUCCESS;
81 | }
82 |
83 | @Override
84 | public JSONObject getEventInfo() {
85 | JSONObject json = new JSONObject();
86 | try {
87 | json.put("event_type", "event_activity");
88 | JSONObject params = new JSONObject();
89 | params.put("c_pkg", mApp.getPackageName());
90 | params.put("c_clz", mApp.getClassName());
91 | json.put("event_params", params);
92 | } catch (Exception e) {
93 | e.printStackTrace();
94 | }
95 | return json;
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyTrackballEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import org.json.JSONArray;
20 | import org.json.JSONObject;
21 |
22 | import android.app.Instrumentation;
23 | import android.util.SparseArray;
24 | import android.view.InputDevice;
25 | import android.view.MotionEvent;
26 |
27 | /**
28 | * monkey trackball event
29 | */
30 | public class MonkeyTrackballEvent extends MonkeyMotionEvent {
31 | MotionEvent event;
32 |
33 | public MonkeyTrackballEvent(int action) {
34 | super(MonkeyEvent.EVENT_TYPE_TRACKBALL, InputDevice.SOURCE_TRACKBALL,
35 | action);
36 | }
37 |
38 | @Override
39 | protected String getTypeLabel() {
40 | return "Trackball";
41 | }
42 |
43 | @Override
44 | public int fireEvent(Instrumentation inst) {
45 | try {
46 | event = getEvent();
47 | // System.out.println(":Touching Key (" + getTypeLabel() + "): ");
48 | printInfo();
49 |
50 | inst.sendTrackballEventSync(event);
51 |
52 | } catch (Exception e) {
53 | MonkeyLog.l(":Touching Key (" + getTypeLabel() + ") rejected ");
54 |
55 | return MonkeyEvent.INJECT_FAIL;
56 |
57 | } finally {
58 | event.recycle();
59 | }
60 | return MonkeyEvent.INJECT_SUCCESS;
61 | }
62 |
63 | @Override
64 | public JSONObject getEventInfo() {
65 | JSONObject json = new JSONObject();
66 | try {
67 | json.put("event_type", "event_trackball");
68 |
69 | JSONObject params = new JSONObject();
70 | params.put("e_act", event.getAction());
71 | params.put("e_donw_time", event.getDownTime());
72 | params.put("e_event_time", event.getEventTime());
73 | params.put("e_pointer_count", event.getPointerCount());
74 | params.put("e_meta_state", event.getMetaState());
75 | params.put("e_x_precision", event.getXPrecision());
76 | params.put("e_y_precision", event.getYPrecision());
77 | params.put("e_device_id", event.getDeviceId());
78 | params.put("e_edge_flag", event.getEdgeFlags());
79 | params.put("e_source", event.getSource());
80 | params.put("e_flag", event.getFlags());
81 |
82 | SparseArray pArray = getPointers();
83 |
84 | JSONArray pointers = new JSONArray();
85 |
86 | final int pointerCount = pArray.size();
87 | for (int i = 0; i < pointerCount; i++) {
88 | JSONObject point = new JSONObject();
89 | point.put("p_id", pArray.keyAt(i));
90 | point.put("p_x", pArray.valueAt(i).x);
91 | point.put("p_y", pArray.valueAt(i).y);
92 | point.put("p_pressure", pArray.valueAt(i).pressure);
93 | point.put("p_size", pArray.valueAt(i).size);
94 | pointers.put(i, point);
95 | }
96 |
97 | params.put("e_pointers", pointers);
98 | json.put("event_params", params);
99 | } catch (Exception e) {
100 | e.printStackTrace();
101 | }
102 | return json;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyTouchEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import org.json.JSONArray;
20 | import org.json.JSONObject;
21 |
22 | import android.app.Instrumentation;
23 | import android.util.SparseArray;
24 | import android.view.InputDevice;
25 | import android.view.MotionEvent;
26 |
27 | /**
28 | * monkey touch event
29 | */
30 | public class MonkeyTouchEvent extends MonkeyMotionEvent {
31 | MotionEvent event;
32 |
33 | public MonkeyTouchEvent(int action) {
34 | super(MonkeyEvent.EVENT_TYPE_TOUCH, InputDevice.SOURCE_TOUCHSCREEN,
35 | action);
36 | }
37 |
38 | @Override
39 | protected String getTypeLabel() {
40 | return "Touch";
41 | }
42 |
43 | @Override
44 | public int fireEvent(Instrumentation testRuner) {
45 | event = getEvent();
46 | // System.out.println(":Touching Key (" + getTypeLabel() + "): ");
47 | printInfo();
48 | try {
49 | testRuner.sendPointerSync(event);
50 | } catch (Exception e) {
51 | MonkeyLog.l(":Touching rejected ");
52 | return MonkeyEvent.INJECT_FAIL;
53 | } finally {
54 | event.recycle();
55 | }
56 |
57 | // testRuner.clickOnScreen(event.getRawX(), event.getRawY());
58 |
59 | return MonkeyEvent.INJECT_SUCCESS;
60 | }
61 |
62 | @Override
63 | public JSONObject getEventInfo() {
64 | JSONObject json = new JSONObject();
65 | try {
66 | json.put("event_type", "event_touch");
67 |
68 | JSONObject params = new JSONObject();
69 | params.put("e_act", event.getAction());
70 | params.put("e_donw_time", event.getDownTime());
71 | params.put("e_event_time", event.getEventTime());
72 | params.put("e_pointer_count", event.getPointerCount());
73 | params.put("e_meta_state", event.getMetaState());
74 | params.put("e_x_precision", event.getXPrecision());
75 | params.put("e_y_precision", event.getYPrecision());
76 | params.put("e_device_id", event.getDeviceId());
77 | params.put("e_edge_flag", event.getEdgeFlags());
78 | params.put("e_source", event.getSource());
79 | params.put("e_flag", event.getFlags());
80 |
81 | SparseArray pArray = getPointers();
82 |
83 | JSONArray pointers = new JSONArray();
84 |
85 | final int pointerCount = pArray.size();
86 | for (int i = 0; i < pointerCount; i++) {
87 | JSONObject point = new JSONObject();
88 | point.put("p_id", pArray.keyAt(i));
89 | point.put("p_x", pArray.valueAt(i).x);
90 | point.put("p_y", pArray.valueAt(i).y);
91 | point.put("p_pressure", pArray.valueAt(i).pressure);
92 | point.put("p_size", pArray.valueAt(i).size);
93 | pointers.put(i, point);
94 | }
95 |
96 | params.put("e_pointers", pointers);
97 | json.put("event_params", params);
98 | } catch (Exception e) {
99 | e.printStackTrace();
100 | }
101 | return json;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/test/TestMainActivity.java:
--------------------------------------------------------------------------------
1 | package love.juhe.test;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.InputStream;
5 | import java.io.InputStreamReader;
6 |
7 | import love.juhe.androidmonkey.MonkeyConfig;
8 | import love.juhe.androidmonkey.MonkeyManager;
9 |
10 |
11 | import android.app.Activity;
12 | import android.app.AlertDialog;
13 | import android.content.DialogInterface;
14 | import android.content.DialogInterface.OnClickListener;
15 | import android.content.Intent;
16 | import android.os.Bundle;
17 | import android.text.TextUtils;
18 | import android.util.Log;
19 | import android.view.LayoutInflater;
20 | import android.view.View;
21 | import android.widget.EditText;
22 | import android.widget.Toast;
23 |
24 | /**
25 | * TODO uncomplete
26 | *
27 | * @author roy.zj
28 | *
29 | */
30 | public class TestMainActivity extends Activity {
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_main);
36 | }
37 |
38 | public void onButtonClick(View v) {
39 | int id = v.getId();
40 | switch (id) {
41 | case R.id.run_tS:
42 | onFireTip();
43 | break;
44 | case R.id.open_his:
45 | openScript();
46 | break;
47 | default:
48 | break;
49 | }
50 | }
51 |
52 | private void onFireTip() {
53 | final View v = LayoutInflater.from(this).inflate(
54 | R.layout.content_params_layout, null);
55 | AlertDialog.Builder ab = new AlertDialog.Builder(this);
56 | ab.setView(v);
57 | ab.setPositiveButton(R.string.action_run, new OnClickListener() {
58 |
59 | @Override
60 | public void onClick(DialogInterface dialog, int which) {
61 | if (checkParams(v)) {
62 | Toast.makeText(TestMainActivity.this, R.string.tip_run, Toast.LENGTH_SHORT).show();
63 | onRun();
64 | }else {
65 | Toast.makeText(TestMainActivity.this, R.string.tip_params_error, Toast.LENGTH_SHORT).show();
66 | }
67 |
68 | dialog.dismiss();
69 | }
70 | });
71 | ab.show();
72 | }
73 |
74 | private boolean checkParams(View v) {
75 | EditText countT = (EditText) v.findViewById(R.id.params_count);
76 | EditText throttleT = (EditText) v.findViewById(R.id.params_throttle);
77 | String c = countT.getText().toString();
78 | String t = throttleT.getText().toString();
79 | if (TextUtils.isEmpty(c) || TextUtils.isEmpty(t)) {
80 | return false;
81 | }
82 | if (!TextUtils.isDigitsOnly(c) || !TextUtils.isDigitsOnly(t)) {
83 | return false;
84 | }
85 |
86 | int count = Integer.parseInt(c);
87 | long throttle = Long.parseLong(t);
88 |
89 | MonkeyConfig.eventCount = count;
90 | MonkeyConfig.eventThrottle = throttle;
91 |
92 | return true;
93 | }
94 |
95 | private void openScript() {
96 | Intent i = new Intent(this, ScriptiLogActivity.class);
97 | startActivity(i);
98 | }
99 |
100 | private void onRun() {
101 | Process pro = null;
102 | InputStream is = null;
103 | InputStreamReader isr = null;
104 | BufferedReader br = null;
105 | try {
106 | String cmd = "";
107 | if (android.os.Build.VERSION.SDK_INT >= 17) {
108 | cmd = "am instrument --user 0 -w love.juhe.test/android.test.InstrumentationTestRunner";
109 | } else {
110 | cmd = "am instrument -w love.juhe.test/android.test.InstrumentationTestRunner";
111 | }
112 | pro = Runtime.getRuntime().exec(cmd);
113 | int result = pro.waitFor();
114 | if (result == 0) {
115 | is = pro.getInputStream();
116 | } else {
117 | is = pro.getErrorStream();
118 | }
119 | isr = new InputStreamReader(is);
120 | br = new BufferedReader(isr);
121 | String line = null;
122 | while ((line = br.readLine()) != null) {
123 | Log.i("ttt", line);
124 | // TODO
125 | }
126 | isr.close();
127 | br.close();
128 | is.close();
129 | pro.getOutputStream().close();
130 | pro.destroy();
131 | } catch (Exception e) {
132 | e.printStackTrace();
133 | }
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyKeyEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import org.json.JSONObject;
20 |
21 | import android.app.Instrumentation;
22 | import android.view.KeyEvent;
23 |
24 | /**
25 | * monkey key event
26 | */
27 | public class MonkeyKeyEvent extends MonkeyEvent {
28 | private long mDownTime = -1;
29 | private int mMetaState = -1;
30 | private int mAction = -1;
31 | private int mKeyCode = -1;
32 | private int mScancode = -1;
33 | private int mRepeatCount = -1;
34 | private int mDeviceId = -1;
35 | private long mEventTime = -1;
36 |
37 | private KeyEvent keyEvent = null;
38 |
39 | public MonkeyKeyEvent(int action, int keycode) {
40 | super(EVENT_TYPE_KEY);
41 | mAction = action;
42 | mKeyCode = keycode;
43 | }
44 |
45 | public MonkeyKeyEvent(KeyEvent e) {
46 | super(EVENT_TYPE_KEY);
47 | keyEvent = e;
48 | }
49 |
50 | public MonkeyKeyEvent(long downTime, long eventTime, int action, int code,
51 | int repeat, int metaState, int device, int scancode) {
52 | super(EVENT_TYPE_KEY);
53 |
54 | mAction = action;
55 | mKeyCode = code;
56 | mMetaState = metaState;
57 | mScancode = scancode;
58 | mRepeatCount = repeat;
59 | mDeviceId = device;
60 | mDownTime = downTime;
61 | mEventTime = eventTime;
62 | }
63 |
64 | public int getKeyCode() {
65 | return mKeyCode;
66 | }
67 |
68 | public int getAction() {
69 | return mAction;
70 | }
71 |
72 | public long getDownTime() {
73 | return mDownTime;
74 | }
75 |
76 | public long getEventTime() {
77 | return mEventTime;
78 | }
79 |
80 | public void setDownTime(long downTime) {
81 | mDownTime = downTime;
82 | }
83 |
84 | public void setEventTime(long eventTime) {
85 | mEventTime = eventTime;
86 | }
87 |
88 | /**
89 | * @return the key event
90 | */
91 | private KeyEvent getEvent() {
92 | if (keyEvent == null) {
93 | if (mDeviceId < 0) {
94 | keyEvent = new KeyEvent(mAction, mKeyCode);
95 | } else {
96 | // for scripts
97 | keyEvent = new KeyEvent(mDownTime, mEventTime, mAction,
98 | mKeyCode, mRepeatCount, mMetaState, mDeviceId,
99 | mScancode);
100 | }
101 | }
102 | return keyEvent;
103 | }
104 |
105 | @Override
106 | public boolean isThrottlable() {
107 | return (getAction() == KeyEvent.ACTION_UP);
108 | }
109 |
110 | @Override
111 | public int fireEvent(Instrumentation testRuner) {
112 | String note;
113 | if (mAction == KeyEvent.ACTION_UP) {
114 | note = "ACTION_UP";
115 | } else {
116 | note = "ACTION_DOWN";
117 | }
118 |
119 | MonkeyLog.l(":Typing Key (" + note + "): " + mKeyCode
120 | + " // ");
121 | try {
122 | // testRuner.sendKeySync(getEvent());
123 | testRuner.sendKeyDownUpSync(mKeyCode);
124 | } catch (Exception e) {
125 | MonkeyLog.l("Failed to send key (" + note + "): " + mKeyCode
126 | + " // ");
127 | return MonkeyEvent.INJECT_FAIL;
128 | }
129 |
130 | return MonkeyEvent.INJECT_SUCCESS;
131 | }
132 |
133 | @Override
134 | public JSONObject getEventInfo() {
135 | JSONObject json = new JSONObject();
136 | try {
137 | json.put("event_type", "event_key");
138 | JSONObject params = new JSONObject();
139 | params.put("e_act", mAction);
140 | params.put("e_code", mKeyCode);
141 | json.put("event_params", params);
142 | } catch (Exception e) {
143 | e.printStackTrace();
144 | }
145 | return json;
146 | }
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/Monkey.java:
--------------------------------------------------------------------------------
1 | package love.juhe.androidmonkey;
2 |
3 | import java.io.File;
4 | import java.io.FileWriter;
5 | import java.io.IOException;
6 | import java.security.SecureRandom;
7 | import java.text.SimpleDateFormat;
8 | import java.util.ArrayList;
9 | import java.util.Date;
10 | import java.util.List;
11 | import java.util.Random;
12 |
13 | import org.json.JSONObject;
14 |
15 | import android.app.Instrumentation;
16 | import android.content.ComponentName;
17 | import android.content.Intent;
18 | import android.content.pm.PackageManager;
19 | import android.content.pm.ResolveInfo;
20 | import android.os.Environment;
21 | import android.view.Display;
22 |
23 | public class Monkey {
24 |
25 | private Instrumentation inst;
26 | private Display display;
27 | private PackageManager pm;
28 | private String testPackage;
29 |
30 | private MonkeySourceRandom mEventSource;
31 |
32 | /** Categories we are allowed to launch **/
33 | private ArrayList mMainCategories = new ArrayList();
34 | /** Applications we can switch to. */
35 | private ArrayList mMainApps = new ArrayList();
36 |
37 | private long mThrottle = 0;
38 | private long throttle = 0;
39 | private boolean mRandomizeThrottle = false;
40 | private int mVerbose = 1;
41 |
42 | private int mEventCount = 100;
43 |
44 | private boolean isError = false;
45 | private File eventLog;
46 | private File eventDir;
47 | private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(
48 | "yyyy-MM-dd--HH:mm:ss");
49 |
50 | public Monkey(Display display, String testPackage, Instrumentation inst,
51 | PackageManager mPm, int eventCount, long throttle) {
52 | this.display = display;
53 | this.inst = inst;
54 | this.pm = mPm;
55 | this.testPackage = testPackage;
56 | this.mEventCount = eventCount;
57 | this.throttle = throttle;
58 | init();
59 | // initLogFiles();
60 | }
61 |
62 | public void setEventCount(int eventCount) {
63 | this.mEventCount = eventCount;
64 | }
65 |
66 | public void setEventThrottle(long throttle) {
67 | this.throttle = throttle;
68 | }
69 |
70 | public void onFire() {
71 | if (mEventCount <= 0) {
72 | return;
73 | }
74 | int eventCounter = 0;
75 | // initEventLogFile();
76 | while (!isError) {
77 | MonkeyEvent ev = mEventSource.getNextEvent();
78 | if (ev != null) {
79 | try {
80 | Thread.sleep(throttle);
81 | } catch (Exception e) {
82 | e.printStackTrace();
83 | }
84 | if (!(ev instanceof MonkeyThrottleEvent)) {
85 | // recordEvent(ev.getEventInfo());
86 | eventCounter++;
87 | if (eventCounter == mEventCount) {
88 | break;
89 | }
90 | }
91 | ev.fireEvent(inst);
92 | }
93 | }
94 | }
95 |
96 | private void initEventLogFile() {
97 | String logName = DATE_FORMATTER.format(new Date()) + ".log";
98 | eventLog = new File(eventDir, logName);
99 | if (!eventLog.exists()) {
100 | try {
101 | eventLog.createNewFile();
102 | } catch (IOException e) {
103 | e.printStackTrace();
104 | }
105 | }
106 | }
107 |
108 | private void recordEvent(JSONObject json) {
109 | if (json == null) {
110 | return;
111 | }
112 | if (eventLog != null && eventLog.isFile() && eventLog.canWrite()) {
113 | FileWriter fw = null;
114 | try {
115 | fw = new FileWriter(eventLog, true);
116 | fw.write(json.toString());
117 | fw.write(System.getProperty("line.separator"));
118 | } catch (Exception e) {
119 | e.printStackTrace();
120 | } finally {
121 | try {
122 | if (fw != null) {
123 | fw.close();
124 | }
125 | } catch (Exception ee) {
126 | ee.printStackTrace();
127 | }
128 | }
129 | }
130 | }
131 |
132 | private void initLogFiles() {
133 | if (Environment.getExternalStorageState().equals(
134 | Environment.MEDIA_MOUNTED)) {
135 | File mDir = new File(Environment.getExternalStorageDirectory(),
136 | "monkey_log");
137 | if (!mDir.exists()) {
138 | mDir.mkdirs();
139 | }
140 | eventDir = new File(mDir, "event_log");
141 | if (!eventDir.exists()) {
142 | eventDir.mkdirs();
143 | }
144 | }
145 |
146 | }
147 |
148 | /**
149 | * Fire next random event
150 | */
151 | public void nextRandomEvent() {
152 | MonkeyEvent ev = mEventSource.getNextEvent();
153 | // System.out.println("Firing Monkey Event:" + ev.toString());
154 | if (ev != null) {
155 | ev.fireEvent(inst);
156 | }
157 |
158 | }
159 |
160 | /**
161 | * Initiate the monkey
162 | */
163 | private void init() {
164 | Random mRandom = new SecureRandom();
165 | mRandom.setSeed(-1);
166 |
167 | getMainApps();
168 |
169 | mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle,
170 | mRandomizeThrottle, display);
171 | mEventSource.setVerbose(mVerbose);
172 | mEventSource.validate();
173 |
174 | // start a random activity
175 | // mEventSource.generateActivity();
176 | }
177 |
178 | /**
179 | * Extract the activities under test
180 | *
181 | * @return
182 | */
183 | private boolean getMainApps() {
184 |
185 | mMainCategories.add(Intent.CATEGORY_LAUNCHER);
186 | mMainCategories.add(Intent.CATEGORY_MONKEY);
187 | final int N = mMainCategories.size();
188 | for (int i = 0; i < N; i++) {
189 | Intent intent = new Intent(Intent.ACTION_MAIN);
190 | String category = mMainCategories.get(i);
191 | if (category.length() > 0) {
192 | intent.addCategory(category);
193 | }
194 | List mainApps = pm.queryIntentActivities(intent, 0);
195 | if (mainApps == null || mainApps.size() == 0) {
196 | MonkeyLog.l("// Warning: no activities found for category "
197 | + category);
198 | continue;
199 | }
200 | if (mVerbose >= 2) { // very verbose
201 | MonkeyLog.l("// Selecting main activities from category "
202 | + category);
203 | }
204 | final int NA = mainApps.size();
205 | for (int a = 0; a < NA; a++) {
206 | ResolveInfo r = mainApps.get(a);
207 | String packageName = r.activityInfo.applicationInfo.packageName;
208 | if (packageName.equals(testPackage)) {
209 | mMainApps.add(new ComponentName(packageName,
210 | r.activityInfo.name));
211 |
212 | MonkeyLog.l("Mokey: " + r.activityInfo.name);
213 | }
214 | }
215 | }
216 |
217 | if (mMainApps.size() == 0) {
218 | MonkeyLog.l("** No activities found to run, monkey aborted.");
219 | return false;
220 | }
221 |
222 | return true;
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeyMotionEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import android.annotation.SuppressLint;
20 | import android.os.SystemClock;
21 | import android.util.SparseArray;
22 | import android.view.MotionEvent;
23 |
24 | /**
25 | * monkey motion event
26 | */
27 | public abstract class MonkeyMotionEvent extends MonkeyEvent {
28 | private long mDownTime;
29 | private long mEventTime;
30 | private int mAction;
31 | private SparseArray mPointers;
32 | private int mMetaState;
33 | private float mXPrecision;
34 | private float mYPrecision;
35 | private int mDeviceId;
36 | private int mSource;
37 | private int mFlags;
38 | private int mEdgeFlags;
39 |
40 | // If true, this is an intermediate step (more verbose logging, only)
41 | private boolean mIntermediateNote;
42 |
43 | protected MonkeyMotionEvent(int type, int source, int action) {
44 | super(type);
45 | mSource = source;
46 | mDownTime = -1;
47 | mEventTime = -1;
48 | mAction = action;
49 | mPointers = new SparseArray();
50 | mXPrecision = 1;
51 | mYPrecision = 1;
52 | }
53 |
54 | public MonkeyMotionEvent addPointer(int id, float x, float y) {
55 | return addPointer(id, x, y, 0, 0);
56 | }
57 |
58 | @SuppressLint("NewApi")
59 | public MonkeyMotionEvent addPointer(int id, float x, float y,
60 | float pressure, float size) {
61 | MotionEvent.PointerCoords c = new MotionEvent.PointerCoords();
62 | c.x = x;
63 | c.y = y;
64 | c.pressure = pressure;
65 | c.size = size;
66 | mPointers.append(id, c);
67 | return this;
68 | }
69 |
70 | public MonkeyMotionEvent setIntermediateNote(boolean b) {
71 | mIntermediateNote = b;
72 | return this;
73 | }
74 |
75 | public boolean getIntermediateNote() {
76 | return mIntermediateNote;
77 | }
78 |
79 | public int getAction() {
80 | return mAction;
81 | }
82 |
83 | public long getDownTime() {
84 | return mDownTime;
85 | }
86 |
87 | public long getEventTime() {
88 | return mEventTime;
89 | }
90 |
91 | public MonkeyMotionEvent setDownTime(long downTime) {
92 | mDownTime = downTime;
93 | return this;
94 | }
95 |
96 | public MonkeyMotionEvent setEventTime(long eventTime) {
97 | mEventTime = eventTime;
98 | return this;
99 | }
100 |
101 | public MonkeyMotionEvent setMetaState(int metaState) {
102 | mMetaState = metaState;
103 | return this;
104 | }
105 |
106 | public MonkeyMotionEvent setPrecision(float xPrecision, float yPrecision) {
107 | mXPrecision = xPrecision;
108 | mYPrecision = yPrecision;
109 | return this;
110 | }
111 |
112 | public MonkeyMotionEvent setDeviceId(int deviceId) {
113 | mDeviceId = deviceId;
114 | return this;
115 | }
116 |
117 | public MonkeyMotionEvent setEdgeFlags(int edgeFlags) {
118 | mEdgeFlags = edgeFlags;
119 | return this;
120 | }
121 |
122 | public SparseArray getPointers() {
123 | return mPointers;
124 | }
125 |
126 | /**
127 | *
128 | * @return instance of a motion event
129 | */
130 | @SuppressLint("NewApi")
131 | protected MotionEvent getEvent() {
132 | int pointerCount = mPointers.size();
133 | int[] pointerIds = new int[pointerCount];
134 | MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount];
135 | for (int i = 0; i < pointerCount; i++) {
136 | pointerIds[i] = mPointers.keyAt(i);
137 | pointerCoords[i] = mPointers.valueAt(i);
138 | }
139 |
140 | MotionEvent ev = MotionEvent.obtain(mDownTime,
141 | mEventTime < 0 ? SystemClock.uptimeMillis() : mEventTime,
142 | mAction, pointerCount, pointerIds, pointerCoords, mMetaState,
143 | mXPrecision, mYPrecision, mDeviceId, mEdgeFlags, mSource,
144 | mFlags);
145 | return ev;
146 | }
147 |
148 | @Override
149 | public boolean isThrottlable() {
150 | return (getAction() == MotionEvent.ACTION_UP);
151 | }
152 |
153 | // @Override
154 | // public int injectEvent(WindowManager iwm, ActivityManager iam, int
155 | // verbose) {
156 | // MotionEvent me = getEvent();
157 | // if ((verbose > 0 && !mIntermediateNote) || verbose > 1) {
158 | // StringBuilder msg = new StringBuilder(":Sending ");
159 | // msg.append(getTypeLabel()).append(" (");
160 | // switch (me.getActionMasked()) {
161 | // case MotionEvent.ACTION_DOWN:
162 | // msg.append("ACTION_DOWN");
163 | // break;
164 | // case MotionEvent.ACTION_MOVE:
165 | // msg.append("ACTION_MOVE");
166 | // break;
167 | // case MotionEvent.ACTION_UP:
168 | // msg.append("ACTION_UP");
169 | // break;
170 | // case MotionEvent.ACTION_CANCEL:
171 | // msg.append("ACTION_CANCEL");
172 | // break;
173 | // case MotionEvent.ACTION_POINTER_DOWN:
174 | // msg.append("ACTION_POINTER_DOWN ").append(me.getPointerId(me.getActionIndex()));
175 | // break;
176 | // case MotionEvent.ACTION_POINTER_UP:
177 | // msg.append("ACTION_POINTER_UP ").append(me.getPointerId(me.getActionIndex()));
178 | // break;
179 | // default:
180 | // msg.append(me.getAction());
181 | // break;
182 | // }
183 | // msg.append("):");
184 | //
185 | // int pointerCount = me.getPointerCount();
186 | // for (int i = 0; i < pointerCount; i++) {
187 | // msg.append(" ").append(me.getPointerId(i));
188 | // msg.append(":(").append(me.getX(i)).append(",").append(me.getY(i)).append(")");
189 | // }
190 | // System.out.println(msg.toString());
191 | // }
192 | // try {
193 | // if (!injectMotionEvent(iwm, me)) {
194 | // return MonkeyEvent.INJECT_FAIL;
195 | // }
196 | // } catch (RemoteException ex) {
197 | // return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION;
198 | // } finally {
199 | // me.recycle();
200 | // }
201 | // return MonkeyEvent.INJECT_SUCCESS;
202 | // }
203 |
204 | @SuppressLint("NewApi")
205 | protected void printInfo() {
206 | MotionEvent me = getEvent();
207 | if (!mIntermediateNote) {
208 | StringBuilder msg = new StringBuilder(":Sending ");
209 | msg.append(getTypeLabel()).append(" (");
210 | switch (me.getActionMasked()) {
211 | case MotionEvent.ACTION_DOWN:
212 | msg.append("ACTION_DOWN");
213 | break;
214 | case MotionEvent.ACTION_MOVE:
215 | msg.append("ACTION_MOVE");
216 | break;
217 | case MotionEvent.ACTION_UP:
218 | msg.append("ACTION_UP");
219 | break;
220 | case MotionEvent.ACTION_CANCEL:
221 | msg.append("ACTION_CANCEL");
222 | break;
223 | case MotionEvent.ACTION_POINTER_DOWN:
224 | msg.append("ACTION_POINTER_DOWN ").append(
225 | me.getPointerId(me.getActionIndex()));
226 | break;
227 | case MotionEvent.ACTION_POINTER_UP:
228 | msg.append("ACTION_POINTER_UP ").append(
229 | me.getPointerId(me.getActionIndex()));
230 | break;
231 | default:
232 | msg.append(me.getAction());
233 | break;
234 | }
235 | msg.append("):");
236 |
237 | int pointerCount = me.getPointerCount();
238 | for (int i = 0; i < pointerCount; i++) {
239 | msg.append(" ").append(me.getPointerId(i));
240 | msg.append(":(").append(me.getX(i)).append(",")
241 | .append(me.getY(i)).append(")");
242 | }
243 | MonkeyLog.l(msg.toString());
244 | }
245 | }
246 |
247 | protected abstract String getTypeLabel();
248 |
249 | }
250 |
--------------------------------------------------------------------------------
/MonkeyPlatform/src/love/juhe/androidmonkey/MonkeySourceRandom.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package love.juhe.androidmonkey;
18 |
19 | import android.annotation.SuppressLint;
20 | import android.content.ComponentName;
21 | import android.graphics.PointF;
22 | import android.os.SystemClock;
23 | import android.view.Display;
24 | import android.view.KeyCharacterMap;
25 | import android.view.KeyEvent;
26 | import android.view.MotionEvent;
27 | import java.util.ArrayList;
28 | import java.util.Random;
29 |
30 | /**
31 | * monkey event queue
32 | */
33 | @SuppressLint("NewApi")
34 | public class MonkeySourceRandom implements MonkeyEventSource {
35 | /** Key events that move around the UI. */
36 | private static final int[] NAV_KEYS = { KeyEvent.KEYCODE_DPAD_UP,
37 | KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT,
38 | KeyEvent.KEYCODE_DPAD_RIGHT, };
39 | /**
40 | * Key events that perform major navigation options (so shouldn't be sent as
41 | * much).
42 | */
43 | private static final int[] MAJOR_NAV_KEYS = { KeyEvent.KEYCODE_MENU, /*
44 | * KeyEvent.
45 | * KEYCODE_SOFT_RIGHT
46 | * ,
47 | */
48 | KeyEvent.KEYCODE_DPAD_CENTER, };
49 | /** Key events that perform system operations. */
50 | private static final int[] SYS_KEYS = { KeyEvent.KEYCODE_HOME,
51 | KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_CALL,
52 | KeyEvent.KEYCODE_ENDCALL, KeyEvent.KEYCODE_VOLUME_UP,
53 | KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_MUTE, };
54 | // , KeyEvent.KEYCODE_VOLUME_MUTE,
55 | /** If a physical key exists? */
56 | @SuppressLint("NewApi")
57 | private static final boolean[] PHYSICAL_KEY_EXISTS = new boolean[KeyEvent
58 | .getMaxKeyCode() + 1];
59 | static {
60 | for (int i = 0; i < PHYSICAL_KEY_EXISTS.length; ++i) {
61 | PHYSICAL_KEY_EXISTS[i] = true;
62 | }
63 | // Only examine SYS_KEYS
64 | for (int i = 0; i < SYS_KEYS.length; ++i) {
65 | PHYSICAL_KEY_EXISTS[SYS_KEYS[i]] = KeyCharacterMap
66 | .deviceHasKey(SYS_KEYS[i]);
67 | }
68 | }
69 |
70 | public static final int FACTOR_TOUCH = 0;
71 | public static final int FACTOR_MOTION = 1;
72 | public static final int FACTOR_PINCHZOOM = 2;
73 | public static final int FACTOR_TRACKBALL = 3;
74 | public static final int FACTOR_NAV = 4;
75 | public static final int FACTOR_MAJORNAV = 5;
76 | public static final int FACTOR_SYSOPS = 6;
77 | public static final int FACTOR_APPSWITCH = 7;
78 | public static final int FACTOR_FLIP = 8;
79 | public static final int FACTOR_ANYTHING = 9;
80 | public static final int FACTORZ_COUNT = 10; // should be last+1
81 |
82 | private static final int GESTURE_TAP = 0;
83 | private static final int GESTURE_DRAG = 1;
84 | private static final int GESTURE_PINCH_OR_ZOOM = 2;
85 |
86 | /**
87 | * percentages for each type of event. These will be remapped to working
88 | * values after we read any optional values.
89 | **/
90 | private float[] mFactors = new float[FACTORZ_COUNT];
91 | private ArrayList mMainApps;
92 | private int mEventCount = 0; // total number of events generated so far
93 | private MonkeyEventQueue mQ;
94 | private Random mRandom;
95 | private int mVerbose = 0;
96 | private long mThrottle = 0;
97 |
98 | private boolean mKeyboardOpen = false;
99 |
100 | private Display mDisplay;
101 |
102 | // public static String getKeyName(int keycode) {
103 | // return KeyEvent.keyCodeToString(keycode);
104 | // }
105 |
106 | /**
107 | * Looks up the keyCode from a given KEYCODE_NAME. NOTE: This may be an
108 | * expensive operation.
109 | *
110 | * @param keyName
111 | * the name of the KEYCODE_VALUE to lookup.
112 | * @returns the intenger keyCode value, or -1 if not found
113 | */
114 | // public static int getKeyCode(String keyName) {
115 | // return KeyEvent.keyCodeFromString(keyName);
116 | // }
117 |
118 | public MonkeySourceRandom(Random random, ArrayList MainApps,
119 | long throttle, boolean randomizeThrottle, Display display) {
120 | // default values for random distributions
121 | // note, these are straight percentages, to match user input (cmd line
122 | // args)
123 | // but they will be converted to 0..1 values before the main loop runs.
124 | mFactors[FACTOR_TOUCH] = 15.0f;
125 | mFactors[FACTOR_MOTION] = 10.0f;
126 | mFactors[FACTOR_TRACKBALL] = 15.0f;
127 | mFactors[FACTOR_NAV] = 25.0f;
128 | mFactors[FACTOR_MAJORNAV] = 15.0f;
129 | mFactors[FACTOR_SYSOPS] = 2.0f;
130 | mFactors[FACTOR_APPSWITCH] = 2.0f;
131 | mFactors[FACTOR_FLIP] = 1.0f;
132 | mFactors[FACTOR_ANYTHING] = 13.0f;
133 | mFactors[FACTOR_PINCHZOOM] = 2.0f;
134 |
135 | mRandom = random;
136 | mMainApps = MainApps;
137 | mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
138 | mDisplay = display;
139 | }
140 |
141 | /**
142 | * Adjust the percentages (after applying user values) and then normalize to
143 | * a 0..1 scale.
144 | */
145 | private boolean adjustEventFactors() {
146 | // go through all values and compute totals for user & default values
147 | float userSum = 0.0f;
148 | float defaultSum = 0.0f;
149 | int defaultCount = 0;
150 | for (int i = 0; i < FACTORZ_COUNT; ++i) {
151 | if (mFactors[i] <= 0.0f) { // user values are zero or negative
152 | userSum -= mFactors[i];
153 | } else {
154 | defaultSum += mFactors[i];
155 | ++defaultCount;
156 | }
157 | }
158 |
159 | // if the user request was > 100%, reject it
160 | if (userSum > 100.0f) {
161 | MonkeyLog.l("** Event weights > 100%");
162 | return false;
163 | }
164 |
165 | // if the user specified all of the weights, then they need to be 100%
166 | if (defaultCount == 0 && (userSum < 99.9f || userSum > 100.1f)) {
167 | MonkeyLog.l("** Event weights != 100%");
168 | return false;
169 | }
170 |
171 | // compute the adjustment necessary
172 | float defaultsTarget = (100.0f - userSum);
173 | float defaultsAdjustment = defaultsTarget / defaultSum;
174 |
175 | // fix all values, by adjusting defaults, or flipping user values back
176 | // to >0
177 | for (int i = 0; i < FACTORZ_COUNT; ++i) {
178 | if (mFactors[i] <= 0.0f) { // user values are zero or negative
179 | mFactors[i] = -mFactors[i];
180 | } else {
181 | mFactors[i] *= defaultsAdjustment;
182 | }
183 | }
184 |
185 | // if verbose, show factors
186 | if (mVerbose > 0) {
187 | MonkeyLog.l("// Event percentages:");
188 | for (int i = 0; i < FACTORZ_COUNT; ++i) {
189 | MonkeyLog.l("// " + i + ": " + mFactors[i] + "%");
190 | }
191 | }
192 |
193 | if (!validateKeys()) {
194 | return false;
195 | }
196 |
197 | // finally, normalize and convert to running sum
198 | float sum = 0.0f;
199 | for (int i = 0; i < FACTORZ_COUNT; ++i) {
200 | sum += mFactors[i] / 100.0f;
201 | mFactors[i] = sum;
202 | }
203 | return true;
204 | }
205 |
206 | private static boolean validateKeyCategory(String catName, int[] keys,
207 | float factor) {
208 | if (factor < 0.1f) {
209 | return true;
210 | }
211 | for (int i = 0; i < keys.length; ++i) {
212 | if (PHYSICAL_KEY_EXISTS[keys[i]]) {
213 | return true;
214 | }
215 | }
216 | MonkeyLog.l("** " + catName + " has no physical keys but with factor "
217 | + factor + "%.");
218 | return false;
219 | }
220 |
221 | /**
222 | * See if any key exists for non-zero factors.
223 | */
224 | private boolean validateKeys() {
225 | return validateKeyCategory("NAV_KEYS", NAV_KEYS, mFactors[FACTOR_NAV])
226 | && validateKeyCategory("MAJOR_NAV_KEYS", MAJOR_NAV_KEYS,
227 | mFactors[FACTOR_MAJORNAV])
228 | && validateKeyCategory("SYS_KEYS", SYS_KEYS,
229 | mFactors[FACTOR_SYSOPS]);
230 | }
231 |
232 | /**
233 | * set the factors
234 | *
235 | * @param factors
236 | * percentages for each type of event
237 | */
238 | public void setFactors(float factors[]) {
239 | int c = FACTORZ_COUNT;
240 | if (factors.length < c) {
241 | c = factors.length;
242 | }
243 | for (int i = 0; i < c; i++)
244 | mFactors[i] = factors[i];
245 | }
246 |
247 | public void setFactors(int index, float v) {
248 | mFactors[index] = v;
249 | }
250 |
251 | /**
252 | * Generates a random motion event. This method counts a down, move, and up
253 | * as multiple events.
254 | *
255 | * TODO: Test & fix the selectors when non-zero percentages TODO: Longpress.
256 | * TODO: Fling. TODO: Meta state TODO: More useful than the random walk here
257 | * would be to pick a single random direction and distance, and divvy it up
258 | * into a random number of segments. (This would serve to generate fling
259 | * gestures, which are important).
260 | *
261 | * @param random
262 | * Random number source for positioning
263 | * @param gesture
264 | * The gesture to perform.
265 | *
266 | */
267 | private void generatePointerEvent(Random random, int gesture) {
268 |
269 | PointF p1 = randomPoint(random, mDisplay);
270 | PointF v1 = randomVector(random);
271 |
272 | long downAt = SystemClock.uptimeMillis();
273 |
274 | mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
275 | .setDownTime(downAt).addPointer(0, p1.x, p1.y)
276 | .setIntermediateNote(false));
277 |
278 | // sometimes we'll move during the touch
279 | if (gesture == GESTURE_DRAG) {
280 | int count = random.nextInt(10);
281 | for (int i = 0; i < count; i++) {
282 | randomWalk(random, mDisplay, p1, v1);
283 |
284 | mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
285 | .setDownTime(downAt).addPointer(0, p1.x, p1.y)
286 | .setIntermediateNote(true));
287 | }
288 | } else if (gesture == GESTURE_PINCH_OR_ZOOM) {
289 | PointF p2 = randomPoint(random, mDisplay);
290 | PointF v2 = randomVector(random);
291 |
292 | randomWalk(random, mDisplay, p1, v1);
293 | mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
294 | | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
295 | .setDownTime(downAt).addPointer(0, p1.x, p1.y)
296 | .addPointer(1, p2.x, p2.y).setIntermediateNote(true));
297 |
298 | int count = random.nextInt(10);
299 | for (int i = 0; i < count; i++) {
300 | randomWalk(random, mDisplay, p1, v1);
301 | randomWalk(random, mDisplay, p2, v2);
302 |
303 | mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
304 | .setDownTime(downAt).addPointer(0, p1.x, p1.y)
305 | .addPointer(1, p2.x, p2.y).setIntermediateNote(true));
306 | }
307 |
308 | randomWalk(random, mDisplay, p1, v1);
309 | randomWalk(random, mDisplay, p2, v2);
310 | mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_UP
311 | | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
312 | .setDownTime(downAt).addPointer(0, p1.x, p1.y)
313 | .addPointer(1, p2.x, p2.y).setIntermediateNote(true));
314 | }
315 |
316 | randomWalk(random, mDisplay, p1, v1);
317 | mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_UP)
318 | .setDownTime(downAt).addPointer(0, p1.x, p1.y)
319 | .setIntermediateNote(false));
320 | }
321 |
322 | private PointF randomPoint(Random random, Display display) {
323 | return new PointF(random.nextInt(display.getWidth()),
324 | random.nextInt(display.getHeight()));
325 | }
326 |
327 | private PointF randomVector(Random random) {
328 | return new PointF((random.nextFloat() - 0.5f) * 50,
329 | (random.nextFloat() - 0.5f) * 50);
330 | }
331 |
332 | private void randomWalk(Random random, Display display, PointF point,
333 | PointF vector) {
334 | point.x = Math.max(
335 | Math.min(point.x + random.nextFloat() * vector.x,
336 | display.getWidth()), 0);
337 | point.y = Math.max(
338 | Math.min(point.y + random.nextFloat() * vector.y,
339 | display.getHeight()), 0);
340 | }
341 |
342 | /**
343 | * Generates a random trackball event. This consists of a sequence of small
344 | * moves, followed by an optional single click.
345 | *
346 | * TODO: Longpress. TODO: Meta state TODO: Parameterize the % clicked TODO:
347 | * More useful than the random walk here would be to pick a single random
348 | * direction and distance, and divvy it up into a random number of segments.
349 | * (This would serve to generate fling gestures, which are important).
350 | *
351 | * @param random
352 | * Random number source for positioning
353 | *
354 | */
355 | private void generateTrackballEvent(Random random) {
356 |
357 | boolean drop = false;
358 | int count = random.nextInt(10);
359 | for (int i = 0; i < 10; ++i) {
360 | // generate a small random step
361 | int dX = random.nextInt(10) - 5;
362 | int dY = random.nextInt(10) - 5;
363 |
364 | mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_MOVE)
365 | .addPointer(0, dX, dY).setIntermediateNote(i > 0));
366 | }
367 |
368 | // 10% of trackball moves end with a click
369 | if (0 == random.nextInt(10)) {
370 | long downAt = SystemClock.uptimeMillis();
371 |
372 | mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_DOWN)
373 | .setDownTime(downAt).addPointer(0, 0, 0)
374 | .setIntermediateNote(true));
375 |
376 | mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_UP)
377 | .setDownTime(downAt).addPointer(0, 0, 0)
378 | .setIntermediateNote(false));
379 | }
380 | }
381 |
382 | /**
383 | * generate a random event based on mFactor
384 | */
385 | private void generateEvents() {
386 | float cls = mRandom.nextFloat();
387 | int lastKey = 0;
388 |
389 | if (cls < mFactors[FACTOR_TOUCH]) {
390 | generatePointerEvent(mRandom, GESTURE_TAP);
391 | return;
392 | } else if (cls < mFactors[FACTOR_MOTION]) {
393 | generatePointerEvent(mRandom, GESTURE_DRAG);
394 | return;
395 | } else if (cls < mFactors[FACTOR_PINCHZOOM]) {
396 | generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM);
397 | return;
398 | } else if (cls < mFactors[FACTOR_TRACKBALL]) {
399 | generateTrackballEvent(mRandom);
400 | return;
401 | }
402 |
403 | // The remaining event categories are injected as key events
404 | for (;;) {
405 | if (cls < mFactors[FACTOR_NAV]) {
406 | lastKey = NAV_KEYS[mRandom.nextInt(NAV_KEYS.length)];
407 | } else if (cls < mFactors[FACTOR_MAJORNAV]) {
408 | lastKey = MAJOR_NAV_KEYS[mRandom.nextInt(MAJOR_NAV_KEYS.length)];
409 | } else if (cls < mFactors[FACTOR_SYSOPS]) {
410 | lastKey = SYS_KEYS[mRandom.nextInt(SYS_KEYS.length)];
411 | } else if (cls < mFactors[FACTOR_APPSWITCH]) {
412 | MonkeyActivityEvent e = new MonkeyActivityEvent(
413 | mMainApps.get(mRandom.nextInt(mMainApps.size())));
414 | mQ.addLast(e);
415 | return;
416 | } else if (cls < mFactors[FACTOR_FLIP]) {
417 | MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
418 | mKeyboardOpen = !mKeyboardOpen;
419 | mQ.addLast(e);
420 | return;
421 | } else {
422 | lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
423 | }
424 |
425 | if (lastKey != KeyEvent.KEYCODE_POWER
426 | && lastKey != KeyEvent.KEYCODE_ENDCALL
427 | && PHYSICAL_KEY_EXISTS[lastKey]) {
428 | break;
429 | }
430 | }
431 |
432 | MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey);
433 | mQ.addLast(e);
434 |
435 | e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
436 | mQ.addLast(e);
437 | }
438 |
439 | @Override
440 | public boolean validate() {
441 | // check factors
442 | return adjustEventFactors();
443 | }
444 |
445 | @Override
446 | public void setVerbose(int verbose) {
447 | mVerbose = verbose;
448 | }
449 |
450 | /**
451 | * generate an activity event
452 | */
453 | public void generateActivity() {
454 | MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(mRandom
455 | .nextInt(mMainApps.size())));
456 | mQ.addLast(e);
457 | }
458 |
459 | /**
460 | * if the queue is empty, we generate events first
461 | *
462 | * @return the first event in the queue
463 | */
464 | @Override
465 | public MonkeyEvent getNextEvent() {
466 | if (mQ.isEmpty()) {
467 | generateEvents();
468 | }
469 | mEventCount++;
470 | MonkeyEvent e = mQ.getFirst();
471 | mQ.removeFirst();
472 | return e;
473 | }
474 | }
475 |
--------------------------------------------------------------------------------