/** generate a random event based on mFactor */
  private void generateEvents() {
    float cls = mRandom.nextFloat();
    int lastKey = 0;

    if (cls < mFactors[FACTOR_TOUCH]) {
      generatePointerEvent(mRandom, GESTURE_TAP);
      return;
    } else if (cls < mFactors[FACTOR_MOTION]) {
      generatePointerEvent(mRandom, GESTURE_DRAG);
      return;
    } else if (cls < mFactors[FACTOR_PINCHZOOM]) {
      generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM);
      return;
    } else if (cls < mFactors[FACTOR_TRACKBALL]) {
      generateTrackballEvent(mRandom);
      return;
    } else if (cls < mFactors[FACTOR_ROTATION]) {
      generateRotationEvent(mRandom);
      return;
    }

    // The remaining event categories are injected as key events
    for (; ; ) {
      if (cls < mFactors[FACTOR_NAV]) {
        lastKey = NAV_KEYS[mRandom.nextInt(NAV_KEYS.length)];
      } else if (cls < mFactors[FACTOR_MAJORNAV]) {
        lastKey = MAJOR_NAV_KEYS[mRandom.nextInt(MAJOR_NAV_KEYS.length)];
      } else if (cls < mFactors[FACTOR_SYSOPS]) {
        lastKey = SYS_KEYS[mRandom.nextInt(SYS_KEYS.length)];
      } else if (cls < mFactors[FACTOR_APPSWITCH]) {
        MonkeyActivityEvent e =
            new MonkeyActivityEvent(mMainApps.get(mRandom.nextInt(mMainApps.size())));
        mQ.addLast(e);
        return;
      } else if (cls < mFactors[FACTOR_FLIP]) {
        MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
        mKeyboardOpen = !mKeyboardOpen;
        mQ.addLast(e);
        return;
      } else {
        lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
      }

      if (lastKey != KeyEvent.KEYCODE_POWER
          && lastKey != KeyEvent.KEYCODE_ENDCALL
          && PHYSICAL_KEY_EXISTS[lastKey]) {
        break;
      }
    }

    MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey);
    mQ.addLast(e);

    e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
    mQ.addLast(e);
  }