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;
20585ab9695077b48436032def57ff50f9d9ec316bJeff Brownimport android.graphics.PointF;
2160df6ce6b8e1f9519aafb5f87c21e07259b463d0Jeff Brownimport android.hardware.display.DisplayManagerGlobal;
2252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.os.SystemClock;
2352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.Display;
245ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wangimport android.view.KeyCharacterMap;
2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.KeyEvent;
2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.MotionEvent;
2746b674174bfded2506d4017ea8c8f3649245e7c1Ying Wangimport android.view.Surface;
2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
2952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.ArrayList;
3052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.Random;
3152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
3252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/**
3352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * monkey event queue
3452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */
35a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napierpublic class MonkeySourceRandom implements MonkeyEventSource {
3652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Key events that move around the UI. */
3752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] NAV_KEYS = {
3852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
3952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT,
4052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
4152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
4252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Key events that perform major navigation options (so shouldn't be sent
4352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * as much).
4452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] MAJOR_NAV_KEYS = {
4652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_MENU, /*KeyEvent.KEYCODE_SOFT_RIGHT,*/
4752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_DPAD_CENTER,
4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
4952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** Key events that perform system operations. */
5052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private static final int[] SYS_KEYS = {
5152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_HOME, KeyEvent.KEYCODE_BACK,
5252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_CALL, KeyEvent.KEYCODE_ENDCALL,
53f083bd43a0c6b7bf1b88775ac0f1d0bec1281a75Jeff Brown        KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE,
5452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        KeyEvent.KEYCODE_MUTE,
5552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    };
565ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    /** If a physical key exists? */
575ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    private static final boolean[] PHYSICAL_KEY_EXISTS = new boolean[KeyEvent.getMaxKeyCode() + 1];
585ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    static {
595ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        for (int i = 0; i < PHYSICAL_KEY_EXISTS.length; ++i) {
605ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            PHYSICAL_KEY_EXISTS[i] = true;
615ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
625ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        // Only examine SYS_KEYS
635ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        for (int i = 0; i < SYS_KEYS.length; ++i) {
645ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            PHYSICAL_KEY_EXISTS[SYS_KEYS[i]] = KeyCharacterMap.deviceHasKey(SYS_KEYS[i]);
655ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
665ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    }
6746b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang    /** Possible screen rotation degrees **/
6846b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang    private static final int[] SCREEN_ROTATION_DEGREES = {
6946b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang      Surface.ROTATION_0,
7046b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang      Surface.ROTATION_90,
7146b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang      Surface.ROTATION_180,
7246b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang      Surface.ROTATION_270,
7346b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang    };
745ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
7552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_TOUCH        = 0;
7652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static final int FACTOR_MOTION       = 1;
77585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    public static final int FACTOR_PINCHZOOM    = 2;
78056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_TRACKBALL    = 3;
79056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_ROTATION     = 4;
80056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_NAV          = 5;
81056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_MAJORNAV     = 6;
82056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_SYSOPS       = 7;
83056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_APPSWITCH    = 8;
84056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_FLIP         = 9;
85056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTOR_ANYTHING     = 10;
86056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang    public static final int FACTORZ_COUNT       = 11;    // should be last+1
87585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
88585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    private static final int GESTURE_TAP = 0;
89585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    private static final int GESTURE_DRAG = 1;
90585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    private static final int GESTURE_PINCH_OR_ZOOM = 2;
91a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
9252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /** percentages for each type of event.  These will be remapped to working
9352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * values after we read any optional values.
94a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     **/
9552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private float[] mFactors = new float[FACTORZ_COUNT];
9652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private ArrayList<ComponentName> mMainApps;
9752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private int mEventCount = 0;  //total number of events generated so far
98565067aeb01670c05692e087ec214f8dd1a426edEvan Millar    private MonkeyEventQueue mQ;
99a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    private Random mRandom;
10052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private int mVerbose = 0;
10162c4d9bfc5eca4a7bd160e8fb67c0bbc066d9ce8Evan Millar    private long mThrottle = 0;
10252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
10352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private boolean mKeyboardOpen = false;
10452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
10552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public static String getKeyName(int keycode) {
106b0b841029ad7592e8082e59e56645f84b06c558dJeff Brown        return KeyEvent.keyCodeToString(keycode);
10752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
108a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
109a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
110a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * Looks up the keyCode from a given KEYCODE_NAME.  NOTE: This may
111a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * be an expensive operation.
112a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
113a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @param keyName the name of the KEYCODE_VALUE to lookup.
1143d3d64250d93c63feef732e873632a67995e242fBill Napier     * @returns the intenger keyCode value, or KeyEvent.KEYCODE_UNKNOWN if not found
115a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     */
116a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    public static int getKeyCode(String keyName) {
117b0b841029ad7592e8082e59e56645f84b06c558dJeff Brown        return KeyEvent.keyCodeFromString(keyName);
118a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    }
119a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
120bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang    public MonkeySourceRandom(Random random, ArrayList<ComponentName> MainApps,
121bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang            long throttle, boolean randomizeThrottle) {
12252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // default values for random distributions
12352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // note, these are straight percentages, to match user input (cmd line args)
12452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // but they will be converted to 0..1 values before the main loop runs.
12552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_TOUCH] = 15.0f;
12652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_MOTION] = 10.0f;
12752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_TRACKBALL] = 15.0f;
12846b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang        // Adjust the values if we want to enable rotation by default.
12946b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang        mFactors[FACTOR_ROTATION] = 0.0f;
13052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_NAV] = 25.0f;
13152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_MAJORNAV] = 15.0f;
13252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_SYSOPS] = 2.0f;
13352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_APPSWITCH] = 2.0f;
13452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[FACTOR_FLIP] = 1.0f;
135056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang        mFactors[FACTOR_ANYTHING] = 13.0f;
136585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        mFactors[FACTOR_PINCHZOOM] = 2.0f;
137a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
138bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang        mRandom = random;
13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mMainApps = MainApps;
140bae45151532d761e6ca61c86ab1ecebfbb685b39Ying Wang        mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
14152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
14252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
14352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
14452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Adjust the percentages (after applying user values) and then normalize to a 0..1 scale.
14552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
14652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private boolean adjustEventFactors() {
14752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // go through all values and compute totals for user & default values
14852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float userSum = 0.0f;
14952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultSum = 0.0f;
15052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int defaultCount = 0;
15152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
15252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mFactors[i] <= 0.0f) {   // user values are zero or negative
15352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                userSum -= mFactors[i];
15452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
15552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                defaultSum += mFactors[i];
15652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                ++defaultCount;
157a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier            }
15852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
159a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
16052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if the user request was > 100%, reject it
16152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (userSum > 100.0f) {
16252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.err.println("** Event weights > 100%");
16352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return false;
16452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
165a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
16652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if the user specified all of the weights, then they need to be 100%
16752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (defaultCount == 0 && (userSum < 99.9f || userSum > 100.1f)) {
16852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.err.println("** Event weights != 100%");
16952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return false;
17052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
171a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
17252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // compute the adjustment necessary
17352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultsTarget = (100.0f - userSum);
17452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float defaultsAdjustment = defaultsTarget / defaultSum;
175a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
17652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // fix all values, by adjusting defaults, or flipping user values back to >0
17752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
17852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mFactors[i] <= 0.0f) {   // user values are zero or negative
17952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mFactors[i] = -mFactors[i];
18052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
18152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mFactors[i] *= defaultsAdjustment;
18252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
18352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
184a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
18552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // if verbose, show factors
18652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (mVerbose > 0) {
18752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            System.out.println("// Event percentages:");
18852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            for (int i = 0; i < FACTORZ_COUNT; ++i) {
18952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                System.out.println("//   " + i + ": " + mFactors[i] + "%");
19052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
191a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
192a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
1935ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        if (!validateKeys()) {
1945ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            return false;
1955ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
1965ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
19752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // finally, normalize and convert to running sum
19852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float sum = 0.0f;
19952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < FACTORZ_COUNT; ++i) {
20052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            sum += mFactors[i] / 100.0f;
20152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mFactors[i] = sum;
202a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
20352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return true;
20452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
205a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
2065ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    private static boolean validateKeyCategory(String catName, int[] keys, float factor) {
2075ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        if (factor < 0.1f) {
2085ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            return true;
2095ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
2105ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        for (int i = 0; i < keys.length; ++i) {
2115ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            if (PHYSICAL_KEY_EXISTS[keys[i]]) {
2125ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                return true;
2135ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            }
2145ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        }
2155ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        System.err.println("** " + catName + " has no physical keys but with factor " + factor + "%.");
2165ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        return false;
2175ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    }
2185ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
2195ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    /**
2205ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang     * See if any key exists for non-zero factors.
2215ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang     */
2225ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    private boolean validateKeys() {
2235ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang        return validateKeyCategory("NAV_KEYS", NAV_KEYS, mFactors[FACTOR_NAV])
2245ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            && validateKeyCategory("MAJOR_NAV_KEYS", MAJOR_NAV_KEYS, mFactors[FACTOR_MAJORNAV])
2255ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            && validateKeyCategory("SYS_KEYS", SYS_KEYS, mFactors[FACTOR_SYSOPS]);
2265ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang    }
2275ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang
22852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
22952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * set the factors
230a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
23120e7a15bb74d7349ee879bb311a0607325f49aafEric Rowe     * @param factors percentages for each type of event
23252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
23352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setFactors(float factors[]) {
23452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int c = FACTORZ_COUNT;
23552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (factors.length < c) {
23652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            c = factors.length;
237a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
23852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < c; i++)
23952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            mFactors[i] = factors[i];
24052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
241a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
24252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setFactors(int index, float v) {
24352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mFactors[index] = v;
24452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
245a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
24652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
24752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Generates a random motion event. This method counts a down, move, and up as multiple events.
248a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
24952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Test & fix the selectors when non-zero percentages
25052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Longpress.
25152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Fling.
25252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Meta state
25352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  More useful than the random walk here would be to pick a single random direction
25452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * and distance, and divvy it up into a random number of segments.  (This would serve to
25552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate fling gestures, which are important).
256a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
25752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @param random Random number source for positioning
258585ab9695077b48436032def57ff50f9d9ec316bJeff Brown     * @param gesture The gesture to perform.
259a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
26052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
261f9fc2a56f18b5d9684b48f0fe7a4e3b24eab5847Jeff Brown    private void generatePointerEvent(Random random, int gesture) {
262056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang        Display display = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
263585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
26447937eb6b2669060da7526cf66a3d9e4f6e35244Ying Wang        PointF p1 = randomPoint(random, display);
26547937eb6b2669060da7526cf66a3d9e4f6e35244Ying Wang        PointF v1 = randomVector(random);
266a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
267056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang        long downAt = SystemClock.uptimeMillis();
268056d0a598a6a2e53256005a0c8722e02749d37f2Ying Wang
269585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
270585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                .setDownTime(downAt)
271585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                .addPointer(0, p1.x, p1.y)
272585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                .setIntermediateNote(false));
273a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
27452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // sometimes we'll move during the touch
275585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        if (gesture == GESTURE_DRAG) {
27652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int count = random.nextInt(10);
27752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            for (int i = 0; i < count; i++) {
278585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                randomWalk(random, display, p1, v1);
279585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
280585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
281585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                        .setDownTime(downAt)
282585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                        .addPointer(0, p1.x, p1.y)
283585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                        .setIntermediateNote(true));
28452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
285585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        } else if (gesture == GESTURE_PINCH_OR_ZOOM) {
286585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            PointF p2 = randomPoint(random, display);
287585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            PointF v2 = randomVector(random);
288585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
289585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            randomWalk(random, display, p1, v1);
290585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
291585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                            | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
292585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setDownTime(downAt)
293585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .addPointer(0, p1.x, p1.y).addPointer(1, p2.x, p2.y)
294585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setIntermediateNote(true));
295585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
296585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            int count = random.nextInt(10);
297585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            for (int i = 0; i < count; i++) {
298585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                randomWalk(random, display, p1, v1);
299585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                randomWalk(random, display, p2, v2);
300585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
301585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE)
302585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                        .setDownTime(downAt)
303585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                        .addPointer(0, p1.x, p1.y).addPointer(1, p2.x, p2.y)
304585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                        .setIntermediateNote(true));
305585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            }
306585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
307585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            randomWalk(random, display, p1, v1);
308585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            randomWalk(random, display, p2, v2);
309585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_UP
310585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                            | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
311585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setDownTime(downAt)
312585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .addPointer(0, p1.x, p1.y).addPointer(1, p2.x, p2.y)
313585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setIntermediateNote(true));
31452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
31552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
316585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        randomWalk(random, display, p1, v1);
317585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_UP)
318585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                .setDownTime(downAt)
319585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                .addPointer(0, p1.x, p1.y)
320585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                .setIntermediateNote(false));
321585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    }
322585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
323585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    private PointF randomPoint(Random random, Display display) {
324585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        return new PointF(random.nextInt(display.getWidth()), random.nextInt(display.getHeight()));
325585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    }
326585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
327585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    private PointF randomVector(Random random) {
328585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        return new PointF((random.nextFloat() - 0.5f) * 50, (random.nextFloat() - 0.5f) * 50);
329585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    }
330585ab9695077b48436032def57ff50f9d9ec316bJeff Brown
331585ab9695077b48436032def57ff50f9d9ec316bJeff Brown    private void randomWalk(Random random, Display display, PointF point, PointF vector) {
332585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        point.x = (float) Math.max(Math.min(point.x + random.nextFloat() * vector.x,
333585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                display.getWidth()), 0);
334585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        point.y = (float) Math.max(Math.min(point.y + random.nextFloat() * vector.y,
335585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                display.getHeight()), 0);
33652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
337a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
33852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
33952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * Generates a random trackball event. This consists of a sequence of small moves, followed by
34052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * an optional single click.
341a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
34252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Longpress.
34352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Meta state
34452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  Parameterize the % clicked
34552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * TODO:  More useful than the random walk here would be to pick a single random direction
34652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * and distance, and divvy it up into a random number of segments.  (This would serve to
34752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate fling gestures, which are important).
348a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
34952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * @param random Random number source for positioning
350a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     *
35152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
35252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    private void generateTrackballEvent(Random random) {
35352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        for (int i = 0; i < 10; ++i) {
35452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            // generate a small random step
35552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int dX = random.nextInt(10) - 5;
35652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            int dY = random.nextInt(10) - 5;
357a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
358585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_MOVE)
359585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .addPointer(0, dX, dY)
360585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setIntermediateNote(i > 0));
36152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
362a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
36352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // 10% of trackball moves end with a click
36452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (0 == random.nextInt(10)) {
36552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            long downAt = SystemClock.uptimeMillis();
366a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
367585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_DOWN)
368585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setDownTime(downAt)
369585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .addPointer(0, 0, 0)
370585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setIntermediateNote(true));
371a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
372585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            mQ.addLast(new MonkeyTrackballEvent(MotionEvent.ACTION_UP)
373585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setDownTime(downAt)
374585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .addPointer(0, 0, 0)
375585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                    .setIntermediateNote(false));
376a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
37752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
378a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
379a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    /**
38046b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang     * Generates a random screen rotation event.
38146b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang     *
38246b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang     * @param random Random number source for rotation degree.
38346b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang     */
38446b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang    private void generateRotationEvent(Random random) {
38546b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang        mQ.addLast(new MonkeyRotationEvent(
38646b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang                SCREEN_ROTATION_DEGREES[random.nextInt(
38746b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang                        SCREEN_ROTATION_DEGREES.length)],
38846b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang                random.nextBoolean()));
38946b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang    }
39046b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang
39146b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang    /**
39252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate a random event based on mFactor
39352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
394a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier    private void generateEvents() {
39552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        float cls = mRandom.nextFloat();
39652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        int lastKey = 0;
39752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
398585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        if (cls < mFactors[FACTOR_TOUCH]) {
399585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            generatePointerEvent(mRandom, GESTURE_TAP);
40052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
401585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        } else if (cls < mFactors[FACTOR_MOTION]) {
402585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            generatePointerEvent(mRandom, GESTURE_DRAG);
403585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            return;
404585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        } else if (cls < mFactors[FACTOR_PINCHZOOM]) {
405585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM);
406585ab9695077b48436032def57ff50f9d9ec316bJeff Brown            return;
407585ab9695077b48436032def57ff50f9d9ec316bJeff Brown        } else if (cls < mFactors[FACTOR_TRACKBALL]) {
40852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            generateTrackballEvent(mRandom);
40952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            return;
41046b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang        } else if (cls < mFactors[FACTOR_ROTATION]) {
41146b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang            generateRotationEvent(mRandom);
41246b674174bfded2506d4017ea8c8f3649245e7c1Ying Wang            return;
41352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
41452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
41552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        // The remaining event categories are injected as key events
41682df76b040cc13c2df4be141edfb2d29e439f57aJeff Brown        for (;;) {
4175ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            if (cls < mFactors[FACTOR_NAV]) {
4185ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = NAV_KEYS[mRandom.nextInt(NAV_KEYS.length)];
4195ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_MAJORNAV]) {
4205ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = MAJOR_NAV_KEYS[mRandom.nextInt(MAJOR_NAV_KEYS.length)];
4215ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_SYSOPS]) {
4225ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = SYS_KEYS[mRandom.nextInt(SYS_KEYS.length)];
4235ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_APPSWITCH]) {
4245ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
4255ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                        mRandom.nextInt(mMainApps.size())));
4265ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                mQ.addLast(e);
4275ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                return;
4285ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else if (cls < mFactors[FACTOR_FLIP]) {
4295ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
4305ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                mKeyboardOpen = !mKeyboardOpen;
4315ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                mQ.addLast(e);
4325ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                return;
4335ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            } else {
4345ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang                lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
4355ee69f6f2c35a6e68bb0428bfb853b873313cbb4Ying Wang            }
4368a2659dc0db131ec6c01e5bfc25185dd51aa1275Jeff Brown
43782df76b040cc13c2df4be141edfb2d29e439f57aJeff Brown            if (lastKey != KeyEvent.KEYCODE_POWER
43882df76b040cc13c2df4be141edfb2d29e439f57aJeff Brown                    && lastKey != KeyEvent.KEYCODE_ENDCALL
439644b8222183d57dafd8de98e04756cbd28b7ae80Guang Zhu                    && lastKey != KeyEvent.KEYCODE_SLEEP
44082df76b040cc13c2df4be141edfb2d29e439f57aJeff Brown                    && PHYSICAL_KEY_EXISTS[lastKey]) {
44182df76b040cc13c2df4be141edfb2d29e439f57aJeff Brown                break;
4428a2659dc0db131ec6c01e5bfc25185dd51aa1275Jeff Brown            }
44382df76b040cc13c2df4be141edfb2d29e439f57aJeff Brown        }
444a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
44552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey);
44652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
447a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
44852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
44952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
45052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
451a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
45252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public boolean validate() {
45352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        //check factors
45452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return adjustEventFactors();
45552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
456a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
45752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setVerbose(int verbose) {
45852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mVerbose = verbose;
45952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
460a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
46152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
46252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * generate an activity event
46352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
46452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void generateActivity() {
46552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
46652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                mRandom.nextInt(mMainApps.size())));
46752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mQ.addLast(e);
46852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
469a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier
47052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    /**
47152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     * if the queue is empty, we generate events first
472a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier     * @return the first event in the queue
47352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project     */
47452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public MonkeyEvent getNextEvent() {
47552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (mQ.isEmpty()) {
47665440eb58d5ff9c728003e1d5420380c3a0af455Eric Rowe            generateEvents();
477a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        }
478a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        mEventCount++;
479a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        MonkeyEvent e = mQ.getFirst();
480a68dbdb1c31c486f489f38291eea05b3c621ae36Bill Napier        mQ.removeFirst();
48152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return e;
48252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
48352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project}
484