MonkeySourceRandom.java revision 20e7a15bb74d7349ee879bb311a0607325f49aaf
152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/*
252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project *
452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * you may not use this file except in compliance with the License.
652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * You may obtain a copy of the License at
752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project *
852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project *
1052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * See the License for the specific language governing permissions and
1452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * limitations under the License.
1552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */
1652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
1752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectpackage com.android.commands.monkey;
1852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
1952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.content.ComponentName;
2052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.os.SystemClock;
2152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.Display;
2252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.KeyEvent;
2352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.MotionEvent;
2452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.WindowManagerImpl;
2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.security.SecureRandom;
2752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.ArrayList;
2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.LinkedList;
2952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.Random;
3052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
3152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/**
3252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * monkey event queue
3352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */
34a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napierpublic class MonkeySourceRandom implements MonkeyEventSource {
3552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Key events that move around the UI. */
3652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] NAV_KEYS = {
3752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
3852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT,
3952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
4052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
4152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Key events that perform major navigation options (so shouldn't be sent
4252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * as much).
4352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
4452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] MAJOR_NAV_KEYS = {
4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_MENU, /*KeyEvent.KEYCODE_SOFT_RIGHT,*/
4652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_CENTER,
4752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Key events that perform system operations. */
4952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] SYS_KEYS = {
5052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_HOME, KeyEvent.KEYCODE_BACK,
5152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_CALL, KeyEvent.KEYCODE_ENDCALL,
5252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN,
5352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_MUTE,
5452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
5552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Nice names for all key events. */
5652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final String[] KEY_NAMES = {
5752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_UNKNOWN",
58a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        "KEYCODE_SOFT_LEFT",
5952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SOFT_RIGHT",
6052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_HOME",
6152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_BACK",
6252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_CALL",
6352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_ENDCALL",
6452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_0",
6552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_1",
6652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_2",
6752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_3",
6852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_4",
6952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_5",
7052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_6",
7152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_7",
7252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_8",
7352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_9",
7452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_STAR",
7552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_POUND",
7652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_DPAD_UP",
7752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_DPAD_DOWN",
7852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_DPAD_LEFT",
7952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_DPAD_RIGHT",
8052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_DPAD_CENTER",
8152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_VOLUME_UP",
8252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_VOLUME_DOWN",
8352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_POWER",
8452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_CAMERA",
8552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_CLEAR",
8652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_A",
8752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_B",
8852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_C",
8952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_D",
9052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_E",
9152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_F",
9252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_G",
9352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_H",
9452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_I",
9552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_J",
9652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_K",
9752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_L",
9852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_M",
9952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_N",
10052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_O",
10152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_P",
10252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_Q",
10352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_R",
10452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_S",
10552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_T",
10652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_U",
10752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_V",
10852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_W",
10952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_X",
11052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_Y",
11152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_Z",
11252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_COMMA",
11352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_PERIOD",
11452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_ALT_LEFT",
11552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_ALT_RIGHT",
11652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SHIFT_LEFT",
11752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SHIFT_RIGHT",
11852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_TAB",
11952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SPACE",
12052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SYM",
12152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_EXPLORER",
12252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_ENVELOPE",
12352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_ENTER",
12452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_DEL",
12552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_GRAVE",
12652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_MINUS",
12752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_EQUALS",
12852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_LEFT_BRACKET",
12952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_RIGHT_BRACKET",
13052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_BACKSLASH",
13152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SEMICOLON",
13252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_APOSTROPHE",
13352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SLASH",
13452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_AT",
13552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_NUM",
13652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_HEADSETHOOK",
13752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_FOCUS",
13852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_PLUS",
13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_MENU",
14052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_NOTIFICATION",
14152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_SEARCH",
14252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_PLAYPAUSE",
14352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_STOP",
14452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_NEXTSONG",
14552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_PREVIOUSSONG",
14652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_REWIND",
14752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_FORWARD",
14852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "KEYCODE_MUTE",
149a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
15052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        "TAG_LAST_KEYCODE"      // EOL.  used to keep the lists in sync
15152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
15252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
15352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_TOUCH        = 0;
15452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_MOTION       = 1;
15552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_TRACKBALL    = 2;
15652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_NAV          = 3;
15752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_MAJORNAV     = 4;
15852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_SYSOPS       = 5;
15952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_APPSWITCH    = 6;
16052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_FLIP         = 7;
161a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    public static final int FACTOR_ANYTHING     = 8;
16252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTORZ_COUNT       = 9;    // should be last+1
163a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
164a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
16552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** percentages for each type of event.  These will be remapped to working
16652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * values after we read any optional values.
167a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     **/
16852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private float[] mFactors = new float[FACTORZ_COUNT];
16952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private ArrayList<ComponentName> mMainApps;
17052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private int mEventCount = 0;  //total number of events generated so far
171565067aeb01670c05692e087ec214f8dd1a426edEvan Millar    private MonkeyEventQueue mQ;
172a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    private Random mRandom;
17352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private int mVerbose = 0;
17462c4d9bfc5eca4a7bd160e8fb67c0bbc066d9ce8Evan Millar    private long mThrottle = 0;
17552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
17652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private boolean mKeyboardOpen = false;
17752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
178a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
17952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @return the last name in the key list
18052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
18152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static String getLastKeyName() {
18252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return KEY_NAMES[KeyEvent.getMaxKeyCode() + 1];
18352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
184a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
18552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static String getKeyName(int keycode) {
18652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return KEY_NAMES[keycode];
18752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
188a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
189a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
190a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * Looks up the keyCode from a given KEYCODE_NAME.  NOTE: This may
191a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * be an expensive operation.
192a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
193a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @param keyName the name of the KEYCODE_VALUE to lookup.
194a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @returns the intenger keyCode value, or -1 if not found
195a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     */
196a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    public static int getKeyCode(String keyName) {
197a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        for (int x = 0; x < KEY_NAMES.length; x++) {
198a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            if (KEY_NAMES[x].equals(keyName)) {
199a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                return x;
200a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            }
201a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
202a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        return -1;
203a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    }
204a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
20562c4d9bfc5eca4a7bd160e8fb67c0bbc066d9ce8Evan Millar    public MonkeySourceRandom(long seed, ArrayList<ComponentName> MainApps, long throttle) {
20652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // default values for random distributions
20752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // note, these are straight percentages, to match user input (cmd line args)
20852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // but they will be converted to 0..1 values before the main loop runs.
20952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_TOUCH] = 15.0f;
21052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_MOTION] = 10.0f;
21152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_TRACKBALL] = 15.0f;
21252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_NAV] = 25.0f;
21352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_MAJORNAV] = 15.0f;
21452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_SYSOPS] = 2.0f;
21552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_APPSWITCH] = 2.0f;
21652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_FLIP] = 1.0f;
21752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_ANYTHING] = 15.0f;
218a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
21952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mRandom = new SecureRandom();
22052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mRandom.setSeed((seed == 0) ? -1 : seed);
22152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mMainApps = MainApps;
222565067aeb01670c05692e087ec214f8dd1a426edEvan Millar        mQ = new MonkeyEventQueue(throttle);
22352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
22452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
22552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
22652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Adjust the percentages (after applying user values) and then normalize to a 0..1 scale.
22752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
22852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private boolean adjustEventFactors() {
22952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // go through all values and compute totals for user & default values
23052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float userSum = 0.0f;
23152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultSum = 0.0f;
23252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int defaultCount = 0;
23352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
23452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mFactors[i] <= 0.0f) {   // user values are zero or negative
23552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                userSum -= mFactors[i];
23652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
23752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                defaultSum += mFactors[i];
23852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                ++defaultCount;
239a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            }
24052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
241a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
24252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if the user request was > 100%, reject it
24352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (userSum > 100.0f) {
24452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.err.println("** Event weights > 100%");
24552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return false;
24652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
247a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
24852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if the user specified all of the weights, then they need to be 100%
24952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (defaultCount == 0 && (userSum < 99.9f || userSum > 100.1f)) {
25052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.err.println("** Event weights != 100%");
25152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return false;
25252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
253a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
25452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // compute the adjustment necessary
25552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultsTarget = (100.0f - userSum);
25652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultsAdjustment = defaultsTarget / defaultSum;
257a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
25852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // fix all values, by adjusting defaults, or flipping user values back to >0
25952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
26052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mFactors[i] <= 0.0f) {   // user values are zero or negative
26152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mFactors[i] = -mFactors[i];
26252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
26352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mFactors[i] *= defaultsAdjustment;
26452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
26552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
266a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
26752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if verbose, show factors
268a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
26952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (mVerbose > 0) {
27052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.out.println("// Event percentages:");
27152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            for (int i = 0; i < FACTORZ_COUNT; ++i) {
27252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                System.out.println("//   " + i + ": " + mFactors[i] + "%");
27352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
274a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
275a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
27652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // finally, normalize and convert to running sum
27752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float sum = 0.0f;
27852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
27952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            sum += mFactors[i] / 100.0f;
28052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mFactors[i] = sum;
281a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
28252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return true;
28352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
284a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
28552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
28652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * set the factors
287a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
28820e7a15bb74d7349ee879bb311a0607325f49aafEric Rowe     * @param factors percentages for each type of event
28952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
29052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setFactors(float factors[]) {
29152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int c = FACTORZ_COUNT;
29252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (factors.length < c) {
29352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            c = factors.length;
294a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
29552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < c; i++)
29652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mFactors[i] = factors[i];
29752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
298a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
29952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setFactors(int index, float v) {
30052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[index] = v;
30152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
302a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
30352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
30452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Generates a random motion event. This method counts a down, move, and up as multiple events.
305a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
30652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Test & fix the selectors when non-zero percentages
30752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Longpress.
30852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Fling.
30952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Meta state
31052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  More useful than the random walk here would be to pick a single random direction
31152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * and distance, and divvy it up into a random number of segments.  (This would serve to
31252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate fling gestures, which are important).
313a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
31452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @param random Random number source for positioning
315a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @param motionEvent If false, touch/release.  If true, touch/move/release.
316a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
31752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
31852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private void generateMotionEvent(Random random, boolean motionEvent){
319a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
32052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
32152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
32252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float x = Math.abs(random.nextInt() % display.getWidth());
32352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float y = Math.abs(random.nextInt() % display.getHeight());
32452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        long downAt = SystemClock.uptimeMillis();
32552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        long eventTime = SystemClock.uptimeMillis();
32652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (downAt == -1) {
32752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            downAt = eventTime;
32852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
329a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
330a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        MonkeyMotionEvent e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
331a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                downAt, MotionEvent.ACTION_DOWN, x, y, 0);
332a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        e.setIntermediateNote(false);
33352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
334a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
33552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // sometimes we'll move during the touch
33652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (motionEvent) {
33752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int count = random.nextInt(10);
33852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            for (int i = 0; i < count; i++) {
33952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                // generate some slop in the up event
34052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                x = (x + (random.nextInt() % 10)) % display.getWidth();
34152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                y = (y + (random.nextInt() % 10)) % display.getHeight();
342a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
343a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
344a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                        downAt, MotionEvent.ACTION_MOVE, x, y, 0);
345a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                e.setIntermediateNote(true);
34652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mQ.addLast(e);
34752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
34852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
34952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
35052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // TODO generate some slop in the up event
351a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
352a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                downAt, MotionEvent.ACTION_UP, x, y, 0);
353a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        e.setIntermediateNote(false);
35452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
35552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
356a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
35752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
35852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Generates a random trackball event. This consists of a sequence of small moves, followed by
35952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * an optional single click.
360a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
36152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Longpress.
36252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Meta state
36352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Parameterize the % clicked
36452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  More useful than the random walk here would be to pick a single random direction
36552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * and distance, and divvy it up into a random number of segments.  (This would serve to
36652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate fling gestures, which are important).
367a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
36852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @param random Random number source for positioning
369a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
37052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
37152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private void generateTrackballEvent(Random random) {
37252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
37352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
37452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        boolean drop = false;
37552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int count = random.nextInt(10);
37652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyMotionEvent e;
37752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < 10; ++i) {
37852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            // generate a small random step
37952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int dX = random.nextInt(10) - 5;
38052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int dY = random.nextInt(10) - 5;
381a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
382a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
383a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1,
384a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                    MotionEvent.ACTION_MOVE, dX, dY, 0);
385a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e.setIntermediateNote(i > 0);
38652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
38752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
388a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
38952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // 10% of trackball moves end with a click
39052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (0 == random.nextInt(10)) {
39152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            long downAt = SystemClock.uptimeMillis();
392a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
393a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
394a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt,
395a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                    MotionEvent.ACTION_DOWN, 0, 0, 0);
396a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e.setIntermediateNote(true);
39752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
398a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
399a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
400a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt,
401a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                    MotionEvent.ACTION_UP, 0, 0, 0);
402a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e.setIntermediateNote(false);
40352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
404a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
40552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
406a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
407a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
40852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate a random event based on mFactor
40952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
410a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    private void generateEvents() {
41152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float cls = mRandom.nextFloat();
41252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int lastKey = 0;
41352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
41452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        boolean touchEvent = cls < mFactors[FACTOR_TOUCH];
41552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        boolean motionEvent = !touchEvent && (cls < mFactors[FACTOR_MOTION]);
416a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        if (touchEvent || motionEvent) {
41752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            generateMotionEvent(mRandom, motionEvent);
41852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
41952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
420a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
421a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        if (cls < mFactors[FACTOR_TRACKBALL]) {
42252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            generateTrackballEvent(mRandom);
42352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
42452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
42552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
42652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // The remaining event categories are injected as key events
42752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (cls < mFactors[FACTOR_NAV]) {
42852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            lastKey = NAV_KEYS[mRandom.nextInt(NAV_KEYS.length)];
42952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        } else if (cls < mFactors[FACTOR_MAJORNAV]) {
43052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            lastKey = MAJOR_NAV_KEYS[mRandom.nextInt(MAJOR_NAV_KEYS.length)];
43152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        } else if (cls < mFactors[FACTOR_SYSOPS]) {
43252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            lastKey = SYS_KEYS[mRandom.nextInt(SYS_KEYS.length)];
43352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        } else if (cls < mFactors[FACTOR_APPSWITCH]) {
43452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
43552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                    mRandom.nextInt(mMainApps.size())));
43652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
43752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
43852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        } else if (cls < mFactors[FACTOR_FLIP]) {
43952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
44052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mKeyboardOpen = !mKeyboardOpen;
44152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
44252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
44352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        } else {
44452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
44552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
446a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
44752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey);
44852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
449a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
45052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
45152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
45252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
453a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
45452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public boolean validate() {
45552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        //check factors
45652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return adjustEventFactors();
45752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
458a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
45952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setVerbose(int verbose) {
46052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mVerbose = verbose;
46152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
462a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
46352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
46452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate an activity event
46552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
46652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void generateActivity() {
46752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
46852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mRandom.nextInt(mMainApps.size())));
46952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
47052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
471a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
47252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
47352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * if the queue is empty, we generate events first
474a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @return the first event in the queue
47552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
47652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public MonkeyEvent getNextEvent() {
47752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (mQ.isEmpty()) {
47852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                generateEvents();
479a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
480a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        mEventCount++;
481a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        MonkeyEvent e = mQ.getFirst();
482a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        mQ.removeFirst();
48352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return e;
48452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
48552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project}
486