/// <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; } } } } }
/// <summary>Checks a key event.</summary> /// <remarks>Checks a key 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 onKeyEvent(android.view.KeyEvent @event, int nestingLevel) { if (!startEvent(@event, nestingLevel, EVENT_TYPE_KEY)) { return; } try { ensureMetaStateIsNormalized(@event.getMetaState()); int action = @event.getAction(); int deviceId = @event.getDeviceId(); int source = @event.getSource(); int keyCode = @event.getKeyCode(); switch (action) { case android.view.KeyEvent.ACTION_DOWN: { android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, false); if (state != null) { // If the key is already down, ensure it is a repeat. // We don't perform this check when processing raw device input // because the input dispatcher itself is responsible for setting // the key repeat count before it delivers input events. if (state.unhandled) { state.unhandled = false; } else { if ((mFlags & FLAG_RAW_DEVICE_INPUT) == 0 && @event.getRepeatCount() == 0) { problem("ACTION_DOWN but key is already down and this event " + "is not a key repeat." ); } } } else { addKeyState(deviceId, source, keyCode); } break; } case android.view.KeyEvent.ACTION_UP: { android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, true); if (state == null) { problem("ACTION_UP but key was not down."); } else { state.recycle(); } break; } case android.view.KeyEvent.ACTION_MULTIPLE: { break; } default: { problem("Invalid action " + android.view.KeyEvent.actionToString(action) + " for key event." ); break; } } } finally { finishEvent(); } }