Fix key debounce (was too aggressive and buggy) and dismiss mini keyboard on cancel event.

Set a 70ms debounce time - i.e., if you spend less than 70ms on the touch-up key,
which was less time than the time spent on the previous key (assuming they weren't the same),
then don't emit the last key. Use the previous key that you lingered on for longer.
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 28a86b8..9201e3b 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -165,6 +165,7 @@
 
     private static final int DELAY_BEFORE_PREVIEW = 0;
     private static final int DELAY_AFTER_PREVIEW = 70;
+    private static final int DEBOUNCE_TIME = 70;
     
     private int mVerticalCorrection;
     private int mProximityThreshold;
@@ -1122,7 +1123,8 @@
         mSwipeTracker.addMovement(me);
 
         // Ignore all motion events until a DOWN.
-        if (mAbortKey && action != MotionEvent.ACTION_DOWN) {
+        if (mAbortKey
+                && action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_CANCEL) {
             return true;
         }
 
@@ -1206,6 +1208,7 @@
                     }
                 }
                 showPreview(mCurrentKey);
+                mLastMoveTime = eventTime;
                 break;
 
             case MotionEvent.ACTION_UP:
@@ -1219,7 +1222,8 @@
                     mCurrentKey = keyIndex;
                     mCurrentKeyTime = 0;
                 }
-                if (mCurrentKeyTime < mLastKeyTime && mLastKey != NOT_A_KEY) {
+                if (mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < DEBOUNCE_TIME
+                        && mLastKey != NOT_A_KEY) {
                     mCurrentKey = mLastKey;
                     touchX = mLastCodeX;
                     touchY = mLastCodeY;