summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/InputEventConsistencyVerifier.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/view/InputEventConsistencyVerifier.java')
-rw-r--r--core/java/android/view/InputEventConsistencyVerifier.java71
1 files changed, 71 insertions, 0 deletions
diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java
index c5e4c21..46ef379 100644
--- a/core/java/android/view/InputEventConsistencyVerifier.java
+++ b/core/java/android/view/InputEventConsistencyVerifier.java
@@ -97,6 +97,9 @@ public final class InputEventConsistencyVerifier {
// Set to true if we received hover enter.
private boolean mHoverEntered;
+ // The bitset of buttons which we've received ACTION_BUTTON_PRESS for.
+ private int mButtonsPressed;
+
// The current violation message.
private StringBuilder mViolationMessage;
@@ -148,6 +151,7 @@ public final class InputEventConsistencyVerifier {
mTouchEventStreamIsTainted = false;
mTouchEventStreamUnhandled = false;
mHoverEntered = false;
+ mButtonsPressed = 0;
while (mKeyStateList != null) {
final KeyState state = mKeyStateList;
@@ -466,6 +470,8 @@ public final class InputEventConsistencyVerifier {
final int action = event.getAction();
final int source = event.getSource();
+ final int buttonState = event.getButtonState();
+ final int actionButton = event.getActionButton();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
@@ -486,6 +492,62 @@ public final class InputEventConsistencyVerifier {
ensureHistorySizeIsZeroForThisAction(event);
ensurePointerCountIsOneForThisAction(event);
break;
+ case MotionEvent.ACTION_BUTTON_PRESS:
+ ensureActionButtonIsNonZeroForThisAction(event);
+ if ((mButtonsPressed & actionButton) != 0) {
+ problem("Action button for ACTION_BUTTON_PRESS event is " +
+ actionButton + ", but it has already been pressed and " +
+ "has yet to be released.");
+ }
+
+ mButtonsPressed |= actionButton;
+ // The system will automatically mirror the stylus buttons onto the button
+ // state as the old set of generic buttons for apps targeting pre-M. If
+ // it looks this has happened, go ahead and set the generic buttons as
+ // pressed to prevent spurious errors.
+ if (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY &&
+ (buttonState & MotionEvent.BUTTON_SECONDARY) != 0) {
+ mButtonsPressed |= MotionEvent.BUTTON_SECONDARY;
+ } else if (actionButton == MotionEvent.BUTTON_STYLUS_SECONDARY &&
+ (buttonState & MotionEvent.BUTTON_TERTIARY) != 0) {
+ mButtonsPressed |= MotionEvent.BUTTON_TERTIARY;
+ }
+
+ if (mButtonsPressed != buttonState) {
+ problem(String.format("Reported button state differs from " +
+ "expected button state based on press and release events. " +
+ "Is 0x%08x but expected 0x%08x.",
+ buttonState, mButtonsPressed));
+ }
+ break;
+ case MotionEvent.ACTION_BUTTON_RELEASE:
+ ensureActionButtonIsNonZeroForThisAction(event);
+ if ((mButtonsPressed & actionButton) != actionButton) {
+ problem("Action button for ACTION_BUTTON_RELEASE event is " +
+ actionButton + ", but it was either never pressed or has " +
+ "already been released.");
+ }
+
+ mButtonsPressed &= ~actionButton;
+ // The system will automatically mirror the stylus buttons onto the button
+ // state as the old set of generic buttons for apps targeting pre-M. If
+ // it looks this has happened, go ahead and set the generic buttons as
+ // released to prevent spurious errors.
+ if (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY &&
+ (buttonState & MotionEvent.BUTTON_SECONDARY) == 0) {
+ mButtonsPressed &= ~MotionEvent.BUTTON_SECONDARY;
+ } else if (actionButton == MotionEvent.BUTTON_STYLUS_SECONDARY &&
+ (buttonState & MotionEvent.BUTTON_TERTIARY) == 0) {
+ mButtonsPressed &= ~MotionEvent.BUTTON_TERTIARY;
+ }
+
+ if (mButtonsPressed != buttonState) {
+ problem(String.format("Reported button state differs from " +
+ "expected button state based on press and release events. " +
+ "Is 0x%08x but expected 0x%08x.",
+ buttonState, mButtonsPressed));
+ }
+ break;
default:
problem("Invalid action for generic pointer event.");
break;
@@ -563,6 +625,15 @@ public final class InputEventConsistencyVerifier {
}
}
+ private void ensureActionButtonIsNonZeroForThisAction(MotionEvent event) {
+ final int actionButton = event.getActionButton();
+ if (actionButton == 0) {
+ problem("No action button set. Action button should always be non-zero for " +
+ MotionEvent.actionToString(event.getAction()));
+
+ }
+ }
+
private void ensureHistorySizeIsZeroForThisAction(MotionEvent event) {
final int historySize = event.getHistorySize();
if (historySize != 0) {