17169aa30eeaac89c49984bb9d061ca152d43391aBill Napier/*
27169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * Copyright (C) 2010 The Android Open Source Project
37169aa30eeaac89c49984bb9d061ca152d43391aBill Napier *
47169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * Licensed under the Apache License, Version 2.0 (the "License");
57169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * you may not use this file except in compliance with the License.
67169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * You may obtain a copy of the License at
77169aa30eeaac89c49984bb9d061ca152d43391aBill Napier *
87169aa30eeaac89c49984bb9d061ca152d43391aBill Napier *      http://www.apache.org/licenses/LICENSE-2.0
97169aa30eeaac89c49984bb9d061ca152d43391aBill Napier *
107169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * Unless required by applicable law or agreed to in writing, software
117169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * distributed under the License is distributed on an "AS IS" BASIS,
127169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * See the License for the specific language governing permissions and
147169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * limitations under the License.
157169aa30eeaac89c49984bb9d061ca152d43391aBill Napier */
167169aa30eeaac89c49984bb9d061ca152d43391aBill Napierpackage com.android.monkeyrunner.controller;
177169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
188c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wrightimport com.android.chimpchat.core.PhysicalButton;
198c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wrightimport com.android.chimpchat.core.TouchPressType;
208c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wrightimport com.android.chimpchat.core.IChimpImage;
218c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wrightimport com.android.chimpchat.core.IChimpDevice;
227169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
237169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.KeyEventDispatcher;
247169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.KeyboardFocusManager;
257169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.event.ActionEvent;
267169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.event.ActionListener;
277169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.event.KeyEvent;
287169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.event.MouseAdapter;
297169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.event.MouseEvent;
307169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.awt.image.BufferedImage;
317169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.io.IOException;
327169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport java.util.logging.Logger;
337169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
347169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.AbstractAction;
357169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.BoxLayout;
367169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.ImageIcon;
377169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.JButton;
387169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.JFrame;
397169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.JLabel;
407169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.JToolBar;
417169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.SwingUtilities;
427169aa30eeaac89c49984bb9d061ca152d43391aBill Napierimport javax.swing.Timer;
437169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
447169aa30eeaac89c49984bb9d061ca152d43391aBill Napier/**
457169aa30eeaac89c49984bb9d061ca152d43391aBill Napier * Main window for MonkeyController.
467169aa30eeaac89c49984bb9d061ca152d43391aBill Napier */
477169aa30eeaac89c49984bb9d061ca152d43391aBill Napierpublic class MonkeyControllerFrame extends JFrame {
487169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private static final Logger LOG = Logger.getLogger(MonkeyControllerFrame.class.getName());
497169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
507169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private final JButton refreshButton = new JButton("Refresh");
517169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private final JButton variablesButton = new JButton("Variable");
527169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private final JLabel imageLabel = new JLabel();
537169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private final VariableFrame variableFrame;
547169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
558c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright    private final IChimpDevice device;
567169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private BufferedImage currentImage;
577169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
588c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright    private final TouchPressType DOWN_AND_UP = TouchPressType.DOWN_AND_UP;
598c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright
607169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private final Timer timer = new Timer(1000, new ActionListener() {
617169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        public void actionPerformed(ActionEvent e) {
627169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            updateScreen();
637169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        }
647169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    });
657169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
667169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private class PressAction extends AbstractAction {
677169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        private final PhysicalButton button;
687169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
697169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        public PressAction(PhysicalButton button) {
707169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            this.button = button;
717169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        }
728c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright        /* When this fails, it no longer throws a runtime exception,
738c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright         * but merely will log the failure.
748c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright         */
757169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        public void actionPerformed(ActionEvent event) {
768c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright            device.press(button.getKeyName(), DOWN_AND_UP);
777169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            updateScreen();
787169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        }
797169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    }
807169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
817169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private JButton createToolbarButton(PhysicalButton hardButton) {
827169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        JButton button = new JButton(new PressAction(hardButton));
837169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        button.setText(hardButton.getKeyName());
847169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        return button;
857169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    }
867169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
878c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright    public MonkeyControllerFrame(IChimpDevice chimpDevice) {
887169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        super("MonkeyController");
898c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright        this.device = chimpDevice;
907169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
917169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
927169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
937169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
947169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        JToolBar toolbar = new JToolBar();
957169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
967169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        toolbar.add(createToolbarButton(PhysicalButton.HOME));
977169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        toolbar.add(createToolbarButton(PhysicalButton.BACK));
987169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        toolbar.add(createToolbarButton(PhysicalButton.SEARCH));
997169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        toolbar.add(createToolbarButton(PhysicalButton.MENU));
1007169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1017169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        add(toolbar);
1027169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        add(refreshButton);
1037169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        add(variablesButton);
1047169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        add(imageLabel);
1057169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1067169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        refreshButton.addActionListener(new ActionListener() {
1077169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            public void actionPerformed(ActionEvent e) {
1087169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                updateScreen();
1097169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            }
1107169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        });
1117169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1127169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        variableFrame = new VariableFrame();
1137169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        variablesButton.addActionListener(new ActionListener() {
1147169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            public void actionPerformed(ActionEvent e) {
1157169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                variableFrame.setVisible(true);
1167169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            }
1177169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        });
1187169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1198c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright        /* Similar to above, when the following two methods fail, they
1208c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright         * no longer throw a runtime exception, but merely will log the failure.
1218c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright         */
1227169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        imageLabel.addMouseListener(new MouseAdapter() {
1237169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            @Override
1247169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            public void mouseClicked(MouseEvent event) {
1258c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright                device.touch(event.getX(), event.getY(), DOWN_AND_UP);
1267169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                updateScreen();
1277169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            }
1287169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1297169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        });
1307169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1317169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
1327169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        focusManager.addKeyEventDispatcher(new KeyEventDispatcher() {
1337169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            public boolean dispatchKeyEvent(KeyEvent event) {
1347169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                if (KeyEvent.KEY_TYPED == event.getID()) {
1358c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright                    device.type(Character.toString(event.getKeyChar()));
1367169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                }
1377169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                return false;
1387169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            }
1397169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        });
1407169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1417169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        SwingUtilities.invokeLater(new Runnable(){
1427169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            public void run() {
1437169aa30eeaac89c49984bb9d061ca152d43391aBill Napier                init();
1448c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright                variableFrame.init(device);
1457169aa30eeaac89c49984bb9d061ca152d43391aBill Napier            }
1467169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        });
1477169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1487169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        pack();
1497169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    }
1507169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1517169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private void updateScreen() {
1528c09f35fe02c38c18f8f7b9e0a531d6ac158476eMichael Wright        IChimpImage snapshot = device.takeSnapshot();
1537169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        currentImage = snapshot.createBufferedImage();
1547169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        imageLabel.setIcon(new ImageIcon(currentImage));
1557169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1567169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        pack();
1577169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    }
1587169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1597169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    private void init() {
1607169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        updateScreen();
1617169aa30eeaac89c49984bb9d061ca152d43391aBill Napier        timer.start();
1627169aa30eeaac89c49984bb9d061ca152d43391aBill Napier    }
1637169aa30eeaac89c49984bb9d061ca152d43391aBill Napier
1647169aa30eeaac89c49984bb9d061ca152d43391aBill Napier}
165