Last big work on #1991910: Make swipes work with capacitive keys

This takes care of allowing us to cancel the back button.  The
back button is a bear because it is strewn all over the place --
everywhere you can close something, there is some code looking
for the back button that now needs to deal with being canceled.

The main things changed are activity (of course), dialog,
input method, search dialog.  There are some other misc places
in the framework (and some I missed here that I will get in a
second pass).

To facility all of this, the key dispatching APIs now provide
a lot more support for dealing with looking for cancelled keys,
and incidentally also provide an actual API for catching long
key presses.  This also helped clean up the code in PhoneWindow
where it deals with all of the combinations of key pressed and
releases.  (And also allows people to override
Activity.onKeyLongPress() to provide a different long press
action for a standard key like search.)

And while I was doing this, I reworked how we detect long
presses by having this be part of the key event delivered by
the window manager.  This should greatly reduce (hopefully
outright eliminate) the problems with long presses being
mis-detected when an application is being slow.

Change-Id: Ia19066b8d588d573df3eee6d96e1c90fdc19f57d
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2cc243e..6ff0fc8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2600,6 +2600,10 @@
         if (mOnFocusChangeListener != null) {
             mOnFocusChangeListener.onFocusChange(this, gainFocus);
         }
+        
+        if (mAttachInfo != null) {
+            mAttachInfo.mKeyDispatchState.reset(this);
+        }
     }
 
     /**
@@ -3609,6 +3613,16 @@
     }
 
     /**
+     * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
+     * for this view's window.  Returns null if the view is not currently attached
+     * to the window.  Normally you will not need to use this directly, but
+     * just use the standard high-level event callbacks like {@link #onKeyDown}.
+     */
+    public KeyEvent.DispatcherState getKeyDispatcherState() {
+        return mAttachInfo != null ? mAttachInfo.mKeyDispatchState : null;
+    }
+    
+    /**
      * Dispatch a key event before it is processed by any input method
      * associated with the view hierarchy.  This can be used to intercept
      * key events in special situations before the IME consumes them; a
@@ -3645,7 +3659,8 @@
             return true;
         }
 
-        return event.dispatch(this);
+        return event.dispatch(this, mAttachInfo != null
+                ? mAttachInfo.mKeyDispatchState : null, this);
     }
 
     /**
@@ -3910,6 +3925,15 @@
     }
 
     /**
+     * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
+     * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
+     * the event).
+     */
+    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+        return false;
+    }
+
+    /**
      * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
      * KeyEvent.Callback.onKeyMultiple()}: perform clicking of the view
      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or
@@ -8572,6 +8596,9 @@
          */
         final ArrayList<View> mScrollContainers = new ArrayList<View>();
 
+        final KeyEvent.DispatcherState mKeyDispatchState
+                = new KeyEvent.DispatcherState();
+
         /**
          * Indicates whether the view's window currently has the focus.
          */