Program: 2890
Project: 2890
Buggy source:
/** 
 * Implement this method to handle hover events. <p> This method is called whenever a pointer is hovering into, over, or out of the bounds of a view and the view is not currently being touched. Hover events are represented as pointer events with action  {@link MotionEvent#ACTION_HOVER_ENTER},   {@link MotionEvent#ACTION_HOVER_MOVE}, or   {@link MotionEvent#ACTION_HOVER_EXIT}. </p> <ul> <li>The view receives a hover event with action   {@link MotionEvent#ACTION_HOVER_ENTER}when the pointer enters the bounds of the view.</li> <li>The view receives a hover event with action   {@link MotionEvent#ACTION_HOVER_MOVE}when the pointer has already entered the bounds of the view and has moved.</li> <li>The view receives a hover event with action   {@link MotionEvent#ACTION_HOVER_EXIT}when the pointer has exited the bounds of the view or when the pointer is about to go down due to a button click, tap, or similar user action that causes the view to be touched.</li> </ul> <p> The view should implement this method to return true to indicate that it is handling the hover event, such as by changing its drawable state. </p><p> The default implementation calls   {@link #setHovered} to update the hovered stateof the view when a hover enter or hover exit event is received, if the view is enabled and is clickable.  The default implementation also sends hover accessibility events. </p>
 * @param event The motion event that describes the hover.
 * @return True if the view handled the hover event.
 * @see #isHovered
 * @see #setHovered
 * @see #onHoverChanged
 */
public boolean onHoverEvent(MotionEvent event){
  final int action=event.getActionMasked();
  if (!mSendingHoverAccessibilityEvents) {
    if ((action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE) && !hasHoveredChild() && pointInView(event.getX(),event.getY())) {
      sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
      mSendingHoverAccessibilityEvents=true;
    }
  }
 else {
    if (action == MotionEvent.ACTION_HOVER_EXIT || (action == MotionEvent.ACTION_MOVE && !pointInView(event.getX(),event.getY()))) {
      mSendingHoverAccessibilityEvents=false;
      sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
      if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) {
        getViewRootImpl().setAccessibilityFocus(null,null);
      }
    }
  }
  if (isHoverable()) {
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
      setHovered(true);
    break;
case MotionEvent.ACTION_HOVER_EXIT:
  setHovered(false);
break;
}
dispatchGenericMotionEventInternal(event);
return true;
}
return false;
}

Fixed version (ground truth):
/** 
 * Implement this method to handle hover events. <p> This method is called whenever a pointer is hovering into, over, or out of the bounds of a view and the view is not currently being touched. Hover events are represented as pointer events with action  {@link MotionEvent#ACTION_HOVER_ENTER},   {@link MotionEvent#ACTION_HOVER_MOVE}, or   {@link MotionEvent#ACTION_HOVER_EXIT}. </p> <ul> <li>The view receives a hover event with action   {@link MotionEvent#ACTION_HOVER_ENTER}when the pointer enters the bounds of the view.</li> <li>The view receives a hover event with action   {@link MotionEvent#ACTION_HOVER_MOVE}when the pointer has already entered the bounds of the view and has moved.</li> <li>The view receives a hover event with action   {@link MotionEvent#ACTION_HOVER_EXIT}when the pointer has exited the bounds of the view or when the pointer is about to go down due to a button click, tap, or similar user action that causes the view to be touched.</li> </ul> <p> The view should implement this method to return true to indicate that it is handling the hover event, such as by changing its drawable state. </p><p> The default implementation calls   {@link #setHovered} to update the hovered stateof the view when a hover enter or hover exit event is received, if the view is enabled and is clickable.  The default implementation also sends hover accessibility events. </p>
 * @param event The motion event that describes the hover.
 * @return True if the view handled the hover event.
 * @see #isHovered
 * @see #setHovered
 * @see #onHoverChanged
 */
public boolean onHoverEvent(MotionEvent event){
  final int action=event.getActionMasked();
  if (!mSendingHoverAccessibilityEvents) {
    if ((action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE) && !hasHoveredChild() && pointInView(event.getX(),event.getY())) {
      sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
      mSendingHoverAccessibilityEvents=true;
    }
  }
 else {
    if (action == MotionEvent.ACTION_HOVER_EXIT || (action == MotionEvent.ACTION_MOVE && !pointInView(event.getX(),event.getY()))) {
      mSendingHoverAccessibilityEvents=false;
      sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
      if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) {
        getViewRootImpl().setAccessibilityFocus(null,null);
      }
    }
  }
  if (isHoverable()) {
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
      setHovered(true);
    break;
case MotionEvent.ACTION_HOVER_EXIT:
  setHovered(false);
break;
}
return dispatchGenericMotionEventInternal(event);
}
return false;
}