Add MotionEvent.HOVER_ENTER and HOVER_EXIT.

The input dispatcher sends a HOVER_ENTER to a window before dispatching
it any HOVER_MOVE events.  For compatibility reasons, the window will
*also* receive the HOVER_MOVE.  When the pointer moves into a different
window or the pointer goes down or when events are canceled for some reason,
the input dispatcher sends a HOVER_EXIT to the previously hovered window.

The view hierarchy behavior is similar.  All views under the pointer
receive onHoverEvent with HOVER_ENTER followed by any number of HOVER_MOVE
events.  When the pointer leaves a view, the view receives HOVER_EXIT.
Similarly, if a parent view decides to capture hover by returning true
from onHoverEvent, the hovered descendants will receive HOVER_EXIT.

The default behavior of onHoverEvent is to update the view's hovered
state by calling setHovered(true/false).  Views can query their current
hovered state using isHovered().

For testing purposes, the hovered state is mapped to the pressed
drawable state.  This will change in a subsequent commit with the
introduction of a new hovered drawable state.

Change-Id: Ib76a7a90236c8f2c7336e55773acade6346cacbe
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 94753bf..82cf62f 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -1605,8 +1605,15 @@
             motionEventAction, 0, metaState, motionEventEdgeFlags,
             1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
 
-    mAccumulator.clear();
+    // Send hover move after UP to tell the application that the mouse is hovering now.
+    if (motionEventAction == AMOTION_EVENT_ACTION_UP
+            && mPointerController != NULL) {
+        getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+                1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
+    }
 
+    // Send scroll events.
     if (vscroll != 0 || hscroll != 0) {
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
@@ -1615,6 +1622,8 @@
                 AMOTION_EVENT_ACTION_SCROLL, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
                 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
     }
+
+    mAccumulator.clear();
 }
 
 int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {