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.app.IActivityManager;
20001a30f89ae0cb70d26eacb88dc2a96b9473b3ddJeff Brownimport android.hardware.input.InputManager;
21001a30f89ae0cb70d26eacb88dc2a96b9473b3ddJeff Brownimport android.os.SystemClock;
2252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.IWindowManager;
23001a30f89ae0cb70d26eacb88dc2a96b9473b3ddJeff Brownimport android.view.InputDevice;
24f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brownimport android.view.KeyCharacterMap;
2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.KeyEvent;
2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/**
2752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * monkey key event
2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */
293faef17986da97e97a394601f87af423f5e50c08Bill Napierpublic class MonkeyKeyEvent extends MonkeyEvent {
30f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private int mDeviceId;
31f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private long mEventTime;
32f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private long mDownTime;
33f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private int mAction;
34f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private int mKeyCode;
35f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private int mScanCode;
36f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private int mMetaState;
37f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    private int mRepeatCount;
383faef17986da97e97a394601f87af423f5e50c08Bill Napier
392af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown    private KeyEvent mKeyEvent;
403faef17986da97e97a394601f87af423f5e50c08Bill Napier
41f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    public MonkeyKeyEvent(int action, int keyCode) {
42f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        this(-1, -1, action, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0);
433faef17986da97e97a394601f87af423f5e50c08Bill Napier    }
443faef17986da97e97a394601f87af423f5e50c08Bill Napier
4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public MonkeyKeyEvent(long downTime, long eventTime, int action,
46f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown            int keyCode, int repeatCount, int metaState,
47f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown            int device, int scanCode) {
4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        super(EVENT_TYPE_KEY);
49f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        mDownTime = downTime;
50f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        mEventTime = eventTime;
5152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mAction = action;
52f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        mKeyCode = keyCode;
53f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        mRepeatCount = repeatCount;
5452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mMetaState = metaState;
5552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mDeviceId = device;
56f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        mScanCode = scanCode;
57f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    }
58f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown
59f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown    public MonkeyKeyEvent(KeyEvent e) {
60f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        super(EVENT_TYPE_KEY);
61f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        mKeyEvent = e;
6252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
633faef17986da97e97a394601f87af423f5e50c08Bill Napier
6452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public int getKeyCode() {
65f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        return mKeyEvent != null ? mKeyEvent.getKeyCode() : mKeyCode;
6652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
673faef17986da97e97a394601f87af423f5e50c08Bill Napier
6852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public int getAction() {
69f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        return mKeyEvent != null ? mKeyEvent.getAction() : mAction;
7052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
713faef17986da97e97a394601f87af423f5e50c08Bill Napier
7252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public long getDownTime() {
73f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        return mKeyEvent != null ? mKeyEvent.getDownTime() : mDownTime;
7452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
753faef17986da97e97a394601f87af423f5e50c08Bill Napier
7652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public long getEventTime() {
77f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        return mKeyEvent != null ? mKeyEvent.getEventTime() : mEventTime;
7852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
793faef17986da97e97a394601f87af423f5e50c08Bill Napier
8052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setDownTime(long downTime) {
81f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        if (mKeyEvent != null) {
82f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown            throw new IllegalStateException("Cannot modify down time of this key event.");
83f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        }
8452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mDownTime = downTime;
8552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
863faef17986da97e97a394601f87af423f5e50c08Bill Napier
8752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public void setEventTime(long eventTime) {
88f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        if (mKeyEvent != null) {
89f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown            throw new IllegalStateException("Cannot modify event time of this key event.");
90f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown        }
9152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        mEventTime = eventTime;
9252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
933faef17986da97e97a394601f87af423f5e50c08Bill Napier
9452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    @Override
95565067aeb01670c05692e087ec214f8dd1a426edEvan Millar    public boolean isThrottlable() {
96565067aeb01670c05692e087ec214f8dd1a426edEvan Millar        return (getAction() == KeyEvent.ACTION_UP);
97565067aeb01670c05692e087ec214f8dd1a426edEvan Millar    }
983faef17986da97e97a394601f87af423f5e50c08Bill Napier
99565067aeb01670c05692e087ec214f8dd1a426edEvan Millar    @Override
10052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
10152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        if (verbose > 1) {
10252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            String note;
10352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            if (mAction == KeyEvent.ACTION_UP) {
10452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                note = "ACTION_UP";
10552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } else {
10652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                note = "ACTION_DOWN";
10752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
10852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
10952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            try {
110585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                System.out.println(":Sending Key (" + note + "): "
11152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                        + mKeyCode + "    // "
11252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                        + MonkeySourceRandom.getKeyName(mKeyCode));
11352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            } catch (ArrayIndexOutOfBoundsException e) {
114585ab9695077b48436032def57ff50f9d9ec316bJeff Brown                System.out.println(":Sending Key (" + note + "): "
11552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project                        + mKeyCode + "    // Unknown key event");
11652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project            }
11752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
11852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project
1192af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown        KeyEvent keyEvent = mKeyEvent;
1202af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown        if (keyEvent == null) {
1212af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            long eventTime = mEventTime;
1222af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            if (eventTime <= 0) {
1232af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown                eventTime = SystemClock.uptimeMillis();
1242af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            }
1252af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            long downTime = mDownTime;
1262af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            if (downTime <= 0) {
1272af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown                downTime = eventTime;
1282af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            }
1292af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown            keyEvent = new KeyEvent(downTime, eventTime, mAction, mKeyCode,
130f63ed9b83c60e1be6fb34c6a64d2fb44b4156d00Jeff Brown                    mRepeatCount, mMetaState, mDeviceId, mScanCode,
1312af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown                    KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_KEYBOARD);
132001a30f89ae0cb70d26eacb88dc2a96b9473b3ddJeff Brown        }
1332af3f3067a55eaa81be0b90d4cbe0531920d48dcJeff Brown        if (!InputManager.getInstance().injectInputEvent(keyEvent,
134001a30f89ae0cb70d26eacb88dc2a96b9473b3ddJeff Brown                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT)) {
135001a30f89ae0cb70d26eacb88dc2a96b9473b3ddJeff Brown            return MonkeyEvent.INJECT_FAIL;
13652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        }
13752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project        return MonkeyEvent.INJECT_SUCCESS;
13852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project    }
13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project}
140