Loading cmds/statsd/src/atoms.proto +18 −7 Original line number Diff line number Diff line Loading @@ -2757,17 +2757,28 @@ message BackGesture { COMPLETED = 1; COMPLETED_REJECTED = 2; // successful because coming from rejected area INCOMPLETE_EXCLUDED = 3; // would have been successful but in the exclusion area INCOMPLETE = 4; INCOMPLETE = 4; // Unsuccessful, for reasons other than below. INCOMPLETE_FAR_FROM_EDGE = 5; // Unsuccessful, far from the edge. INCOMPLETE_MULTI_TOUCH = 6; // Unsuccessful, multi touch. INCOMPLETE_LONG_PRESS = 7; // Unsuccessful, long press. INCOMPLETE_VERTICAL_MOVE = 8; // Unsuccessful, move vertically. } optional BackType type = 1; optional int32 y_coordinate = 2; // y coordinate for ACTION_DOWN event optional int32 y_coordinate = 2 [deprecated = true]; // y coordinate for ACTION_DOWN event optional int32 start_x = 4; // X coordinate for ACTION_DOWN event. optional int32 start_y = 5; // Y coordinate for ACTION_DOWN event. optional int32 end_x = 6; // X coordinate for ACTION_MOVE event. optional int32 end_y = 7; // Y coordinate for ACTION_MOVE event. optional int32 left_boundary = 8; // left edge width + left inset optional int32 right_boundary = 9; // screen width - (right edge width + right inset) enum WindowHorizontalLocation { DEFAULT_LOCATION = 0; LEFT = 1; RIGHT = 2; } optional WindowHorizontalLocation x_location = 3; optional WindowHorizontalLocation x_location = 3 [deprecated = true]; } message ExclusionRectStateChanged { Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +90 −43 Original line number Diff line number Diff line Loading @@ -110,10 +110,14 @@ public class EdgeBackGestureHandler implements DisplayListener, private final float mTouchSlop; // Duration after which we consider the event as longpress. private final int mLongPressTimeout; // The back gesture type private int mBackType; private final PointF mDownPoint = new PointF(); private final PointF mEndPoint = new PointF(); private boolean mThresholdCrossed = false; private boolean mAllowGesture = false; private boolean mLogGesture = false; private boolean mInRejectedExclusion = false; private boolean mIsOnLeftEdge; Loading Loading @@ -141,24 +145,16 @@ public class EdgeBackGestureHandler implements DisplayListener, mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x, (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); int backtype = (mInRejectedExclusion ? SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED : SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED); SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, (int) mDownPoint.y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT); logGesture(mInRejectedExclusion ? SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED : SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED); } @Override public void cancelBack() { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE); mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x, (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); int backtype = SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE; SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, (int) mDownPoint.y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT); } }; Loading Loading @@ -331,39 +327,55 @@ public class EdgeBackGestureHandler implements DisplayListener, } private boolean isWithinTouchRegion(int x, int y) { // Disallow if too far from the edge if (x > mEdgeWidthLeft + mLeftInset && x < (mDisplaySize.x - mEdgeWidthRight - mRightInset)) { // Disallow if we are in the bottom gesture area if (y >= (mDisplaySize.y - mBottomGestureHeight)) { return false; } // Disallow if we are in the bottom gesture area if (y >= (mDisplaySize.y - mBottomGestureHeight)) { // If the point is way too far (twice the margin), it is // not interesting to us for logging purposes, nor we // should process it. Simply return false and keep // mLogGesture = false. if (x > 2 * (mEdgeWidthLeft + mLeftInset) && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) { return false; } // Denotes whether we should proceed with the gesture. // Even if it is false, we may want to log it assuming // it is not invalid due to exclusion. boolean withinRange = x <= mEdgeWidthLeft + mLeftInset || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset); // Always allow if the user is in a transient sticky immersive state if (mIsNavBarShownTransiently) { return true; mLogGesture = true; return withinRange; } boolean isInExcludedRegion = mExcludeRegion.contains(x, y); if (isInExcludedRegion) { mOverviewProxyService.notifyBackAction(false /* completed */, -1, -1, false /* isButton */, !mIsOnLeftEdge); SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED, y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT); } else { mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y); if (mExcludeRegion.contains(x, y)) { if (withinRange) { // Log as exclusion only if it is in acceptable range in the first place. mOverviewProxyService.notifyBackAction( false /* completed */, -1, -1, false /* isButton */, !mIsOnLeftEdge); // We don't have the end point for logging purposes. mEndPoint.x = -1; mEndPoint.y = -1; mLogGesture = true; logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED); } return !isInExcludedRegion; return false; } mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y); mLogGesture = true; return withinRange; } private void cancelGesture(MotionEvent ev) { // Send action cancel to reset all the touch events mAllowGesture = false; mLogGesture = false; mInRejectedExclusion = false; MotionEvent cancelEv = MotionEvent.obtain(ev); cancelEv.setAction(MotionEvent.ACTION_CANCEL); Loading @@ -371,52 +383,87 @@ public class EdgeBackGestureHandler implements DisplayListener, cancelEv.recycle(); } private void logGesture(int backType) { if (!mLogGesture) { return; } mLogGesture = false; SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backType, (int) mDownPoint.y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT, (int) mDownPoint.x, (int) mDownPoint.y, (int) mEndPoint.x, (int) mEndPoint.y, mEdgeWidthLeft + mLeftInset, mDisplaySize.x - (mEdgeWidthRight + mRightInset)); } private void onMotionEvent(MotionEvent ev) { int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { // Verify if this is in within the touch region and we aren't in immersive mode, and // either the bouncer is showing or the notification panel is hidden mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset; mLogGesture = false; mInRejectedExclusion = false; mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags) && isWithinTouchRegion((int) ev.getX(), (int) ev.getY()); if (mAllowGesture) { mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge); mEdgeBackPlugin.onMotionEvent(ev); } if (mLogGesture) { mDownPoint.set(ev.getX(), ev.getY()); mEndPoint.set(-1, -1); mThresholdCrossed = false; } } else if (mAllowGesture) { } else if (mAllowGesture || mLogGesture) { if (!mThresholdCrossed) { mEndPoint.x = (int) ev.getX(); mEndPoint.y = (int) ev.getY(); if (action == MotionEvent.ACTION_POINTER_DOWN) { if (mAllowGesture) { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH); // We do not support multi touch for back gesture cancelGesture(ev); } mLogGesture = false; return; } else if (action == MotionEvent.ACTION_MOVE) { if ((ev.getEventTime() - ev.getDownTime()) > mLongPressTimeout) { if (mAllowGesture) { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_LONG_PRESS); cancelGesture(ev); } mLogGesture = false; return; } float dx = Math.abs(ev.getX() - mDownPoint.x); float dy = Math.abs(ev.getY() - mDownPoint.y); if (dy > dx && dy > mTouchSlop) { if (mAllowGesture) { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_VERTICAL_MOVE); cancelGesture(ev); } mLogGesture = false; return; } else if (dx > dy && dx > mTouchSlop) { if (mAllowGesture) { mThresholdCrossed = true; // Capture inputs mInputMonitor.pilferPointers(); } else { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_FAR_FROM_EDGE); } } } } if (mAllowGesture) { // forward touch mEdgeBackPlugin.onMotionEvent(ev); } } Dependency.get(ProtoTracer.class).update(); } Loading Loading
cmds/statsd/src/atoms.proto +18 −7 Original line number Diff line number Diff line Loading @@ -2757,17 +2757,28 @@ message BackGesture { COMPLETED = 1; COMPLETED_REJECTED = 2; // successful because coming from rejected area INCOMPLETE_EXCLUDED = 3; // would have been successful but in the exclusion area INCOMPLETE = 4; INCOMPLETE = 4; // Unsuccessful, for reasons other than below. INCOMPLETE_FAR_FROM_EDGE = 5; // Unsuccessful, far from the edge. INCOMPLETE_MULTI_TOUCH = 6; // Unsuccessful, multi touch. INCOMPLETE_LONG_PRESS = 7; // Unsuccessful, long press. INCOMPLETE_VERTICAL_MOVE = 8; // Unsuccessful, move vertically. } optional BackType type = 1; optional int32 y_coordinate = 2; // y coordinate for ACTION_DOWN event optional int32 y_coordinate = 2 [deprecated = true]; // y coordinate for ACTION_DOWN event optional int32 start_x = 4; // X coordinate for ACTION_DOWN event. optional int32 start_y = 5; // Y coordinate for ACTION_DOWN event. optional int32 end_x = 6; // X coordinate for ACTION_MOVE event. optional int32 end_y = 7; // Y coordinate for ACTION_MOVE event. optional int32 left_boundary = 8; // left edge width + left inset optional int32 right_boundary = 9; // screen width - (right edge width + right inset) enum WindowHorizontalLocation { DEFAULT_LOCATION = 0; LEFT = 1; RIGHT = 2; } optional WindowHorizontalLocation x_location = 3; optional WindowHorizontalLocation x_location = 3 [deprecated = true]; } message ExclusionRectStateChanged { Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +90 −43 Original line number Diff line number Diff line Loading @@ -110,10 +110,14 @@ public class EdgeBackGestureHandler implements DisplayListener, private final float mTouchSlop; // Duration after which we consider the event as longpress. private final int mLongPressTimeout; // The back gesture type private int mBackType; private final PointF mDownPoint = new PointF(); private final PointF mEndPoint = new PointF(); private boolean mThresholdCrossed = false; private boolean mAllowGesture = false; private boolean mLogGesture = false; private boolean mInRejectedExclusion = false; private boolean mIsOnLeftEdge; Loading Loading @@ -141,24 +145,16 @@ public class EdgeBackGestureHandler implements DisplayListener, mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x, (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); int backtype = (mInRejectedExclusion ? SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED : SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED); SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, (int) mDownPoint.y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT); logGesture(mInRejectedExclusion ? SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED : SysUiStatsLog.BACK_GESTURE__TYPE__COMPLETED); } @Override public void cancelBack() { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE); mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x, (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); int backtype = SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE; SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, (int) mDownPoint.y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT); } }; Loading Loading @@ -331,39 +327,55 @@ public class EdgeBackGestureHandler implements DisplayListener, } private boolean isWithinTouchRegion(int x, int y) { // Disallow if too far from the edge if (x > mEdgeWidthLeft + mLeftInset && x < (mDisplaySize.x - mEdgeWidthRight - mRightInset)) { // Disallow if we are in the bottom gesture area if (y >= (mDisplaySize.y - mBottomGestureHeight)) { return false; } // Disallow if we are in the bottom gesture area if (y >= (mDisplaySize.y - mBottomGestureHeight)) { // If the point is way too far (twice the margin), it is // not interesting to us for logging purposes, nor we // should process it. Simply return false and keep // mLogGesture = false. if (x > 2 * (mEdgeWidthLeft + mLeftInset) && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) { return false; } // Denotes whether we should proceed with the gesture. // Even if it is false, we may want to log it assuming // it is not invalid due to exclusion. boolean withinRange = x <= mEdgeWidthLeft + mLeftInset || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset); // Always allow if the user is in a transient sticky immersive state if (mIsNavBarShownTransiently) { return true; mLogGesture = true; return withinRange; } boolean isInExcludedRegion = mExcludeRegion.contains(x, y); if (isInExcludedRegion) { mOverviewProxyService.notifyBackAction(false /* completed */, -1, -1, false /* isButton */, !mIsOnLeftEdge); SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED, y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT); } else { mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y); if (mExcludeRegion.contains(x, y)) { if (withinRange) { // Log as exclusion only if it is in acceptable range in the first place. mOverviewProxyService.notifyBackAction( false /* completed */, -1, -1, false /* isButton */, !mIsOnLeftEdge); // We don't have the end point for logging purposes. mEndPoint.x = -1; mEndPoint.y = -1; mLogGesture = true; logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_EXCLUDED); } return !isInExcludedRegion; return false; } mInRejectedExclusion = mUnrestrictedExcludeRegion.contains(x, y); mLogGesture = true; return withinRange; } private void cancelGesture(MotionEvent ev) { // Send action cancel to reset all the touch events mAllowGesture = false; mLogGesture = false; mInRejectedExclusion = false; MotionEvent cancelEv = MotionEvent.obtain(ev); cancelEv.setAction(MotionEvent.ACTION_CANCEL); Loading @@ -371,52 +383,87 @@ public class EdgeBackGestureHandler implements DisplayListener, cancelEv.recycle(); } private void logGesture(int backType) { if (!mLogGesture) { return; } mLogGesture = false; SysUiStatsLog.write(SysUiStatsLog.BACK_GESTURE_REPORTED_REPORTED, backType, (int) mDownPoint.y, mIsOnLeftEdge ? SysUiStatsLog.BACK_GESTURE__X_LOCATION__LEFT : SysUiStatsLog.BACK_GESTURE__X_LOCATION__RIGHT, (int) mDownPoint.x, (int) mDownPoint.y, (int) mEndPoint.x, (int) mEndPoint.y, mEdgeWidthLeft + mLeftInset, mDisplaySize.x - (mEdgeWidthRight + mRightInset)); } private void onMotionEvent(MotionEvent ev) { int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { // Verify if this is in within the touch region and we aren't in immersive mode, and // either the bouncer is showing or the notification panel is hidden mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset; mLogGesture = false; mInRejectedExclusion = false; mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags) && isWithinTouchRegion((int) ev.getX(), (int) ev.getY()); if (mAllowGesture) { mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge); mEdgeBackPlugin.onMotionEvent(ev); } if (mLogGesture) { mDownPoint.set(ev.getX(), ev.getY()); mEndPoint.set(-1, -1); mThresholdCrossed = false; } } else if (mAllowGesture) { } else if (mAllowGesture || mLogGesture) { if (!mThresholdCrossed) { mEndPoint.x = (int) ev.getX(); mEndPoint.y = (int) ev.getY(); if (action == MotionEvent.ACTION_POINTER_DOWN) { if (mAllowGesture) { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH); // We do not support multi touch for back gesture cancelGesture(ev); } mLogGesture = false; return; } else if (action == MotionEvent.ACTION_MOVE) { if ((ev.getEventTime() - ev.getDownTime()) > mLongPressTimeout) { if (mAllowGesture) { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_LONG_PRESS); cancelGesture(ev); } mLogGesture = false; return; } float dx = Math.abs(ev.getX() - mDownPoint.x); float dy = Math.abs(ev.getY() - mDownPoint.y); if (dy > dx && dy > mTouchSlop) { if (mAllowGesture) { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_VERTICAL_MOVE); cancelGesture(ev); } mLogGesture = false; return; } else if (dx > dy && dx > mTouchSlop) { if (mAllowGesture) { mThresholdCrossed = true; // Capture inputs mInputMonitor.pilferPointers(); } else { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_FAR_FROM_EDGE); } } } } if (mAllowGesture) { // forward touch mEdgeBackPlugin.onMotionEvent(ev); } } Dependency.get(ProtoTracer.class).update(); } Loading