/// <summary>Checks an arbitrary input event.</summary> /// <remarks>Checks an arbitrary input event.</remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onInputEvent(android.view.InputEvent @event, int nestingLevel) { if (@event is android.view.KeyEvent) { android.view.KeyEvent keyEvent = (android.view.KeyEvent)@event; onKeyEvent(keyEvent, nestingLevel); } else { android.view.MotionEvent motionEvent = (android.view.MotionEvent)@event; if (motionEvent.isTouchEvent()) { onTouchEvent(motionEvent, nestingLevel); } else { if ((motionEvent.getSource() & android.view.InputDevice.SOURCE_CLASS_TRACKBALL) != 0) { onTrackballEvent(motionEvent, nestingLevel); } else { onGenericMotionEvent(motionEvent, nestingLevel); } } } }
private static void appendEvent(java.lang.StringBuilder message, int index, android.view.InputEvent @event, bool unhandled) { message.append(index).append(": sent at ").append(@event.getEventTimeNano()); message.append(", "); if (unhandled) { message.append("(unhandled) "); } message.append(@event); }
private void finishEvent() { if (mViolationMessage != null && mViolationMessage.Length != 0) { if (!mCurrentEvent.isTainted()) { // Write a log message only if the event was not already tainted. mViolationMessage.append("\n in ").append(mCaller); mViolationMessage.append("\n "); appendEvent(mViolationMessage, 0, mCurrentEvent, false); if (RECENT_EVENTS_TO_LOG != 0 && mRecentEvents != null) { mViolationMessage.append("\n -- recent events --"); { for (int i = 0; i < RECENT_EVENTS_TO_LOG; i++) { int index = (mMostRecentEventIndex + RECENT_EVENTS_TO_LOG - i) % RECENT_EVENTS_TO_LOG; android.view.InputEvent @event = mRecentEvents[index]; if (@event == null) { break; } mViolationMessage.append("\n "); appendEvent(mViolationMessage, i + 1, @event, mRecentEventsUnhandled[index]); } } } android.util.Log.d(mLogTag, mViolationMessage.ToString()); // Taint the event so that we do not generate additional violations from it // further downstream. mCurrentEvent.setTainted(true); } mViolationMessage.setLength(0); } if (RECENT_EVENTS_TO_LOG != 0) { if (mRecentEvents == null) { mRecentEvents = new android.view.InputEvent[RECENT_EVENTS_TO_LOG]; mRecentEventsUnhandled = new bool[RECENT_EVENTS_TO_LOG]; } int index = (mMostRecentEventIndex + 1) % RECENT_EVENTS_TO_LOG; mMostRecentEventIndex = index; if (mRecentEvents[index] != null) { mRecentEvents[index].recycle(); } mRecentEvents[index] = mCurrentEvent.copy(); mRecentEventsUnhandled[index] = false; } mCurrentEvent = null; mCurrentEventType = null; }
/// <summary>Resets the state of the input event consistency verifier.</summary> /// <remarks>Resets the state of the input event consistency verifier.</remarks> public void reset() { mLastEvent = null; mLastNestingLevel = 0; mTrackballDown = false; mTrackballUnhandled = false; mTouchEventStreamPointers = 0; mTouchEventStreamIsTainted = false; mTouchEventStreamUnhandled = false; mHoverEntered = false; while (mKeyStateList != null) { android.view.InputEventConsistencyVerifier.KeyState state = mKeyStateList; mKeyStateList = state.next; state.recycle(); } }
/// <summary> /// Notifies the verifier that a given event was unhandled and the rest of the /// trace for the event should be ignored. /// </summary> /// <remarks> /// Notifies the verifier that a given event was unhandled and the rest of the /// trace for the event should be ignored. /// This method should only be called if the event was previously checked by /// the consistency verifier using /// <see cref="onInputEvent(InputEvent, int)">onInputEvent(InputEvent, int)</see> /// and other methods. /// </remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onUnhandledEvent(android.view.InputEvent @event, int nestingLevel) { if (nestingLevel != mLastNestingLevel) { return; } if (mRecentEventsUnhandled != null) { mRecentEventsUnhandled[mMostRecentEventIndex] = true; } if (@event is android.view.KeyEvent) { android.view.KeyEvent keyEvent = (android.view.KeyEvent)@event; int deviceId = keyEvent.getDeviceId(); int source = keyEvent.getSource(); int keyCode = keyEvent.getKeyCode(); android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, false); if (state != null) { state.unhandled = true; } } else { android.view.MotionEvent motionEvent = (android.view.MotionEvent)@event; if (motionEvent.isTouchEvent()) { mTouchEventStreamUnhandled = true; } else { if ((motionEvent.getSource() & android.view.InputDevice.SOURCE_CLASS_TRACKBALL) != 0) { if (mTrackballDown) { mTrackballUnhandled = true; } } } } }
private bool startEvent(android.view.InputEvent @event, int nestingLevel, string eventType) { // Ignore the event if we already checked it at a higher nesting level. if (@event == mLastEvent && nestingLevel < mLastNestingLevel && eventType == mLastEventType) { return(false); } if (nestingLevel > 0) { mLastEvent = @event; mLastEventType = eventType; mLastNestingLevel = nestingLevel; } else { mLastEvent = null; mLastEventType = null; mLastNestingLevel = 0; } mCurrentEvent = @event; mCurrentEventType = eventType; return(true); }
private bool startEvent(android.view.InputEvent @event, int nestingLevel, string eventType) { // Ignore the event if we already checked it at a higher nesting level. if (@event == mLastEvent && nestingLevel < mLastNestingLevel && eventType == mLastEventType) { return false; } if (nestingLevel > 0) { mLastEvent = @event; mLastEventType = eventType; mLastNestingLevel = nestingLevel; } else { mLastEvent = null; mLastEventType = null; mLastNestingLevel = 0; } mCurrentEvent = @event; mCurrentEventType = eventType; return true; }