/**
* {@inheritDoc}
*/
@Override
public
boolean
dispatchTouchEvent(MotionEvent ev)
{
if
(mInputEventConsistencyVerifier !=
null
)
{
mInputEventConsistencyVerifier.onTouchEvent(ev,
1
);
}
boolean
handled =
false
;
if
(onFilterTouchEventForSecurity(ev))
{
final
int
action = ev.getAction();
final
int
actionMasked = action & MotionEvent.ACTION_MASK;
if
(actionMasked == MotionEvent.ACTION_DOWN)
{
cancelAndClearTouchTargets(ev);
resetTouchState();
}
final
boolean
intercepted;
if
(actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget !=
null
)
{
final
boolean
disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) !=
0
;
if
(!disallowIntercept)
{
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action);
}
else
{
intercepted =
false
;
}
}
else
{
intercepted =
true
;
}
final
boolean
canceled = resetCancelNextUpFlag(
this
) || actionMasked == MotionEvent.ACTION_CANCEL;
final
boolean
split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) !=
0
;
TouchTarget newTouchTarget =
null
;
boolean
alreadyDispatchedToNewTouchTarget =
false
;
if
(!canceled && !intercepted)
{
if
(actionMasked == MotionEvent.ACTION_DOWN || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE)
{
final
int
actionIndex = ev.getActionIndex();
final
int
idBitsToAssign = split ?
1
<< ev.getPointerId(actionIndex) : TouchTarget.ALL_POINTER_IDS;
removePointersFromTouchTargets(idBitsToAssign);
final
int
childrenCount = mChildrenCount;
if
(childrenCount !=
0
)
{
final
View[] children = mChildren;
final
float
x = ev.getX(actionIndex);
final
float
y = ev.getY(actionIndex);
for
(
int
i = childrenCount -
1
; i >=
0
; i--)
{
final
View child = children[i];
if
(!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child,
null
))
{
continue
;
}
newTouchTarget = getTouchTarget(child);
if
(newTouchTarget !=
null
)
{
newTouchTarget.pointerIdBits |= idBitsToAssign;
break
;
}
resetCancelNextUpFlag(child);
if
(dispatchTransformedTouchEvent(ev,
false
, child, idBitsToAssign))
{
mLastTouchDownTime = ev.getDownTime();
mLastTouchDownIndex = i;
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
newTouchTarget = addTouchTarget(child, idBitsToAssign);
alreadyDispatchedToNewTouchTarget =
true
;
break
;
}
}
}
if
(newTouchTarget ==
null
&& mFirstTouchTarget !=
null
)
{
newTouchTarget = mFirstTouchTarget;
while
(newTouchTarget.next !=
null
)
{
newTouchTarget = newTouchTarget.next;
}
newTouchTarget.pointerIdBits |= idBitsToAssign;
}
}
}
if
(mFirstTouchTarget ==
null
)
{
handled = dispatchTransformedTouchEvent(ev, canceled,
null
, TouchTarget.ALL_POINTER_IDS);
}
else
{
TouchTarget predecessor =
null
;
TouchTarget target = mFirstTouchTarget;
while
(target !=
null
)
{
final
TouchTarget next = target.next;
if
(alreadyDispatchedToNewTouchTarget && target == newTouchTarget)
{
handled =
true
;
}
else
{
final
boolean
cancelChild = resetCancelNextUpFlag(target.child) || intercepted;
if
(dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits))
{
handled =
true
;
}
if
(cancelChild)
{
if
(predecessor ==
null
)
{
mFirstTouchTarget = next;
}
else
{
predecessor.next = next;
}
target.recycle();
target = next;
continue
;
}
}
predecessor = target;
target = next;
}
}
if
(canceled || actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_HOVER_MOVE)
{
resetTouchState();
}
else
if
(split && actionMasked == MotionEvent.ACTION_POINTER_UP)
{
final
int
actionIndex = ev.getActionIndex();
final
int
idBitsToRemove =
1
<< ev.getPointerId(actionIndex);
removePointersFromTouchTargets(idBitsToRemove);
}
}
if
(!handled && mInputEventConsistencyVerifier !=
null
)
{
mInputEventConsistencyVerifier.onUnhandledEvent(ev,
1
);
}
return
handled;
}