Home | History | Annotate | Download | only in dumprendertree
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dumprendertree;
     18 
     19 import android.os.Handler;
     20 import android.os.SystemClock;
     21 import android.util.*;
     22 import android.view.KeyEvent;
     23 import android.view.MotionEvent;
     24 import android.webkit.WebView;
     25 
     26 import java.lang.InterruptedException;
     27 import java.util.Arrays;
     28 import java.util.Vector;
     29 
     30 public class WebViewEventSender implements EventSender {
     31 
     32     private static final String LOGTAG = "WebViewEventSender";
     33 
     34     WebViewEventSender(WebView webView) {
     35         mWebView = webView;
     36         mTouchPoints = new Vector();
     37     }
     38 
     39 	public void resetMouse() {
     40 		mouseX = mouseY = 0;
     41 	}
     42 
     43 	public void enableDOMUIEventLogging(int DOMNode) {
     44 		// TODO Auto-generated method stub
     45 
     46 	}
     47 
     48 	public void fireKeyboardEventsToElement(int DOMNode) {
     49 		// TODO Auto-generated method stub
     50 
     51 	}
     52 
     53 	public void keyDown(String character, String[] withModifiers) {
     54         Log.e("EventSender", "KeyDown: " + character + "("
     55                 + character.getBytes()[0] + ") Modifiers: "
     56                 + Arrays.toString(withModifiers));
     57         KeyEvent modifier = null;
     58         if (withModifiers != null && withModifiers.length > 0) {
     59             for (int i = 0; i < withModifiers.length; i++) {
     60                 int keyCode = modifierMapper(withModifiers[i]);
     61                 modifier = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
     62                 mWebView.onKeyDown(modifier.getKeyCode(), modifier);
     63             }
     64         }
     65         int keyCode = keyMapper(character.toLowerCase().toCharArray()[0]);
     66         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
     67         mWebView.onKeyDown(event.getKeyCode(), event);
     68 
     69     }
     70 
     71 	public void keyDown(String character) {
     72         keyDown(character, null);
     73 	}
     74 
     75 	public void leapForward(int milliseconds) {
     76 		// TODO Auto-generated method stub
     77 
     78 	}
     79 
     80 	public void mouseClick() {
     81 		mouseDown();
     82 		mouseUp();
     83 	}
     84 
     85 	public void mouseDown() {
     86           /*  KeyEvent event = new KeyEvent(
     87                 KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
     88             mWebView.onKeyDown(event.getKeyCode(), event); */
     89 	}
     90 
     91 	public void mouseMoveTo(int X, int Y) {
     92 		if (X > mouseX) {
     93                     KeyEvent event = new KeyEvent(
     94                         KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
     95                     mWebView.onKeyDown(event.getKeyCode(), event);
     96                     mWebView.onKeyUp(event.getKeyCode(), event);
     97 		} else if ( X < mouseX ) {
     98                     KeyEvent event = new KeyEvent(
     99                         KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT);
    100                     mWebView.onKeyDown(event.getKeyCode(), event);
    101                     mWebView.onKeyUp(event.getKeyCode(), event);
    102 		}
    103 		if (Y > mouseY) {
    104                     KeyEvent event = new KeyEvent(
    105                         KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN);
    106                     mWebView.onKeyDown(event.getKeyCode(), event);
    107                     mWebView.onKeyUp(event.getKeyCode(), event);
    108 		} else if (Y < mouseY ) {
    109                     KeyEvent event = new KeyEvent(
    110                         KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP);
    111                     mWebView.onKeyDown(event.getKeyCode(), event);
    112                     mWebView.onKeyUp(event.getKeyCode(), event);
    113 		}
    114 		mouseX= X;
    115 		mouseY= Y;
    116 
    117 	}
    118 
    119 	public void mouseUp() {
    120         /*    KeyEvent event = new KeyEvent(
    121                 KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
    122             mWebView.onKeyDown(event.getKeyCode(), event);*/
    123 
    124 	}
    125 
    126 	// Assumes lowercase chars, case needs to be
    127 	// handled by calling function.
    128 	static int keyMapper(char c) {
    129 		// handle numbers
    130 		if (c >= '0' && c<= '9') {
    131 			int offset = c - '0';
    132 			return KeyEvent.KEYCODE_0 + offset;
    133 		}
    134 
    135 		// handle characters
    136 		if (c >= 'a' && c <= 'z') {
    137 			int offset = c - 'a';
    138 			return KeyEvent.KEYCODE_A + offset;
    139 		}
    140 
    141 		// handle all others
    142 		switch (c) {
    143 		case '*':
    144 			return KeyEvent.KEYCODE_STAR;
    145 		case '#':
    146 			return KeyEvent.KEYCODE_POUND;
    147 		case ',':
    148 			return KeyEvent.KEYCODE_COMMA;
    149 		case '.':
    150 			return KeyEvent.KEYCODE_PERIOD;
    151 		case '\t':
    152 			return KeyEvent.KEYCODE_TAB;
    153 		case ' ':
    154 			return KeyEvent.KEYCODE_SPACE;
    155 		case '\n':
    156 			return KeyEvent.KEYCODE_ENTER;
    157 		case '\b':
    158         case 0x7F:
    159 			return KeyEvent.KEYCODE_DEL;
    160 		case '~':
    161 			return KeyEvent.KEYCODE_GRAVE;
    162 		case '-':
    163 			return KeyEvent.KEYCODE_MINUS;
    164 		case '=':
    165 			return KeyEvent.KEYCODE_EQUALS;
    166 		case '(':
    167 			return KeyEvent.KEYCODE_LEFT_BRACKET;
    168 		case ')':
    169 			return KeyEvent.KEYCODE_RIGHT_BRACKET;
    170 		case '\\':
    171 			return KeyEvent.KEYCODE_BACKSLASH;
    172 		case ';':
    173 			return KeyEvent.KEYCODE_SEMICOLON;
    174 		case '\'':
    175 			return KeyEvent.KEYCODE_APOSTROPHE;
    176 		case '/':
    177 			return KeyEvent.KEYCODE_SLASH;
    178 		default:
    179 			break;
    180 		}
    181 
    182 		return c;
    183 	}
    184 
    185 	static int modifierMapper(String modifier) {
    186 		if (modifier.equals("ctrlKey")) {
    187 			return KeyEvent.KEYCODE_ALT_LEFT;
    188 		} else if (modifier.equals("shiftKey")) {
    189 			return KeyEvent.KEYCODE_SHIFT_LEFT;
    190 		} else if (modifier.equals("altKey")) {
    191 			return KeyEvent.KEYCODE_SYM;
    192 		} else if (modifier.equals("metaKey")) {
    193 			return KeyEvent.KEYCODE_UNKNOWN;
    194 		}
    195 		return KeyEvent.KEYCODE_UNKNOWN;
    196 	}
    197 
    198     public void touchStart() {
    199         // We only support single touch so examine the first touch point only.
    200         // If multi touch is enabled in the future, we need to re-examine this to send
    201         // all the touch points with the event.
    202         TouchPoint tp = mTouchPoints.get(0);
    203 
    204         if (tp == null) {
    205             return;
    206         }
    207 
    208         tp.setDownTime(SystemClock.uptimeMillis());
    209         MotionEvent event = MotionEvent.obtain(tp.downTime(), tp.downTime(),
    210                 MotionEvent.ACTION_DOWN, tp.getX(), tp.getY(), mTouchMetaState);
    211         mWebView.onTouchEvent(event);
    212     }
    213 
    214     public void touchMove() {
    215         TouchPoint tp = mTouchPoints.get(0);
    216 
    217         if (tp == null) {
    218             return;
    219         }
    220 
    221         if (!tp.hasMoved()) {
    222             return;
    223         }
    224 
    225         MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(),
    226                 MotionEvent.ACTION_MOVE, tp.getX(), tp.getY(), mTouchMetaState);
    227         mWebView.onTouchEvent(event);
    228 
    229         tp.setMoved(false);
    230     }
    231 
    232     public void touchEnd() {
    233         TouchPoint tp = mTouchPoints.get(0);
    234 
    235         if (tp == null) {
    236             return;
    237         }
    238 
    239         MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(),
    240                 MotionEvent.ACTION_UP, tp.getX(), tp.getY(), mTouchMetaState);
    241         mWebView.onTouchEvent(event);
    242 
    243         if (tp.isReleased()) {
    244             mTouchPoints.remove(0);
    245         }
    246     }
    247 
    248     public void touchCancel() {
    249         TouchPoint tp = mTouchPoints.get(0);
    250         if (tp == null) {
    251             return;
    252         }
    253 
    254         if (tp.cancelled()) {
    255             MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(),
    256                     MotionEvent.ACTION_CANCEL, tp.getX(), tp.getY(), mTouchMetaState);
    257             mWebView.onTouchEvent(event);
    258         }
    259     }
    260 
    261     public void cancelTouchPoint(int id) {
    262         TouchPoint tp = mTouchPoints.get(0);
    263         if (tp == null) {
    264             return;
    265         }
    266 
    267         tp.cancel();
    268     }
    269 
    270     public void addTouchPoint(int x, int y) {
    271         mTouchPoints.add(new TouchPoint(contentsToWindowX(x), contentsToWindowY(y)));
    272         if (mTouchPoints.size() > 1) {
    273             Log.w(LOGTAG, "Adding more than one touch point, but multi touch is not supported!");
    274         }
    275     }
    276 
    277     public void updateTouchPoint(int id, int x, int y) {
    278         TouchPoint tp = mTouchPoints.get(0);
    279         if (tp == null) {
    280             return;
    281         }
    282 
    283         tp.update(contentsToWindowX(x), contentsToWindowY(y));
    284         tp.setMoved(true);
    285     }
    286 
    287     public void setTouchModifier(String modifier, boolean enabled) {
    288         int mask = 0;
    289         if ("alt".equals(modifier.toLowerCase())) {
    290             mask = KeyEvent.META_ALT_ON;
    291         } else if ("shift".equals(modifier.toLowerCase())) {
    292             mask = KeyEvent.META_SHIFT_ON;
    293         } else if ("ctrl".equals(modifier.toLowerCase())) {
    294             mask = KeyEvent.META_SYM_ON;
    295         }
    296 
    297         if (enabled) {
    298             mTouchMetaState |= mask;
    299         } else {
    300             mTouchMetaState &= ~mask;
    301         }
    302     }
    303 
    304     public void releaseTouchPoint(int id) {
    305         TouchPoint tp = mTouchPoints.get(0);
    306         if (tp == null) {
    307             return;
    308         }
    309 
    310         tp.release();
    311     }
    312 
    313     public void clearTouchPoints() {
    314         mTouchPoints.clear();
    315     }
    316 
    317     public void clearTouchMetaState() {
    318         mTouchMetaState = 0;
    319     }
    320 
    321     private int contentsToWindowX(int x) {
    322         return (int) (x * mWebView.getScale()) - mWebView.getScrollX();
    323     }
    324 
    325     private int contentsToWindowY(int y) {
    326         return (int) (y * mWebView.getScale()) - mWebView.getScrollY();
    327     }
    328 
    329     private WebView mWebView = null;
    330     private int mouseX;
    331     private int mouseY;
    332 
    333     private class TouchPoint {
    334         private int mX;
    335         private int mY;
    336         private long mDownTime;
    337         private boolean mReleased;
    338         private boolean mMoved;
    339         private boolean mCancelled;
    340 
    341         public TouchPoint(int x, int y) {
    342             mX = x;
    343             mY = y;
    344             mReleased = false;
    345             mMoved = false;
    346             mCancelled = false;
    347         }
    348 
    349         public void setDownTime(long downTime) { mDownTime = downTime; }
    350         public long downTime() { return mDownTime; }
    351         public void cancel() { mCancelled = true; }
    352 
    353         public boolean cancelled() { return mCancelled; }
    354 
    355         public void release() { mReleased = true; }
    356         public boolean isReleased() { return mReleased; }
    357 
    358         public void setMoved(boolean moved) { mMoved = moved; }
    359         public boolean hasMoved() { return mMoved; }
    360 
    361         public int getX() { return mX; }
    362         public int getY() { return mY; }
    363 
    364         public void update(int x, int y) {
    365             mX = x;
    366             mY = y;
    367         }
    368     };
    369 
    370     private Vector<TouchPoint> mTouchPoints;
    371     private int mTouchMetaState;
    372 }
    373