mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-12-04 05:10:06 +08:00
add View::onFilterTouchEventForSecurity
This commit is contained in:
parent
18acce3218
commit
316f8996f3
@ -143,7 +143,10 @@ View::View(Context*ctx,const AttributeSet&attrs){
|
||||
setPivotY(attrs.getDimensionPixelSize("transformPivotY",0));
|
||||
|
||||
setKeyboardNavigationCluster( attrs.getBoolean("keyboardNavigationCluster",false) );
|
||||
|
||||
if(attrs.getBoolean("filterTouchesWhenObscured",false)){
|
||||
viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED;
|
||||
viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED;
|
||||
}
|
||||
if( attrs.getBoolean( "focusableInTouchMode" , false ) ){
|
||||
viewFlagValues &= ~FOCUSABLE_AUTO;
|
||||
viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE;
|
||||
@ -161,6 +164,10 @@ View::View(Context*ctx,const AttributeSet&attrs){
|
||||
viewFlagValues |= LONG_CLICKABLE;
|
||||
viewFlagMasks |= LONG_CLICKABLE;
|
||||
}
|
||||
if( !attrs.getBoolean("saveEnabled",true)){
|
||||
viewFlagValues |=SAVE_DISABLED;
|
||||
viewFlagMasks |=SAVE_DISABLED_MASK;
|
||||
}
|
||||
if(attrs.getBoolean("duplicateParentState",false)){
|
||||
viewFlagValues |= DUPLICATE_PARENT_STATE;
|
||||
viewFlagMasks |= DUPLICATE_PARENT_STATE;
|
||||
@ -6061,6 +6068,27 @@ bool View::canReceivePointerEvents()const{
|
||||
return (mViewFlags & VISIBILITY_MASK) == VISIBLE || getAnimation() != nullptr;
|
||||
}
|
||||
|
||||
bool View::getFilterTouchesWhenObscured() const{
|
||||
return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0;
|
||||
}
|
||||
|
||||
View& View::setFilterTouchesWhenObscured(bool enabled) {
|
||||
setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
|
||||
FILTER_TOUCHES_WHEN_OBSCURED);
|
||||
//calculateAccessibilityDataSensitive();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool View::onFilterTouchEventForSecurity(MotionEvent& event){
|
||||
//noinspection RedundantIfStatement
|
||||
if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
|
||||
&& (event.getFlags() & MotionEvent::FLAG_WINDOW_IS_OBSCURED) != 0) {
|
||||
// Window is obscured, drop this touch.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool View::dispatchTrackballEvent(MotionEvent& event){
|
||||
if (mInputEventConsistencyVerifier) {
|
||||
mInputEventConsistencyVerifier->onTrackballEvent(event, 0);
|
||||
@ -6157,10 +6185,10 @@ bool View::dispatchGenericMotionEvent(MotionEvent&event){
|
||||
if (mInputEventConsistencyVerifier)
|
||||
mInputEventConsistencyVerifier->onGenericMotionEvent(event, 0);
|
||||
if ((source & InputDevice::SOURCE_CLASS_POINTER) != 0) {
|
||||
int action = event.getAction();
|
||||
if (action == MotionEvent::ACTION_HOVER_ENTER
|
||||
|| action == MotionEvent::ACTION_HOVER_MOVE
|
||||
|| action == MotionEvent::ACTION_HOVER_EXIT) {
|
||||
const int action = event.getAction();
|
||||
if ((action == MotionEvent::ACTION_HOVER_ENTER)
|
||||
|| (action == MotionEvent::ACTION_HOVER_MOVE)
|
||||
|| (action == MotionEvent::ACTION_HOVER_EXIT)) {
|
||||
if (dispatchHoverEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
@ -6184,29 +6212,31 @@ bool View::dispatchTouchEvent(MotionEvent&event){
|
||||
if (mInputEventConsistencyVerifier)
|
||||
mInputEventConsistencyVerifier->onTouchEvent(event, 0);
|
||||
|
||||
if (actionMasked == MotionEvent::ACTION_UP ||
|
||||
actionMasked == MotionEvent::ACTION_CANCEL ||
|
||||
(actionMasked == MotionEvent::ACTION_DOWN && !result)) {
|
||||
if ( (actionMasked == MotionEvent::ACTION_UP) ||
|
||||
(actionMasked == MotionEvent::ACTION_CANCEL) ||
|
||||
(actionMasked == MotionEvent::ACTION_DOWN && !result)) {
|
||||
stopNestedScroll();
|
||||
}
|
||||
|
||||
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
|
||||
result = true;
|
||||
}
|
||||
if(onFilterTouchEventForSecurity(event)){
|
||||
if (((mViewFlags & ENABLED_MASK) == ENABLED) && handleScrollBarDragging(event)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
if ( mListenerInfo && mListenerInfo->mOnTouchListener
|
||||
&& (mViewFlags & ENABLED_MASK) == ENABLED
|
||||
&& mListenerInfo->mOnTouchListener(*this, event)) {
|
||||
result = true;
|
||||
}
|
||||
if ( mListenerInfo && mListenerInfo->mOnTouchListener
|
||||
&& ((mViewFlags & ENABLED_MASK) == ENABLED)
|
||||
&& mListenerInfo->mOnTouchListener(*this, event)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
if(!result&& onTouchEvent(event)){
|
||||
result=true;
|
||||
if(!result&& onTouchEvent(event)){
|
||||
result=true;
|
||||
}
|
||||
}
|
||||
if (!result && mInputEventConsistencyVerifier)
|
||||
mInputEventConsistencyVerifier->onUnhandledEvent(event, 0);
|
||||
if (actionMasked == MotionEvent::ACTION_UP ||
|
||||
actionMasked == MotionEvent::ACTION_CANCEL ||
|
||||
if ( (actionMasked == MotionEvent::ACTION_UP) ||
|
||||
(actionMasked == MotionEvent::ACTION_CANCEL) ||
|
||||
(actionMasked == MotionEvent::ACTION_DOWN && !result)) {
|
||||
stopNestedScroll();
|
||||
}
|
||||
|
@ -236,16 +236,15 @@ public:
|
||||
SCROLLBARS_VERTICAL = 0x200 ,
|
||||
SCROLLBARS_MASK = 0x300 ,
|
||||
|
||||
CLIPCHILDREN = 0x400 ,
|
||||
TRANSPARENT = 0x800 ,
|
||||
FILTER_TOUCHES_WHEN_OBSCURED = 0x400,//CLIPCHILDREN = 0x400 ,TRANSPARENT = 0x800 ,
|
||||
|
||||
FADING_EDGE_NONE =0x000000 ,
|
||||
FADING_EDGE_NONE = 0x000000 ,
|
||||
FADING_EDGE_HORIZONTAL= 0x1000 ,
|
||||
FADING_EDGE_VERTICAL = 0x2000 ,
|
||||
FADING_EDGE_MASK = 0x3000 ,
|
||||
|
||||
CLICKABLE = 0x4000 ,
|
||||
DRAWING_CACHE_ENABLED = 0x8000 ,
|
||||
DRAWING_CACHE_ENABLED = 0x8000 ,
|
||||
|
||||
SAVE_DISABLED = 0x000010000,
|
||||
SAVE_DISABLED_MASK = 0x000010000,
|
||||
@ -262,10 +261,10 @@ public:
|
||||
DRAWING_CACHE_QUALITY_AUTO = 0x00000000 ,
|
||||
DRAWING_CACHE_QUALITY_MASK = 0x00180000 ,
|
||||
|
||||
MEASURED_HEIGHT_STATE_SHIFT=16 ,
|
||||
MEASURED_STATE_TOO_SMALL=0x1000000 ,
|
||||
MEASURED_SIZE_MASK =0x00ffffff ,
|
||||
MEASURED_STATE_MASK=0xff000000 ,
|
||||
MEASURED_HEIGHT_STATE_SHIFT= 16 ,
|
||||
MEASURED_STATE_TOO_SMALL= 0x1000000 ,
|
||||
MEASURED_SIZE_MASK = 0x00ffffff ,
|
||||
MEASURED_STATE_MASK= 0xff000000 ,
|
||||
|
||||
//FocusDirection{
|
||||
FOCUS_BACKWARD=0x01 ,
|
||||
@ -612,7 +611,10 @@ protected:
|
||||
virtual void dispatchCancelPendingInputEvents();
|
||||
virtual void onCancelPendingInputEvents();
|
||||
bool canReceivePointerEvents()const;
|
||||
bool getFilterTouchesWhenObscured()const;
|
||||
View& setFilterTouchesWhenObscured(bool enabled);
|
||||
virtual bool dispatchHoverEvent(MotionEvent&event);
|
||||
virtual bool onFilterTouchEventForSecurity(MotionEvent& event);
|
||||
virtual bool dispatchTrackballEvent(MotionEvent& event);
|
||||
virtual bool dispatchCapturedPointerEvent(MotionEvent& event);
|
||||
virtual bool dispatchGenericPointerEvent(MotionEvent& event);
|
||||
|
@ -2899,134 +2899,136 @@ bool ViewGroup::dispatchTouchEvent(MotionEvent&ev){
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
if (actionMasked == MotionEvent::ACTION_DOWN) {
|
||||
cancelAndClearTouchTargets(&ev);
|
||||
resetTouchState();
|
||||
}
|
||||
// Check for interception.
|
||||
bool intercepted=false;
|
||||
if((actionMasked == MotionEvent::ACTION_DOWN)||mFirstTouchTarget){
|
||||
const bool disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
|
||||
if (!disallowIntercept) {
|
||||
intercepted = onInterceptTouchEvent(ev);
|
||||
ev.setAction(action); // restore action in case it was changed
|
||||
if(onFilterTouchEventForSecurity(ev)){
|
||||
if (actionMasked == MotionEvent::ACTION_DOWN) {
|
||||
cancelAndClearTouchTargets(&ev);
|
||||
resetTouchState();
|
||||
}
|
||||
}else{
|
||||
intercepted=true;
|
||||
}
|
||||
|
||||
if (intercepted || mFirstTouchTarget != nullptr) {
|
||||
ev.setTargetAccessibilityFocus(false);
|
||||
}
|
||||
// Check for cancelation.
|
||||
const bool canceled = resetCancelNextUpFlag(this)|| actionMasked == MotionEvent::ACTION_CANCEL;
|
||||
// Check for interception.
|
||||
bool intercepted=false;
|
||||
if((actionMasked == MotionEvent::ACTION_DOWN)||mFirstTouchTarget){
|
||||
const bool disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
|
||||
if (!disallowIntercept) {
|
||||
intercepted = onInterceptTouchEvent(ev);
|
||||
ev.setAction(action); // restore action in case it was changed
|
||||
}
|
||||
}else{
|
||||
intercepted=true;
|
||||
}
|
||||
|
||||
if (intercepted || mFirstTouchTarget != nullptr) {
|
||||
ev.setTargetAccessibilityFocus(false);
|
||||
}
|
||||
// Check for cancelation.
|
||||
const bool canceled = resetCancelNextUpFlag(this)|| actionMasked == MotionEvent::ACTION_CANCEL;
|
||||
|
||||
const bool split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
|
||||
TouchTarget* newTouchTarget = nullptr;
|
||||
bool alreadyDispatchedToNewTouchTarget = false;
|
||||
const bool split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
|
||||
TouchTarget* newTouchTarget = nullptr;
|
||||
bool alreadyDispatchedToNewTouchTarget = false;
|
||||
|
||||
if(!canceled && !intercepted){
|
||||
if( (actionMasked == MotionEvent::ACTION_DOWN) || (split && (actionMasked == MotionEvent::ACTION_POINTER_DOWN))
|
||||
|| (actionMasked == MotionEvent::ACTION_HOVER_MOVE) ){
|
||||
const int actionIndex = ev.getActionIndex(); // always 0 for down
|
||||
const int idBitsToAssign = split ? (1 << ev.getPointerId(actionIndex)) : TouchTarget::ALL_POINTER_IDS;
|
||||
if(!canceled && !intercepted){
|
||||
if( (actionMasked == MotionEvent::ACTION_DOWN) || (split && (actionMasked == MotionEvent::ACTION_POINTER_DOWN))
|
||||
|| (actionMasked == MotionEvent::ACTION_HOVER_MOVE) ){
|
||||
const int actionIndex = ev.getActionIndex(); // always 0 for down
|
||||
const int idBitsToAssign = split ? (1 << ev.getPointerId(actionIndex)) : TouchTarget::ALL_POINTER_IDS;
|
||||
|
||||
removePointersFromTouchTargets(idBitsToAssign);
|
||||
const int childrenCount = mChildren.size();
|
||||
if ((newTouchTarget == nullptr) && childrenCount){
|
||||
const int x = ev.getXDispatchLocation(actionIndex);
|
||||
const int y = ev.getYDispatchLocation(actionIndex);
|
||||
removePointersFromTouchTargets(idBitsToAssign);
|
||||
const int childrenCount = mChildren.size();
|
||||
if ((newTouchTarget == nullptr) && childrenCount){
|
||||
const int x = ev.getXDispatchLocation(actionIndex);
|
||||
const int y = ev.getYDispatchLocation(actionIndex);
|
||||
|
||||
std::vector<View*>preorderedList = buildTouchDispatchChildList();
|
||||
const bool customOrder = preorderedList.empty() && isChildrenDrawingOrderEnabled();
|
||||
std::vector<View*>&children = mChildren;
|
||||
for(int i = childrenCount-1;i >= 0;i--){
|
||||
const int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
|
||||
View* child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
|
||||
if (!canViewReceivePointerEvents(*child) || !isTransformedTouchPointInView(x, y,*child, nullptr)) {
|
||||
ev.setTargetAccessibilityFocus(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
newTouchTarget = getTouchTarget(child);
|
||||
if (newTouchTarget) {
|
||||
// Child is already receiving touch within its bounds.
|
||||
// Give it the new pointer in addition to the ones it is handling.
|
||||
newTouchTarget->pointerIdBits |= idBitsToAssign;
|
||||
break;
|
||||
}
|
||||
|
||||
resetCancelNextUpFlag(child);
|
||||
if(dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)){
|
||||
mLastTouchDownTime = ev.getDownTime();
|
||||
if(preorderedList.size()){
|
||||
for(int j=0;j<childrenCount;j++){
|
||||
if(children[childIndex]==mChildren[j]){
|
||||
mLastTouchDownIndex=j; break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
mLastTouchDownIndex = childIndex;
|
||||
std::vector<View*>preorderedList = buildTouchDispatchChildList();
|
||||
const bool customOrder = preorderedList.empty() && isChildrenDrawingOrderEnabled();
|
||||
std::vector<View*>&children = mChildren;
|
||||
for(int i = childrenCount-1;i >= 0;i--){
|
||||
const int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
|
||||
View* child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
|
||||
if (!canViewReceivePointerEvents(*child) || !isTransformedTouchPointInView(x, y,*child, nullptr)) {
|
||||
ev.setTargetAccessibilityFocus(false);
|
||||
continue;
|
||||
}
|
||||
mLastTouchDownX = ev.getX() ;
|
||||
mLastTouchDownY = ev.getY() ;
|
||||
newTouchTarget=addTouchTarget(child,idBitsToAssign);
|
||||
alreadyDispatchedToNewTouchTarget = true;
|
||||
break;
|
||||
|
||||
newTouchTarget = getTouchTarget(child);
|
||||
if (newTouchTarget) {
|
||||
// Child is already receiving touch within its bounds.
|
||||
// Give it the new pointer in addition to the ones it is handling.
|
||||
newTouchTarget->pointerIdBits |= idBitsToAssign;
|
||||
break;
|
||||
}
|
||||
|
||||
resetCancelNextUpFlag(child);
|
||||
if(dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)){
|
||||
mLastTouchDownTime = ev.getDownTime();
|
||||
if(preorderedList.size()){
|
||||
for(int j=0;j<childrenCount;j++){
|
||||
if(children[childIndex]==mChildren[j]){
|
||||
mLastTouchDownIndex=j; break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
mLastTouchDownIndex = childIndex;
|
||||
}
|
||||
mLastTouchDownX = ev.getX() ;
|
||||
mLastTouchDownY = ev.getY() ;
|
||||
newTouchTarget=addTouchTarget(child,idBitsToAssign);
|
||||
alreadyDispatchedToNewTouchTarget = true;
|
||||
break;
|
||||
}
|
||||
ev.setTargetAccessibilityFocus(false);
|
||||
}
|
||||
ev.setTargetAccessibilityFocus(false);
|
||||
preorderedList.clear();
|
||||
}
|
||||
preorderedList.clear();
|
||||
}
|
||||
if ( (newTouchTarget == nullptr) && mFirstTouchTarget) {
|
||||
// Did not find a child to receive the event.
|
||||
// Assign the pointer to the least recently added target.
|
||||
newTouchTarget = mFirstTouchTarget;
|
||||
while (newTouchTarget->next) {
|
||||
newTouchTarget = newTouchTarget->next;
|
||||
if ( (newTouchTarget == nullptr) && mFirstTouchTarget) {
|
||||
// Did not find a child to receive the event.
|
||||
// Assign the pointer to the least recently added target.
|
||||
newTouchTarget = mFirstTouchTarget;
|
||||
while (newTouchTarget->next) {
|
||||
newTouchTarget = newTouchTarget->next;
|
||||
}
|
||||
newTouchTarget->pointerIdBits |= idBitsToAssign;
|
||||
}
|
||||
newTouchTarget->pointerIdBits |= idBitsToAssign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch to touch targets.
|
||||
if (mFirstTouchTarget == nullptr){
|
||||
handled = dispatchTransformedTouchEvent(ev, canceled, nullptr,TouchTarget::ALL_POINTER_IDS);
|
||||
}else{
|
||||
TouchTarget* predecessor = nullptr;
|
||||
TouchTarget* target = mFirstTouchTarget;
|
||||
while (target ) {
|
||||
TouchTarget* next = target->next;
|
||||
if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
|
||||
handled = true;
|
||||
} else {
|
||||
const bool cancelChild = resetCancelNextUpFlag(target->child)|| intercepted;
|
||||
if (dispatchTransformedTouchEvent(ev, cancelChild, target->child, target->pointerIdBits)) {
|
||||
|
||||
// Dispatch to touch targets.
|
||||
if (mFirstTouchTarget == nullptr){
|
||||
handled = dispatchTransformedTouchEvent(ev, canceled, nullptr,TouchTarget::ALL_POINTER_IDS);
|
||||
}else{
|
||||
TouchTarget* predecessor = nullptr;
|
||||
TouchTarget* target = mFirstTouchTarget;
|
||||
while (target ) {
|
||||
TouchTarget* next = target->next;
|
||||
if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
|
||||
handled = true;
|
||||
}
|
||||
if (cancelChild) {
|
||||
if (predecessor == nullptr) mFirstTouchTarget = next;
|
||||
else predecessor->next = next;
|
||||
target->recycle();
|
||||
target = next;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const bool cancelChild = resetCancelNextUpFlag(target->child)|| intercepted;
|
||||
if (dispatchTransformedTouchEvent(ev, cancelChild, target->child, target->pointerIdBits)) {
|
||||
handled = true;
|
||||
}
|
||||
if (cancelChild) {
|
||||
if (predecessor == nullptr) mFirstTouchTarget = next;
|
||||
else predecessor->next = next;
|
||||
target->recycle();
|
||||
target = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
predecessor = target;
|
||||
target = next;
|
||||
}
|
||||
predecessor = target;
|
||||
target = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update list of touch targets for pointer up or cancel, if needed.
|
||||
if (canceled || (actionMasked == MotionEvent::ACTION_UP)
|
||||
|| (actionMasked == MotionEvent::ACTION_HOVER_MOVE) ) {
|
||||
resetTouchState();
|
||||
} else if (split && (actionMasked == MotionEvent::ACTION_POINTER_UP) ) {
|
||||
int actionIndex = ev.getActionIndex();
|
||||
int idBitsToRemove = 1 << ev.getPointerId(actionIndex);
|
||||
removePointersFromTouchTargets(idBitsToRemove);
|
||||
}
|
||||
// Update list of touch targets for pointer up or cancel, if needed.
|
||||
if (canceled || (actionMasked == MotionEvent::ACTION_UP)
|
||||
|| (actionMasked == MotionEvent::ACTION_HOVER_MOVE) ) {
|
||||
resetTouchState();
|
||||
} else if (split && (actionMasked == MotionEvent::ACTION_POINTER_UP) ) {
|
||||
int actionIndex = ev.getActionIndex();
|
||||
int idBitsToRemove = 1 << ev.getPointerId(actionIndex);
|
||||
removePointersFromTouchTargets(idBitsToRemove);
|
||||
}
|
||||
}
|
||||
if (!handled && mInputEventConsistencyVerifier)
|
||||
mInputEventConsistencyVerifier->onUnhandledEvent(ev, 1);
|
||||
return handled;
|
||||
|
Loading…
Reference in New Issue
Block a user