public void typeKey(
     double sec,
     final int charCode,
     final int keyCode,
     final boolean alt,
     final boolean ctrl,
     final boolean shift,
     final int delay,
     final boolean async) {
   if (!isSecure(sec)) return;
   // called by doh.robot._keyPress
   // see it for details
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           try {
             log("> typeKey Robot " + charCode + ", " + keyCode + ", " + async);
             KeyPressThread thread =
                 new KeyPressThread(
                     charCode, keyCode, alt, ctrl, shift, delay, async ? null : previousThread);
             previousThread = async ? previousThread : thread;
             thread.start();
             log("< typeKey Robot");
           } catch (Exception e) {
             log("Error calling typeKey");
             e.printStackTrace();
           }
           return null;
         }
       });
 }
 public void moveMouse(double sec, final int x1, final int y1, final int d, final int duration) {
   // called by doh.robot.mouseMove
   // see it for details
   // a nice name like "mouseMove" is reserved in Java
   if (!isSecure(sec)) return;
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           int x = x1 + docScreenX;
           int y = y1 + docScreenY;
           if (x > docScreenXMax || y > docScreenYMax) {
             // TODO: try to scroll view
             log("Request to mouseMove denied");
             return null;
           }
           int delay = d;
           log("> mouseMove Robot " + x + ", " + y);
           MouseMoveThread thread = new MouseMoveThread(x, y, delay, duration, previousThread);
           previousThread = thread;
           thread.start();
           log("< mouseMove Robot");
           return null;
         }
       });
 }
    public void componentShown(ComponentEvent evt) {
      // sets the security manager to fix a bug in liveconnect in Safari on Mac
      if (key != -1) {
        return;
      }
      window = (JSObject) JSObject.getWindow(applet());

      AccessController.doPrivileged(
          new PrivilegedAction() {
            public Object run() {
              log("> init Robot");
              try {
                SecurityManager oldsecurity = System.getSecurityManager();
                boolean isOpera = false;
                try {
                  isOpera = (System.getProperty("browser").equals("Opera.plugin"));
                } catch (Exception e) {
                }
                try {
                  securitymanager = oldsecurity;
                  securitymanager.checkTopLevelWindow(null);
                  // xdomain
                  if (charMap == null) {
                    if (!confirm(
                        "DOH has detected that the current Web page is attempting to access DOH, but belongs to a different domain than the one you agreed to let DOH automate. If you did not intend to start a new DOH test by visiting this Web page, press Cancel now and leave the Web page. Otherwise, press OK to trust this domain to automate DOH tests.")) {
                      stop();
                      return null;
                    }
                  }
                  log("Found old security manager");
                } catch (Exception e) {
                  e.printStackTrace();
                  log("Making new security manager");
                  securitymanager = new RobotSecurityManager(isOpera, oldsecurity);
                  securitymanager.checkTopLevelWindow(null);
                  System.setSecurityManager(securitymanager);
                }
                // instantiate the Robot
                robot = new Robot();
              } catch (Exception e) {
                log("Error calling _init_: " + e.getMessage());
                key = -2;
                e.printStackTrace();
              }
              log("< init Robot");
              return null;
            }
          });
      if (key == -2) {
        // applet not trusted
        // start the test without it
        window.eval("doh.robot._appletDead=true;doh.run();");
      } else {
        // now that the applet has really started, let doh know it's ok to use it
        log("_initRobot");
        dohrobot = (JSObject) window.eval("doh.robot");
        dohrobot.call("_initRobot", new Object[] {applet()});
      }
    }
 private void alert(final String s) {
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           window.eval("top.alert(\"" + s + "\");");
           return null;
         }
       });
 }
 public void log(final String s) {
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           System.out.println((new Date()).toString() + ": " + s);
           return null;
         }
       });
 }
 private boolean confirm(final String s) {
   return ((Boolean)
           AccessController.doPrivileged(
               new PrivilegedAction() {
                 public Object run() {
                   return ((Boolean) window.eval("top.confirm(\"" + s + "\");"));
                 }
               }))
       .booleanValue();
 }
 public void wheelMouse(double sec, final int amount, final int delay, final int duration) {
   // called by doh.robot.mouseWheel
   // see it for details
   if (!isSecure(sec)) return;
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           MouseWheelThread thread = new MouseWheelThread(amount, delay, duration, previousThread);
           previousThread = thread;
           thread.start();
           return null;
         }
       });
 }
 public void downKey(double sec, final int charCode, final int keyCode, final int delay) {
   // called by doh.robot.keyUp
   // see it for details
   // a nice name like "keyDown" is reserved in Java
   if (!isSecure(sec)) return;
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           log("> downKey Robot " + charCode + ", " + keyCode);
           KeyDownThread thread = new KeyDownThread(charCode, keyCode, delay, previousThread);
           previousThread = thread;
           thread.start();
           log("< downKey Robot");
           return null;
         }
       });
 }
 // java.awt.Applet methods
 public void stop() {
   window = null;
   // only secure code run once
   if (key != -2) {
     // prevent further execution of secure functions
     key = -2;
     // Java calls this when you close the window.
     // It plays nice and restores the old security manager.
     AccessController.doPrivileged(
         new PrivilegedAction() {
           public Object run() {
             log("Stop");
             securitymanager.checkTopLevelWindow(null);
             log("Security manager reset");
             return null;
           }
         });
   }
 }
 public void releaseMouse(
     double sec, final boolean left, final boolean middle, final boolean right, final int delay) {
   if (!isSecure(sec)) return;
   // called by doh.robot.mouseRelease
   // see it for details
   // a nice name like "mouseRelease" is reserved in Java
   AccessController.doPrivileged(
       new PrivilegedAction() {
         public Object run() {
           log("> mouseRelease Robot " + left + ", " + middle + ", " + right);
           MouseReleaseThread thread =
               new MouseReleaseThread(
                   (left ? InputEvent.BUTTON1_MASK : 0)
                       + (middle ? InputEvent.BUTTON2_MASK : 0)
                       + (right ? InputEvent.BUTTON3_MASK : 0),
                   delay,
                   previousThread);
           previousThread = thread;
           thread.start();
           log("< mouseRelease Robot");
           return null;
         }
       });
 }
  private void _typeKey(
      final int cCode, final int kCode, final boolean a, final boolean c, final boolean s) {
    AccessController.doPrivileged(
        new PrivilegedAction() {
          public Object run() {
            int charCode = cCode;
            int keyCode = kCode;
            boolean alt = a;
            boolean ctrl = c;
            boolean shift = s;
            boolean altgraph = false;
            log("> _typeKey Robot " + charCode + ", " + keyCode);
            try {
              int keyboardCode = getVKCode(charCode, keyCode);
              if (charCode >= 32) {
                // if it is printable, then it lives in our hashmap
                KeyEvent event = (KeyEvent) charMap.get(new Integer(charCode));
                // see if we need to press shift to generate this
                // character
                if (!shift) {
                  shift = event.isShiftDown();
                }
                altgraph = event.isAltGraphDown();
                keyboardCode = event.getKeyCode();
              }

              // run through exemption list
              if (!isUnsafe(keyboardCode)) {
                if (shift) {
                  log("Pressing shift");
                  robot.keyPress(KeyEvent.VK_SHIFT);
                }
                if (alt) {
                  log("Pressing alt");
                  robot.keyPress(KeyEvent.VK_ALT);
                }
                if (altgraph) {
                  log("Pressing altgraph");
                  robot.keyPress(KeyEvent.VK_ALT_GRAPH);
                }
                if (ctrl) {
                  log("Pressing ctrl");
                  robot.keyPress(KeyEvent.VK_CONTROL);
                }
                if (keyboardCode != KeyEvent.VK_SHIFT
                    && keyboardCode != KeyEvent.VK_ALT
                    && keyboardCode != KeyEvent.VK_CONTROL) {
                  try {
                    robot.keyPress(keyboardCode);
                    robot.keyRelease(keyboardCode);
                  } catch (Exception e) {
                    log("Error while actually typing a key");
                    e.printStackTrace();
                  }
                }
                if (ctrl) {
                  robot.keyRelease(KeyEvent.VK_CONTROL);
                  ctrl = false;
                }
                if (alt) {
                  robot.keyRelease(KeyEvent.VK_ALT);
                  alt = false;
                }
                if (altgraph) {
                  robot.keyRelease(KeyEvent.VK_ALT_GRAPH);
                  altgraph = false;
                }
                if (shift) {
                  log("Releasing shift");
                  robot.keyRelease(KeyEvent.VK_SHIFT);
                  shift = false;
                }
              }
            } catch (Exception e) {
              log("Error in _typeKey");
              e.printStackTrace();
            }
            log("< _typeKey Robot");
            return null;
          }
        });
  }
  public void _initKeyboard(double sec) {
    log("> initKeyboard");
    // javascript entry point to discover the keyboard
    if (!isSecure(sec)) return;
    if (charMap != null) {
      dohrobot.call("_onKeyboard", new Object[] {});
      return;
    }

    AccessController.doPrivileged(
        new PrivilegedAction() {
          public Object run() {
            charMap = new HashMap();
            KeyEvent event = new KeyEvent(applet(), 0, 0, 0, KeyEvent.VK_SPACE, ' ');
            charMap.put(new Integer(32), event);
            try {
              // a-zA-Z0-9 + 29 others
              vkKeys = new Vector();
              for (char i = 'a'; i <= 'z'; i++) {
                vkKeys.add(
                    new Integer(
                        KeyEvent.class
                            .getField("VK_" + Character.toUpperCase((char) i))
                            .getInt(null)));
              }
              for (char i = '0'; i <= '9'; i++) {
                vkKeys.add(
                    new Integer(
                        KeyEvent.class
                            .getField("VK_" + Character.toUpperCase((char) i))
                            .getInt(null)));
              }
              int[] mykeys =
                  new int[] {
                    KeyEvent.VK_COMMA,
                    KeyEvent.VK_MINUS,
                    KeyEvent.VK_PERIOD,
                    KeyEvent.VK_SLASH,
                    KeyEvent.VK_SEMICOLON,
                    KeyEvent.VK_LEFT_PARENTHESIS,
                    KeyEvent.VK_NUMBER_SIGN,
                    KeyEvent.VK_PLUS,
                    KeyEvent.VK_RIGHT_PARENTHESIS,
                    KeyEvent.VK_UNDERSCORE,
                    KeyEvent.VK_EXCLAMATION_MARK,
                    KeyEvent.VK_DOLLAR,
                    KeyEvent.VK_CIRCUMFLEX,
                    KeyEvent.VK_AMPERSAND,
                    KeyEvent.VK_ASTERISK,
                    KeyEvent.VK_QUOTEDBL,
                    KeyEvent.VK_LESS,
                    KeyEvent.VK_GREATER,
                    KeyEvent.VK_BRACELEFT,
                    KeyEvent.VK_BRACERIGHT,
                    KeyEvent.VK_COLON,
                    KeyEvent.VK_BACK_QUOTE,
                    KeyEvent.VK_QUOTE,
                    KeyEvent.VK_OPEN_BRACKET,
                    KeyEvent.VK_BACK_SLASH,
                    KeyEvent.VK_CLOSE_BRACKET,
                    KeyEvent.VK_EQUALS
                  };
              for (int i = 0; i < mykeys.length; i++) {
                vkKeys.add(new Integer(mykeys[i]));
              }
            } catch (Exception e) {
              e.printStackTrace();
            }
            Thread thread =
                new Thread() {
                  public void run() {
                    robot.setAutoDelay(0);
                    log("< initKeyboard");
                    pressNext();
                  }
                };
            thread.start();
            return null;
          }
        });
  }