19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.dumprendertree; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdochimport android.os.SystemClock; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.*; 21ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdochimport android.view.KeyEvent; 22ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdochimport android.view.MotionEvent; 23ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdochimport android.webkit.WebView; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 26ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdochimport java.util.Vector; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WebViewEventSender implements EventSender { 29ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 30ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private static final String LOGTAG = "WebViewEventSender"; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch WebViewEventSender(WebView webView) { 33ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mWebView = webView; 3441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mWebView.getSettings().setBuiltInZoomControls(true); 35b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu mTouchPoints = new Vector<TouchPoint>(); 36ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void resetMouse() { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mouseX = mouseY = 0; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableDOMUIEventLogging(int DOMNode) { 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO Auto-generated method stub 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void fireKeyboardEventsToElement(int DOMNode) { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO Auto-generated method stub 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void keyDown(String character, String[] withModifiers) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e("EventSender", "KeyDown: " + character + "(" 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + character.getBytes()[0] + ") Modifiers: " 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Arrays.toString(withModifiers)); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent modifier = null; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (withModifiers != null && withModifiers.length > 0) { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < withModifiers.length; i++) { 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int keyCode = modifierMapper(withModifiers[i]); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modifier = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWebView.onKeyDown(modifier.getKeyCode(), modifier); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int keyCode = keyMapper(character.toLowerCase().toCharArray()[0]); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWebView.onKeyDown(event.getKeyCode(), event); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void keyDown(String character) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keyDown(character, null); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void leapForward(int milliseconds) { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO Auto-generated method stub 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void mouseClick() { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mouseDown(); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mouseUp(); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu public void mouseDown() { 85b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu long ts = SystemClock.uptimeMillis(); 86b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu MotionEvent event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_DOWN, mouseX, mouseY, 0); 87b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu mWebView.onTouchEvent(event); 88b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 90b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu public void mouseMoveTo(int X, int Y) { 91b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu mouseX= X; 92b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu mouseY= Y; 93b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 95b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu public void mouseUp() { 96b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu long ts = SystemClock.uptimeMillis(); 97b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu MotionEvent event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_UP, mouseX, mouseY, 0); 98b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu mWebView.onTouchEvent(event); 99b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Assumes lowercase chars, case needs to be 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handled by calling function. 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int keyMapper(char c) { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handle numbers 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c >= '0' && c<= '9') { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = c - '0'; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_0 + offset; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handle characters 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c >= 'a' && c <= 'z') { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = c - 'a'; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_A + offset; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // handle all others 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (c) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '*': 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_STAR; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '#': 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_POUND; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ',': 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_COMMA; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '.': 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_PERIOD; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\t': 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_TAB; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ' ': 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_SPACE; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\n': 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_ENTER; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\b': 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0x7F: 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_DEL; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '~': 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_GRAVE; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '-': 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_MINUS; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '=': 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_EQUALS; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '(': 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_LEFT_BRACKET; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ')': 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_RIGHT_BRACKET; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\\': 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_BACKSLASH; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ';': 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_SEMICOLON; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '\'': 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_APOSTROPHE; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case '/': 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_SLASH; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int modifierMapper(String modifier) { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (modifier.equals("ctrlKey")) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_ALT_LEFT; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (modifier.equals("shiftKey")) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_SHIFT_LEFT; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (modifier.equals("altKey")) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_SYM; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (modifier.equals("metaKey")) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_UNKNOWN; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return KeyEvent.KEYCODE_UNKNOWN; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 172ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 173ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void touchStart() { 17441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu final int numPoints = mTouchPoints.size(); 17541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numPoints == 0) { 176ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 177ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 178ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 17941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int[] pointerIds = new int[numPoints]; 18041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; 18141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu long downTime = SystemClock.uptimeMillis(); 18241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 18341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu for (int i = 0; i < numPoints; ++i) { 18441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerIds[i] = mTouchPoints.get(i).getId(); 18541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i] = new MotionEvent.PointerCoords(); 18641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i].x = mTouchPoints.get(i).getX(); 18741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i].y = mTouchPoints.get(i).getY(); 18841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchPoints.get(i).setDownTime(downTime); 18941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 19041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 19141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent event = MotionEvent.obtain(downTime, downTime, 19241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent.ACTION_DOWN, numPoints, pointerIds, pointerCoords, 19341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); 19441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 195ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mWebView.onTouchEvent(event); 196ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 197ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 198ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void touchMove() { 19941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu final int numPoints = mTouchPoints.size(); 20041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numPoints == 0) { 201ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 202ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 203ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 20441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int[] pointerIds = new int[numPoints]; 20541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; 20641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int numMovedPoints = 0; 20741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu for (int i = 0; i < numPoints; ++i) { 20841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu TouchPoint tp = mTouchPoints.get(i); 20941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (tp.hasMoved()) { 21041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerIds[numMovedPoints] = mTouchPoints.get(i).getId(); 21141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i] = new MotionEvent.PointerCoords(); 21241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[numMovedPoints].x = mTouchPoints.get(i).getX(); 21341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[numMovedPoints].y = mTouchPoints.get(i).getY(); 21441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu ++numMovedPoints; 21541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu tp.setMoved(false); 21641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 21741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 21841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 21941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numMovedPoints == 0) { 220ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 221ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 222ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 22341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(), 22441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, 22541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu numMovedPoints, pointerIds, pointerCoords, 22641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); 227ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mWebView.onTouchEvent(event); 228ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 229ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 230ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void touchEnd() { 23141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu final int numPoints = mTouchPoints.size(); 23241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numPoints == 0) { 233ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 234ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 235ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 23641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int[] pointerIds = new int[numPoints]; 23741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; 23841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 23941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu for (int i = 0; i < numPoints; ++i) { 24041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerIds[i] = mTouchPoints.get(i).getId(); 24141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i] = new MotionEvent.PointerCoords(); 24241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i].x = mTouchPoints.get(i).getX(); 24341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[i].y = mTouchPoints.get(i).getY(); 24441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 24541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 24641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(), 24741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 24841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu numPoints, pointerIds, pointerCoords, 24941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); 250ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mWebView.onTouchEvent(event); 251ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 25241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu for (int i = numPoints - 1; i >= 0; --i) { // remove released points. 25341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu TouchPoint tp = mTouchPoints.get(i); 25441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (tp.isReleased()) { 25541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchPoints.remove(i); 25641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 257ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 258ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 259ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 260ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void touchCancel() { 26141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu final int numPoints = mTouchPoints.size(); 26241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numPoints == 0) { 263ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 264ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 265ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 26641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int[] pointerIds = new int[numPoints]; 26741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; 26841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu long cancelTime = SystemClock.uptimeMillis(); 26941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int numCanceledPoints = 0; 27041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 27141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu for (int i = 0; i < numPoints; ++i) { 27241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu TouchPoint tp = mTouchPoints.get(i); 27341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (tp.cancelled()) { 27441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerIds[numCanceledPoints] = mTouchPoints.get(i).getId(); 27541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[numCanceledPoints] = new MotionEvent.PointerCoords(); 27641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[numCanceledPoints].x = mTouchPoints.get(i).getX(); 27741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu pointerCoords[numCanceledPoints].y = mTouchPoints.get(i).getY(); 27841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu ++numCanceledPoints; 27941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 28041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } 28141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 28241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numCanceledPoints == 0) { 28341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu return; 284ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 28541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 28641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(), 28741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 28841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu numCanceledPoints, pointerIds, pointerCoords, 28941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); 29041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 29141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mWebView.onTouchEvent(event); 292ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 293ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 294ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void cancelTouchPoint(int id) { 29541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu TouchPoint tp = mTouchPoints.get(id); 296ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch if (tp == null) { 297ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 298ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 299ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 300ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch tp.cancel(); 301ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 302ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 303ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void addTouchPoint(int x, int y) { 30441865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu final int numPoints = mTouchPoints.size(); 30541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu int id; 30641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu if (numPoints == 0) { 30741865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu id = 0; 30841865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu } else { 30941865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu id = mTouchPoints.get(numPoints - 1).getId() + 1; 310ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 31141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu 31241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mTouchPoints.add(new TouchPoint(id, contentsToWindowX(x), contentsToWindowY(y))); 313ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 314ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 31541865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu public void updateTouchPoint(int i, int x, int y) { 31641865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu TouchPoint tp = mTouchPoints.get(i); 317ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch if (tp == null) { 318ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 319ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 320ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 321ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch tp.update(contentsToWindowX(x), contentsToWindowY(y)); 322ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch tp.setMoved(true); 323ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 324ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 325ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void setTouchModifier(String modifier, boolean enabled) { 3268a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch int mask = 0; 3278a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch if ("alt".equals(modifier.toLowerCase())) { 3288a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch mask = KeyEvent.META_ALT_ON; 3298a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch } else if ("shift".equals(modifier.toLowerCase())) { 3308a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch mask = KeyEvent.META_SHIFT_ON; 3318a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch } else if ("ctrl".equals(modifier.toLowerCase())) { 3328a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch mask = KeyEvent.META_SYM_ON; 3338a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch } 3348a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch 3358a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch if (enabled) { 3368a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch mTouchMetaState |= mask; 3378a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch } else { 3388a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch mTouchMetaState &= ~mask; 3398a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch } 340ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 341ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 342ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void releaseTouchPoint(int id) { 34341865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu TouchPoint tp = mTouchPoints.get(id); 344ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch if (tp == null) { 345ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch return; 346ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 347ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 348ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch tp.release(); 349ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 350ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 351ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void clearTouchPoints() { 352ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mTouchPoints.clear(); 353ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 354ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 3558a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch public void clearTouchMetaState() { 3568a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch mTouchMetaState = 0; 3578a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch } 3588a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch 359ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private int contentsToWindowX(int x) { 360a586b7baaf71eef621a826675346b95947fd1df0Huahui Wu return Math.round(x * mWebView.getScale()) - mWebView.getScrollX(); 361ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 362ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 363ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private int contentsToWindowY(int y) { 364a586b7baaf71eef621a826675346b95947fd1df0Huahui Wu return Math.round(y * mWebView.getScale()) - mWebView.getScrollY(); 365ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 366ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WebView mWebView = null; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mouseX; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mouseY; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 371ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private class TouchPoint { 37241865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu private int mId; 373ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private int mX; 374ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private int mY; 375ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private long mDownTime; 376ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private boolean mReleased; 377ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private boolean mMoved; 378ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private boolean mCancelled; 379ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 38041865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu public TouchPoint(int id, int x, int y) { 38141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu mId = id; 382ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mX = x; 383ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mY = y; 384ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mReleased = false; 385ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mMoved = false; 386ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mCancelled = false; 387ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 388ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 389ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void setDownTime(long downTime) { mDownTime = downTime; } 390ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public long downTime() { return mDownTime; } 391ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void cancel() { mCancelled = true; } 392ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 393ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public boolean cancelled() { return mCancelled; } 394ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 395ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void release() { mReleased = true; } 396ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public boolean isReleased() { return mReleased; } 397ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 398ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void setMoved(boolean moved) { mMoved = moved; } 399ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public boolean hasMoved() { return mMoved; } 400ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 40141865f4b0c5670369bf957ad72a867757fc6b356Huahui Wu public int getId() { return mId; } 402ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public int getX() { return mX; } 403ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public int getY() { return mY; } 404ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 405ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch public void update(int x, int y) { 406ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mX = x; 407ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch mY = y; 408ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch } 409b5c4caa07819e59f909cf9d71e7e45ae2c88d715Guang Zhu } 410ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch 411ecbc65cf8f2ea3bdd311f954e3927b46fca068ffBen Murdoch private Vector<TouchPoint> mTouchPoints; 4128a032a3b29e7708e468e2078ff88a39e083db1daBen Murdoch private int mTouchMetaState; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 414