MonkeySourceRandom.java revision f083bd43a0c6b7bf1b88775ac0f1d0bec1281a75
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;
225ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wangimport android.view.KeyCharacterMap;
2352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.KeyEvent;
2452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.MotionEvent;
2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.WindowManagerImpl;
2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
2752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.ArrayList;
2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.Random;
2952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
3052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/**
3152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * monkey event queue
3252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */
33a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napierpublic class MonkeySourceRandom implements MonkeyEventSource {
3452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Key events that move around the UI. */
3552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] NAV_KEYS = {
3652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
3752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT,
3852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
3952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
4052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Key events that perform major navigation options (so shouldn't be sent
4152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * as much).
4252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
4352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] MAJOR_NAV_KEYS = {
4452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_MENU, /*KeyEvent.KEYCODE_SOFT_RIGHT,*/
4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_CENTER,
4652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
4752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Key events that perform system operations. */
4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] SYS_KEYS = {
4952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_HOME, KeyEvent.KEYCODE_BACK,
5052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_CALL, KeyEvent.KEYCODE_ENDCALL,
51f083bd43a0c6b7bf1b88775ac0f1d0bec1281a75Jeff Brown        KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE,
5252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_MUTE,
5352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
545ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    /** If a physical key exists? */
555ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    private static final boolean[] PHYSICAL_KEY_EXISTS = new boolean[KeyEvent.getMaxKeyCode() + 1];
565ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    static {
575ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        for (int i = 0; i < PHYSICAL_KEY_EXISTS.length; ++i) {
585ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            PHYSICAL_KEY_EXISTS[i] = true;
595ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
605ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        // Only examine SYS_KEYS
615ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        for (int i = 0; i < SYS_KEYS.length; ++i) {
625ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            PHYSICAL_KEY_EXISTS[SYS_KEYS[i]] = KeyCharacterMap.deviceHasKey(SYS_KEYS[i]);
635ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
645ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    }
655ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
6652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_TOUCH        = 0;
6752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_MOTION       = 1;
6852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_TRACKBALL    = 2;
6952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_NAV          = 3;
7052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_MAJORNAV     = 4;
7152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_SYSOPS       = 5;
7252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_APPSWITCH    = 6;
7352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_FLIP         = 7;
74a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    public static final int FACTOR_ANYTHING     = 8;
7552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTORZ_COUNT       = 9;    // should be last+1
76a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
77a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
7852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** percentages for each type of event.  These will be remapped to working
7952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * values after we read any optional values.
80a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     **/
8152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private float[] mFactors = new float[FACTORZ_COUNT];
8252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private ArrayList<ComponentName> mMainApps;
8352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private int mEventCount = 0;  //total number of events generated so far
84565067aeb01670c05692e087ec214f8dd1a426edEvan Millar    private MonkeyEventQueue mQ;
85a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    private Random mRandom;
8652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private int mVerbose = 0;
8762c4d9bfc5eca4a7bd160e8fb67c0bbc066d9ce8Evan Millar    private long mThrottle = 0;
8852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
8952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private boolean mKeyboardOpen = false;
9052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
9152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static String getKeyName(int keycode) {
92b0b841029ad7592e8082e59e56645f84b06c558dJeff Brown        return KeyEvent.keyCodeToString(keycode);
9352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
94a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
95a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
96a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * Looks up the keyCode from a given KEYCODE_NAME.  NOTE: This may
97a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * be an expensive operation.
98a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
99a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @param keyName the name of the KEYCODE_VALUE to lookup.
100a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @returns the intenger keyCode value, or -1 if not found
101a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     */
102a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    public static int getKeyCode(String keyName) {
103b0b841029ad7592e8082e59e56645f84b06c558dJeff Brown        return KeyEvent.keyCodeFromString(keyName);
104a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    }
105a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
106bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang    public MonkeySourceRandom(Random random, ArrayList<ComponentName> MainApps,
107bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang            long throttle, boolean randomizeThrottle) {
10852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // default values for random distributions
10952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // note, these are straight percentages, to match user input (cmd line args)
11052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // but they will be converted to 0..1 values before the main loop runs.
11152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_TOUCH] = 15.0f;
11252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_MOTION] = 10.0f;
11352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_TRACKBALL] = 15.0f;
11452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_NAV] = 25.0f;
11552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_MAJORNAV] = 15.0f;
11652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_SYSOPS] = 2.0f;
11752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_APPSWITCH] = 2.0f;
11852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_FLIP] = 1.0f;
11952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_ANYTHING] = 15.0f;
120a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
121bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang        mRandom = random;
12252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mMainApps = MainApps;
123bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang        mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
12452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
12552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
12652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
12752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Adjust the percentages (after applying user values) and then normalize to a 0..1 scale.
12852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
12952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private boolean adjustEventFactors() {
13052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // go through all values and compute totals for user & default values
13152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float userSum = 0.0f;
13252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultSum = 0.0f;
13352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int defaultCount = 0;
13452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
13552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mFactors[i] <= 0.0f) {   // user values are zero or negative
13652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                userSum -= mFactors[i];
13752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
13852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                defaultSum += mFactors[i];
13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                ++defaultCount;
140a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            }
14152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
142a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
14352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if the user request was > 100%, reject it
14452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (userSum > 100.0f) {
14552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.err.println("** Event weights > 100%");
14652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return false;
14752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
148a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
14952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if the user specified all of the weights, then they need to be 100%
15052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (defaultCount == 0 && (userSum < 99.9f || userSum > 100.1f)) {
15152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.err.println("** Event weights != 100%");
15252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return false;
15352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
154a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
15552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // compute the adjustment necessary
15652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultsTarget = (100.0f - userSum);
15752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultsAdjustment = defaultsTarget / defaultSum;
158a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
15952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // fix all values, by adjusting defaults, or flipping user values back to >0
16052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
16152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mFactors[i] <= 0.0f) {   // user values are zero or negative
16252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mFactors[i] = -mFactors[i];
16352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
16452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mFactors[i] *= defaultsAdjustment;
16552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
16652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
167a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
16852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if verbose, show factors
16952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (mVerbose > 0) {
17052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.out.println("// Event percentages:");
17152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            for (int i = 0; i < FACTORZ_COUNT; ++i) {
17252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                System.out.println("//   " + i + ": " + mFactors[i] + "%");
17352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
174a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
175a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
1765ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        if (!validateKeys()) {
1775ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            return false;
1785ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
1795ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
18052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // finally, normalize and convert to running sum
18152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float sum = 0.0f;
18252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
18352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            sum += mFactors[i] / 100.0f;
18452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mFactors[i] = sum;
185a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
18652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return true;
18752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
188a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
1895ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    private static boolean validateKeyCategory(String catName, int[] keys, float factor) {
1905ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        if (factor < 0.1f) {
1915ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            return true;
1925ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
1935ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        for (int i = 0; i < keys.length; ++i) {
1945ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            if (PHYSICAL_KEY_EXISTS[keys[i]]) {
1955ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                return true;
1965ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            }
1975ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
1985ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        System.err.println("** " + catName + " has no physical keys but with factor " + factor + "%.");
1995ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        return false;
2005ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    }
2015ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
2025ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    /**
2035ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang     * See if any key exists for non-zero factors.
2045ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang     */
2055ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    private boolean validateKeys() {
2065ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        return validateKeyCategory("NAV_KEYS", NAV_KEYS, mFactors[FACTOR_NAV])
2075ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            && validateKeyCategory("MAJOR_NAV_KEYS", MAJOR_NAV_KEYS, mFactors[FACTOR_MAJORNAV])
2085ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            && validateKeyCategory("SYS_KEYS", SYS_KEYS, mFactors[FACTOR_SYSOPS]);
2095ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    }
2105ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
21152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
21252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * set the factors
213a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
21420e7a15bb74d7349ee879bb311a0607325f49aafEric Rowe     * @param factors percentages for each type of event
21552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
21652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setFactors(float factors[]) {
21752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int c = FACTORZ_COUNT;
21852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (factors.length < c) {
21952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            c = factors.length;
220a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
22152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < c; i++)
22252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mFactors[i] = factors[i];
22352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
224a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
22552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setFactors(int index, float v) {
22652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[index] = v;
22752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
228a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
22952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
23052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Generates a random motion event. This method counts a down, move, and up as multiple events.
231a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
23252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Test & fix the selectors when non-zero percentages
23352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Longpress.
23452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Fling.
23552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Meta state
23652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  More useful than the random walk here would be to pick a single random direction
23752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * and distance, and divvy it up into a random number of segments.  (This would serve to
23852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate fling gestures, which are important).
239a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
24052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @param random Random number source for positioning
241a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @param motionEvent If false, touch/release.  If true, touch/move/release.
242a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
24352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
24452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private void generateMotionEvent(Random random, boolean motionEvent){
245a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
24652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
24752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
24852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float x = Math.abs(random.nextInt() % display.getWidth());
24952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float y = Math.abs(random.nextInt() % display.getHeight());
25052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        long downAt = SystemClock.uptimeMillis();
25152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        long eventTime = SystemClock.uptimeMillis();
25252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (downAt == -1) {
25352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            downAt = eventTime;
25452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
255a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
256a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        MonkeyMotionEvent e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
257a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                downAt, MotionEvent.ACTION_DOWN, x, y, 0);
258a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        e.setIntermediateNote(false);
25952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
260a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
26152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // sometimes we'll move during the touch
26252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (motionEvent) {
26352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int count = random.nextInt(10);
26452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            for (int i = 0; i < count; i++) {
26552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                // generate some slop in the up event
26652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                x = (x + (random.nextInt() % 10)) % display.getWidth();
26752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                y = (y + (random.nextInt() % 10)) % display.getHeight();
268a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
269a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
270a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                        downAt, MotionEvent.ACTION_MOVE, x, y, 0);
271a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                e.setIntermediateNote(true);
27252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mQ.addLast(e);
27352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
27452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
27552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
27652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // TODO generate some slop in the up event
277a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER,
278a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                downAt, MotionEvent.ACTION_UP, x, y, 0);
279a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        e.setIntermediateNote(false);
28052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
28152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
282a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
28352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
28452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Generates a random trackball event. This consists of a sequence of small moves, followed by
28552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * an optional single click.
286a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
28752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Longpress.
28852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Meta state
28952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Parameterize the % clicked
29052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  More useful than the random walk here would be to pick a single random direction
29152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * and distance, and divvy it up into a random number of segments.  (This would serve to
29252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate fling gestures, which are important).
293a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
29452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @param random Random number source for positioning
295a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
29652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
29752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private void generateTrackballEvent(Random random) {
29852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
29952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
30052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        boolean drop = false;
30152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int count = random.nextInt(10);
30252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyMotionEvent e;
30352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < 10; ++i) {
30452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            // generate a small random step
30552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int dX = random.nextInt(10) - 5;
30652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int dY = random.nextInt(10) - 5;
307a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
308a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
309a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1,
310a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                    MotionEvent.ACTION_MOVE, dX, dY, 0);
311a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e.setIntermediateNote(i > 0);
31252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
31352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
314a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
31552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // 10% of trackball moves end with a click
31652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (0 == random.nextInt(10)) {
31752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            long downAt = SystemClock.uptimeMillis();
318a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
319a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
320a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt,
321a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                    MotionEvent.ACTION_DOWN, 0, 0, 0);
322a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e.setIntermediateNote(true);
32352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
324a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
325a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
326a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt,
327a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier                    MotionEvent.ACTION_UP, 0, 0, 0);
328a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            e.setIntermediateNote(false);
32952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mQ.addLast(e);
330a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
33152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
332a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
333a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
33452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate a random event based on mFactor
33552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
336a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    private void generateEvents() {
33752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float cls = mRandom.nextFloat();
33852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int lastKey = 0;
33952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
34052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        boolean touchEvent = cls < mFactors[FACTOR_TOUCH];
34152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        boolean motionEvent = !touchEvent && (cls < mFactors[FACTOR_MOTION]);
342a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        if (touchEvent || motionEvent) {
34352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            generateMotionEvent(mRandom, motionEvent);
34452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
34552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
346a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
347a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        if (cls < mFactors[FACTOR_TRACKBALL]) {
34852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            generateTrackballEvent(mRandom);
34952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
35052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
35152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
35252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // The remaining event categories are injected as key events
3535ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        do {
3545ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            if (cls < mFactors[FACTOR_NAV]) {
3555ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = NAV_KEYS[mRandom.nextInt(NAV_KEYS.length)];
3565ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_MAJORNAV]) {
3575ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = MAJOR_NAV_KEYS[mRandom.nextInt(MAJOR_NAV_KEYS.length)];
3585ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_SYSOPS]) {
3595ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = SYS_KEYS[mRandom.nextInt(SYS_KEYS.length)];
3605ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_APPSWITCH]) {
3615ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
3625ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                        mRandom.nextInt(mMainApps.size())));
3635ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                mQ.addLast(e);
3645ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                return;
3655ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_FLIP]) {
3665ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
3675ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                mKeyboardOpen = !mKeyboardOpen;
3685ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                mQ.addLast(e);
3695ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                return;
3705ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else {
3715ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
3725ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            }
3735ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        } while (!PHYSICAL_KEY_EXISTS[lastKey]);
374a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
37552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey);
37652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
377a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
37852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
37952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
38052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
381a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
38252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public boolean validate() {
38352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        //check factors
38452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return adjustEventFactors();
38552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
386a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
38752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setVerbose(int verbose) {
38852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mVerbose = verbose;
38952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
390a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
39152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
39252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate an activity event
39352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
39452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void generateActivity() {
39552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
39652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mRandom.nextInt(mMainApps.size())));
39752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
39852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
399a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
40052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
40152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * if the queue is empty, we generate events first
402a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @return the first event in the queue
40352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
40452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public MonkeyEvent getNextEvent() {
40552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (mQ.isEmpty()) {
40665440eb58d5ff9c728003e1d5420380c3a0af455Eric Rowe            generateEvents();
407a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
408a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        mEventCount++;
409a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        MonkeyEvent e = mQ.getFirst();
410a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        mQ.removeFirst();
41152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return e;
41252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
41352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project}
414