1694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy/* 2694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * Copyright (C) 2010 The Android Open Source Project 3694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * 4694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * you may not use this file except in compliance with the License. 6694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * You may obtain a copy of the License at 7694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * 8694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * 10694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * Unless required by applicable law or agreed to in writing, software 11694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * See the License for the specific language governing permissions and 14694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * limitations under the License. 15694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy */ 16694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 17694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guypackage com.android.dumprendertree2; 18694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 19694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guyimport android.os.Bundle; 20694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guyimport android.os.Handler; 2151769a68a5cb34e9564740c6a854fcb93018789dRomain Guyimport android.os.Message; 22e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guyimport android.os.SystemClock; 2351769a68a5cb34e9564740c6a854fcb93018789dRomain Guyimport android.util.Log; 2451769a68a5cb34e9564740c6a854fcb93018789dRomain Guyimport android.view.KeyEvent; 25c9855a53edfac818dc68714557185977556f849dRomain Guyimport android.view.MotionEvent; 2651769a68a5cb34e9564740c6a854fcb93018789dRomain Guyimport android.webkit.WebView; 2751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 28694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guyimport java.util.LinkedList; 29694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guyimport java.util.List; 30694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 31694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy/** 3251769a68a5cb34e9564740c6a854fcb93018789dRomain Guy * An implementation of EventSender 3351769a68a5cb34e9564740c6a854fcb93018789dRomain Guy */ 3451769a68a5cb34e9564740c6a854fcb93018789dRomain Guypublic class EventSenderImpl { 3551769a68a5cb34e9564740c6a854fcb93018789dRomain Guy private static final String LOG_TAG = "EventSenderImpl"; 3651769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 3751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy private static final int MSG_ENABLE_DOM_UI_EVENT_LOGGING = 0; 38726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy private static final int MSG_FIRE_KEYBOARD_EVENTS_TO_ELEMENT = 1; 3944984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase private static final int MSG_LEAP_FORWARD = 2; 4044984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase 4144984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase private static final int MSG_KEY_DOWN = 3; 4251769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 43694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_MOUSE_DOWN = 4; 44694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_MOUSE_UP = 5; 45694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_MOUSE_CLICK = 6; 462577db1ec135a1470a2c42139772ec97a6c30e78Romain Guy private static final int MSG_MOUSE_MOVE_TO = 7; 478668f8a633d9299091556c3b2e5ae07be8dce360Chet Haase 482577db1ec135a1470a2c42139772ec97a6c30e78Romain Guy private static final int MSG_ADD_TOUCH_POINT = 8; 498668f8a633d9299091556c3b2e5ae07be8dce360Chet Haase private static final int MSG_TOUCH_START = 9; 50694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_UPDATE_TOUCH_POINT = 10; 51694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_TOUCH_MOVE = 11; 52694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_CLEAR_TOUCH_POINTS = 12; 53694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_TOUCH_CANCEL = 13; 54694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_RELEASE_TOUCH_POINT = 14; 55694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_TOUCH_END = 15; 56694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_SET_TOUCH_MODIFIER = 16; 57694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static final int MSG_CANCEL_TOUCH_POINT = 17; 58694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 59694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private static class Point { 60694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private int mX; 61694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private int mY; 62726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy 63694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public Point(int x, int y) { 64694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mX = x; 65694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mY = y; 66694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 67694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public int x() { 68694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return mX; 69694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 70694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public int y() { 71694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return mY; 72f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk } 73f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk } 74f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 75f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk private Point createViewPointFromContentCoordinates(int x, int y) { 76f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk return new Point(Math.round(x * mWebView.getScale()) - mWebView.getScrollX(), 77f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk Math.round(y * mWebView.getScale()) - mWebView.getScrollY()); 78f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk } 7961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy 80f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk public static class TouchPoint { 81f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk private int mId; 8261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy private Point mPoint; 83f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk private long mDownTime; 84f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk private boolean mReleased = false; 8561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy private boolean mMoved = false; 86f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk private boolean mCancelled = false; 87f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 8861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy public TouchPoint(int id, Point point) { 89f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk mId = id; 90f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk mPoint = point; 91f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk } 92f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 93694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public int getId() { 94694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return mId; 95694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 96694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 9751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy public int getX() { 9851769a68a5cb34e9564740c6a854fcb93018789dRomain Guy return mPoint.x(); 9951769a68a5cb34e9564740c6a854fcb93018789dRomain Guy } 10051769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 10151769a68a5cb34e9564740c6a854fcb93018789dRomain Guy public int getY() { 10251769a68a5cb34e9564740c6a854fcb93018789dRomain Guy return mPoint.y(); 10351769a68a5cb34e9564740c6a854fcb93018789dRomain Guy } 10451769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 10551769a68a5cb34e9564740c6a854fcb93018789dRomain Guy public boolean hasMoved() { 10651769a68a5cb34e9564740c6a854fcb93018789dRomain Guy return mMoved; 10751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy } 10851769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 109694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void move(Point point) { 110694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mPoint = point; 111b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy mMoved = true; 112b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy } 11389a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk 11489a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk public void resetHasMoved() { 11589a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk mMoved = false; 11689a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk } 11789a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk 11889a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk public long getDownTime() { 11989a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk return mDownTime; 12089a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk } 12189a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk 122f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk public void setDownTime(long downTime) { 123f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk mDownTime = downTime; 12489a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk } 12589a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk 126b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy public boolean isReleased() { 127f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk return mReleased; 128f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk } 129f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 13089a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk public void release() { 13189a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk mReleased = true; 13289a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk } 13389a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk 13489a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk public boolean isCancelled() { 13589a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk return mCancelled; 13689a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk } 137726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy 1381e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy public void cancel() { 139726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy mCancelled = true; 1401e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1411e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1421e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 143726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy private List<TouchPoint> mTouchPoints; 14465ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk private int mTouchMetaState; 14565ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk private Point mMousePoint; 14665ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk 14765ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk private WebView mWebView; 148726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy 14965ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk private Handler mEventSenderHandler = new Handler() { 15065ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk @Override 15165ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk public void handleMessage(Message msg) { 15265ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk Bundle bundle; 15365ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk MotionEvent event; 15465ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk long ts; 155726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy 15661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy switch (msg.what) { 15761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy case MSG_ENABLE_DOM_UI_EVENT_LOGGING: 158726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy /** TODO: implement */ 15961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy break; 16061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy 161726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy case MSG_FIRE_KEYBOARD_EVENTS_TO_ELEMENT: 162726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy /** TODO: implement */ 163f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk break; 164f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 165f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk case MSG_LEAP_FORWARD: 166f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk /** TODO: implement */ 167726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy break; 16861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy 16961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy case MSG_KEY_DOWN: 170f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk bundle = (Bundle)msg.obj; 171f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk String character = bundle.getString("character"); 172f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk String[] withModifiers = bundle.getStringArray("withModifiers"); 173f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 174726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy if (withModifiers != null && withModifiers.length > 0) { 175f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk for (int i = 0; i < withModifiers.length; i++) { 176f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk executeKeyEvent(KeyEvent.ACTION_DOWN, 17758ef7fbf16864164efe98bf613b15c64deb1afc0Romain Guy modifierToKeyCode(withModifiers[i])); 1782bffd268f135df8308c9e67af110525a5c463424Romain Guy } 179726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy } 18061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy executeKeyEvent(KeyEvent.ACTION_DOWN, 18161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy charToKeyCode(character.toLowerCase().toCharArray()[0])); 182694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 183694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 184694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy /** MOUSE */ 185694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 1862bffd268f135df8308c9e67af110525a5c463424Romain Guy case MSG_MOUSE_DOWN: 1872bffd268f135df8308c9e67af110525a5c463424Romain Guy if (mMousePoint != null) { 188694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy ts = SystemClock.uptimeMillis(); 189694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_DOWN, mMousePoint.x(), mMousePoint.y(), 0); 190694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mWebView.onTouchEvent(event); 191694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 192694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 1932bffd268f135df8308c9e67af110525a5c463424Romain Guy 1942bffd268f135df8308c9e67af110525a5c463424Romain Guy case MSG_MOUSE_UP: 1952bffd268f135df8308c9e67af110525a5c463424Romain Guy if (mMousePoint != null) { 196694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy ts = SystemClock.uptimeMillis(); 197694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_UP, mMousePoint.x(), mMousePoint.y(), 0); 198694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mWebView.onTouchEvent(event); 199726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy } 200694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 20161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy 202726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy case MSG_MOUSE_CLICK: 203694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mouseDown(); 204694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mouseUp(); 205694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 206726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy 2072bffd268f135df8308c9e67af110525a5c463424Romain Guy case MSG_MOUSE_MOVE_TO: 2082bffd268f135df8308c9e67af110525a5c463424Romain Guy mMousePoint = createViewPointFromContentCoordinates(msg.arg1, msg.arg2); 209694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 210694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 211694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy /** TOUCH */ 212f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk 213f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk case MSG_ADD_TOUCH_POINT: 2142bffd268f135df8308c9e67af110525a5c463424Romain Guy int numPoints = getTouchPoints().size(); 215f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk int id; 216f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk if (numPoints == 0) { 2172bffd268f135df8308c9e67af110525a5c463424Romain Guy id = 0; 218f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk } else { 219f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk id = getTouchPoints().get(numPoints - 1).getId() + 1; 2202bffd268f135df8308c9e67af110525a5c463424Romain Guy } 221f18136cb3c881a9d16c1a4f0f341732c276936bfAlex Sakhartchouk getTouchPoints().add( 22289a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk new TouchPoint(id, createViewPointFromContentCoordinates(msg.arg1, msg.arg2))); 223694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 224694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 2252bffd268f135df8308c9e67af110525a5c463424Romain Guy case MSG_TOUCH_START: 226694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (getTouchPoints().isEmpty()) { 227694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return; 228694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 229694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy for (int i = 0; i < getTouchPoints().size(); ++i) { 230694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy getTouchPoints().get(i).setDownTime(SystemClock.uptimeMillis()); 231694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 232694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy executeTouchEvent(MotionEvent.ACTION_DOWN); 233694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 23451769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 235694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case MSG_UPDATE_TOUCH_POINT: 236694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle = (Bundle)msg.obj; 237694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 238694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy int index = bundle.getInt("id"); 2392bffd268f135df8308c9e67af110525a5c463424Romain Guy if (index >= getTouchPoints().size()) { 2402bffd268f135df8308c9e67af110525a5c463424Romain Guy Log.w(LOG_TAG + "::MSG_UPDATE_TOUCH_POINT", "TouchPoint out of bounds: " 241694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy + index); 242694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 243694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 244694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 245694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy getTouchPoints().get(index).move( 246694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy createViewPointFromContentCoordinates(bundle.getInt("x"), bundle.getInt("y"))); 24751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy break; 248694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 249694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case MSG_TOUCH_MOVE: 250694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy /** 251694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * FIXME: At the moment we don't support multi-touch. Hence, we only examine 252694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * the first touch point. In future this method will need rewriting. 253694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy */ 254694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (getTouchPoints().isEmpty()) { 255694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return; 25689a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk } 25789a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk executeTouchEvent(MotionEvent.ACTION_MOVE); 258694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy for (int i = 0; i < getTouchPoints().size(); ++i) { 259694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy getTouchPoints().get(i).resetHasMoved(); 260694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 26151769a68a5cb34e9564740c6a854fcb93018789dRomain Guy break; 26251769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 263694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case MSG_CANCEL_TOUCH_POINT: 264694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (msg.arg1 >= getTouchPoints().size()) { 265694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy Log.w(LOG_TAG + "::MSG_RELEASE_TOUCH_POINT", "TouchPoint out of bounds: " 266694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy + msg.arg1); 267694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 268694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 26951769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 270694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy getTouchPoints().get(msg.arg1).cancel(); 271694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 272726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy 27351769a68a5cb34e9564740c6a854fcb93018789dRomain Guy case MSG_TOUCH_CANCEL: 274694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy /** 275694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * FIXME: At the moment we don't support multi-touch. Hence, we only examine 276726aeba80ffc6778a9bc3e0ee957b8d644183505Romain Guy * the first touch point. In future this method will need rewriting. 277694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy */ 278694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (getTouchPoints().isEmpty()) { 279694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return; 280694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 281694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy executeTouchEvent(MotionEvent.ACTION_CANCEL); 282694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 283694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 284694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case MSG_RELEASE_TOUCH_POINT: 2852577db1ec135a1470a2c42139772ec97a6c30e78Romain Guy if (msg.arg1 >= getTouchPoints().size()) { 2868668f8a633d9299091556c3b2e5ae07be8dce360Chet Haase Log.w(LOG_TAG + "::MSG_RELEASE_TOUCH_POINT", "TouchPoint out of bounds: " 287694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy + msg.arg1); 288694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 289694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 29051769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 2912577db1ec135a1470a2c42139772ec97a6c30e78Romain Guy getTouchPoints().get(msg.arg1).release(); 2928668f8a633d9299091556c3b2e5ae07be8dce360Chet Haase break; 2938668f8a633d9299091556c3b2e5ae07be8dce360Chet Haase 29451769a68a5cb34e9564740c6a854fcb93018789dRomain Guy case MSG_TOUCH_END: 295694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy /** 296694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * FIXME: At the moment we don't support multi-touch. Hence, we only examine 297694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy * the first touch point. In future this method will need rewriting. 2988668f8a633d9299091556c3b2e5ae07be8dce360Chet Haase */ 299694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (getTouchPoints().isEmpty()) { 300694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return; 301694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 302694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy executeTouchEvent(MotionEvent.ACTION_UP); 303694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy // remove released points. 304694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy for (int i = getTouchPoints().size() - 1; i >= 0; --i) { 305694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (getTouchPoints().get(i).isReleased()) { 306694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy getTouchPoints().remove(i); 307514fb18827186591d66973c2362c859b64b63556Romain Guy } 308514fb18827186591d66973c2362c859b64b63556Romain Guy } 309694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 310c9855a53edfac818dc68714557185977556f849dRomain Guy 311c9855a53edfac818dc68714557185977556f849dRomain Guy case MSG_SET_TOUCH_MODIFIER: 312c9855a53edfac818dc68714557185977556f849dRomain Guy bundle = (Bundle)msg.obj; 31351769a68a5cb34e9564740c6a854fcb93018789dRomain Guy String modifier = bundle.getString("modifier"); 314b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy boolean enabled = bundle.getBoolean("enabled"); 315694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 316694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy int mask = 0; 317694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if ("alt".equals(modifier.toLowerCase())) { 3189b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk mask = KeyEvent.META_ALT_ON; 319694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } else if ("shift".equals(modifier.toLowerCase())) { 3209cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy mask = KeyEvent.META_SHIFT_ON; 3219cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy } else if ("ctrl".equals(modifier.toLowerCase())) { 3229cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy mask = KeyEvent.META_SYM_ON; 323694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 324894df17eee708688c8a6e67941add2017239c790Alex Sakhartchouk 325894df17eee708688c8a6e67941add2017239c790Alex Sakhartchouk if (enabled) { 326694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mTouchMetaState |= mask; 32751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy } else { 3289b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk mTouchMetaState &= ~mask; 32951769a68a5cb34e9564740c6a854fcb93018789dRomain Guy } 33051769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 33151769a68a5cb34e9564740c6a854fcb93018789dRomain Guy break; 332c9855a53edfac818dc68714557185977556f849dRomain Guy 333c9855a53edfac818dc68714557185977556f849dRomain Guy case MSG_CLEAR_TOUCH_POINTS: 334c9855a53edfac818dc68714557185977556f849dRomain Guy getTouchPoints().clear(); 33551769a68a5cb34e9564740c6a854fcb93018789dRomain Guy break; 33651769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 337514fb18827186591d66973c2362c859b64b63556Romain Guy default: 338c9855a53edfac818dc68714557185977556f849dRomain Guy break; 339514fb18827186591d66973c2362c859b64b63556Romain Guy } 34051769a68a5cb34e9564740c6a854fcb93018789dRomain Guy } 34151769a68a5cb34e9564740c6a854fcb93018789dRomain Guy }; 34251769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 343c9855a53edfac818dc68714557185977556f849dRomain Guy public void reset(WebView webView) { 344c9855a53edfac818dc68714557185977556f849dRomain Guy mWebView = webView; 345c9855a53edfac818dc68714557185977556f849dRomain Guy mTouchPoints = null; 34651769a68a5cb34e9564740c6a854fcb93018789dRomain Guy mTouchMetaState = 0; 34751769a68a5cb34e9564740c6a854fcb93018789dRomain Guy mMousePoint = null; 348514fb18827186591d66973c2362c859b64b63556Romain Guy } 349c9855a53edfac818dc68714557185977556f849dRomain Guy 350514fb18827186591d66973c2362c859b64b63556Romain Guy public void enableDOMUIEventLogging(int domNode) { 35151769a68a5cb34e9564740c6a854fcb93018789dRomain Guy Message msg = mEventSenderHandler.obtainMessage(MSG_ENABLE_DOM_UI_EVENT_LOGGING); 352514fb18827186591d66973c2362c859b64b63556Romain Guy msg.arg1 = domNode; 353514fb18827186591d66973c2362c859b64b63556Romain Guy msg.sendToTarget(); 354694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 355694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 356694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void fireKeyboardEventsToElement(int domNode) { 357694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy Message msg = mEventSenderHandler.obtainMessage(MSG_FIRE_KEYBOARD_EVENTS_TO_ELEMENT); 358694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy msg.arg1 = domNode; 359694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy msg.sendToTarget(); 360694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 361694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 3629cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy public void leapForward(int milliseconds) { 3639cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy Message msg = mEventSenderHandler.obtainMessage(MSG_LEAP_FORWARD); 3649cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy msg.arg1 = milliseconds; 3659cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy msg.sendToTarget(); 3669b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk } 3679cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy 3689b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk public void keyDown(String character, String[] withModifiers) { 3699b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk Bundle bundle = new Bundle(); 370694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putString("character", character); 371694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putStringArray("withModifiers", withModifiers); 372694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.obtainMessage(MSG_KEY_DOWN, bundle).sendToTarget(); 373694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 374694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 375694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy /** MOUSE */ 376694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 377694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void mouseDown() { 378694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_MOUSE_DOWN); 379694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 380694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 381694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void mouseUp() { 382694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_MOUSE_UP); 383694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 384694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 385694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void mouseClick() { 386694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_MOUSE_CLICK); 387694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 388694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 389694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void mouseMoveTo(int x, int y) { 39051769a68a5cb34e9564740c6a854fcb93018789dRomain Guy mEventSenderHandler.obtainMessage(MSG_MOUSE_MOVE_TO, x, y).sendToTarget(); 391694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 3922bffd268f135df8308c9e67af110525a5c463424Romain Guy 39344984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase /** TOUCH */ 39444984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase 39544984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase public void addTouchPoint(int x, int y) { 39644984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase mEventSenderHandler.obtainMessage(MSG_ADD_TOUCH_POINT, x, y).sendToTarget(); 39744984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase } 39844984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase 39944984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase public void touchStart() { 40044984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_START); 40144984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase } 40244984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase 40344984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase public void updateTouchPoint(int id, int x, int y) { 404694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy Bundle bundle = new Bundle(); 405694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putInt("id", id); 406694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putInt("x", x); 407694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putInt("y", y); 408694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.obtainMessage(MSG_UPDATE_TOUCH_POINT, bundle).sendToTarget(); 409694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 410694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 411694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void touchMove() { 412694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_MOVE); 413694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 414694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 415694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void cancelTouchPoint(int id) { 416694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy Message msg = mEventSenderHandler.obtainMessage(MSG_CANCEL_TOUCH_POINT); 417694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy msg.arg1 = id; 418694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy msg.sendToTarget(); 419694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 420694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 421694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void touchCancel() { 422694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_CANCEL); 423694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 424694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 425694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void releaseTouchPoint(int id) { 426694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy Message msg = mEventSenderHandler.obtainMessage(MSG_RELEASE_TOUCH_POINT); 427694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy msg.arg1 = id; 428694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy msg.sendToTarget(); 429694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 430694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 431694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void touchEnd() { 432694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_END); 433694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 434694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 435694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void setTouchModifier(String modifier, boolean enabled) { 436694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy Bundle bundle = new Bundle(); 437694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putString("modifier", modifier); 438694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy bundle.putBoolean("enabled", enabled); 439694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.obtainMessage(MSG_SET_TOUCH_MODIFIER, bundle).sendToTarget(); 440694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 441694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 442694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy public void clearTouchPoints() { 443694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mEventSenderHandler.sendEmptyMessage(MSG_CLEAR_TOUCH_POINTS); 444694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 445694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 44689a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk private List<TouchPoint> getTouchPoints() { 44789a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk if (mTouchPoints == null) { 448694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mTouchPoints = new LinkedList<TouchPoint>(); 449694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 450694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 451694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return mTouchPoints; 452694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 45389a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk 454b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy private void executeTouchEvent(int action) { 455694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy int numPoints = getTouchPoints().size(); 456694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy int[] pointerIds = new int[numPoints]; 457694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; 458694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 459694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy for (int i = 0; i < numPoints; ++i) { 460694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy boolean isNeeded = false; 46144984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase switch(action) { 46244984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase case MotionEvent.ACTION_DOWN: 46344984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase case MotionEvent.ACTION_UP: 46444984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase isNeeded = true; 46544984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase break; 46644984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase case MotionEvent.ACTION_MOVE: 46744984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase isNeeded = getTouchPoints().get(i).hasMoved(); 46889a524ac2d4a36739e51b01b336c0bade77e2ee0Alex Sakhartchouk break; 4691de1083e98cde9bdd5e8539dbc54fdea6531906eRomain Guy case MotionEvent.ACTION_CANCEL: 4701de1083e98cde9bdd5e8539dbc54fdea6531906eRomain Guy isNeeded = getTouchPoints().get(i).isCancelled(); 471694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy break; 472694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy default: 47344984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase Log.w(LOG_TAG + "::executeTouchEvent(),", "action not supported:" + action); 47444984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase break; 47544984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase } 476694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 477694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy numPoints = 0; 478694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (isNeeded) { 47944984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase pointerIds[numPoints] = getTouchPoints().get(i).getId(); 4809b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk pointerCoords[numPoints] = new MotionEvent.PointerCoords(); 48161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy pointerCoords[numPoints].x = getTouchPoints().get(i).getX(); 482694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy pointerCoords[numPoints].y = getTouchPoints().get(i).getY(); 483e8cb9c14309b0f01c0159efdf9a7198f44a62642Romain Guy ++numPoints; 484e8cb9c14309b0f01c0159efdf9a7198f44a62642Romain Guy } 485e8cb9c14309b0f01c0159efdf9a7198f44a62642Romain Guy } 486694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 487694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (numPoints == 0) { 488694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return; 489694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 490694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 491694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).getDownTime(), 4927975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy SystemClock.uptimeMillis(), action, 493694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy numPoints, pointerIds, pointerCoords, 4947975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); 495694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 4967975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy mWebView.onTouchEvent(event); 49765ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk } 4987975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy 499694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy private void executeKeyEvent(int action, int keyCode) { 5007975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy KeyEvent event = new KeyEvent(action, keyCode); 501694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy mWebView.onKeyDown(event.getKeyCode(), event); 5027975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy } 503694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 50444984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase /** 50544984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase * Assumes lowercase chars, case needs to be handled by calling function. 50644984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase */ 50744984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase private static int charToKeyCode(char c) { 50844984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase // handle numbers 50944984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase if (c >= '0' && c <= '9') { 51044984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase int offset = c - '0'; 51144984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase return KeyEvent.KEYCODE_0 + offset; 51244984ea0cb3702384d023b5f211deda3c4b0b656Chet Haase } 51351769a68a5cb34e9564740c6a854fcb93018789dRomain Guy 514694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy // handle characters 515694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy if (c >= 'a' && c <= 'z') { 516694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy int offset = c - 'a'; 517694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_A + offset; 518694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy } 519694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 52051769a68a5cb34e9564740c6a854fcb93018789dRomain Guy // handle all others 521694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy switch (c) { 522694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '*': 523694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_STAR; 524694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 525694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '#': 526694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_POUND; 527694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 528694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case ',': 529694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_COMMA; 530694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 531694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '.': 532694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_PERIOD; 533694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 534694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '\t': 535694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_TAB; 536694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 5375d794412e3e429e47404395badcd11b0b8639e8bRomain Guy case ' ': 5385d794412e3e429e47404395badcd11b0b8639e8bRomain Guy return KeyEvent.KEYCODE_SPACE; 5395d794412e3e429e47404395badcd11b0b8639e8bRomain Guy 540694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '\n': 541694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_ENTER; 542694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 543694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '\b': 544694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case 0x7F: 545694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_DEL; 5469b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk 5479b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk case '~': 548694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_GRAVE; 549694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 550694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '-': 551694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_MINUS; 552694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 553694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '=': 554694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_EQUALS; 555694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 556694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case '(': 557694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_LEFT_BRACKET; 558694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 55965ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk case ')': 56065ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk return KeyEvent.KEYCODE_RIGHT_BRACKET; 56165ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk 56265ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk case '\\': 56365ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk return KeyEvent.KEYCODE_BACKSLASH; 56465ef909776c03417d8b597738da54ca211e37e4fAlex Sakhartchouk 565694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy case ';': 566694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy return KeyEvent.KEYCODE_SEMICOLON; 567694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy 5689b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk case '\'': 5699b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk return KeyEvent.KEYCODE_APOSTROPHE; 5709b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk 5719b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk case '/': 5729b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk return KeyEvent.KEYCODE_SLASH; 5739b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk 5749b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk default: 5759b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk return c; 5769b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk } 5779b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk } 5789b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk 5799b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk private static int modifierToKeyCode(String modifier) { 5809b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk if (modifier.equals("ctrlKey")) { 5819b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk return KeyEvent.KEYCODE_ALT_LEFT; 5829b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk } else if (modifier.equals("shiftKey")) { 5831e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy return KeyEvent.KEYCODE_SHIFT_LEFT; 5849b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk } else if (modifier.equals("altKey")) { 5859b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk return KeyEvent.KEYCODE_SYM; 5861e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 5879b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk 5889b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk return KeyEvent.KEYCODE_UNKNOWN; 5899b9902ddbb01548f4a0199087b7035e7c10b2ae7Alex Sakhartchouk } 590694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy} 591694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy