Example usage for android.view.accessibility AccessibilityEvent getEventTime

List of usage examples for android.view.accessibility AccessibilityEvent getEventTime

Introduction

In this page you can find the example usage for android.view.accessibility AccessibilityEvent getEventTime.

Prototype

public long getEventTime() 

Source Link

Document

Gets the time in which this event was sent.

Usage

From source file:com.android.screenspeak.eventprocessor.ProcessorEventQueue.java

/**
 * Computes the queuing mode for the current utterance.
 *
 * @param utterance to compute queuing from
 * @return A queuing mode, one of:/*from  w  w w . j  a v a  2  s . c o  m*/
 *         <ul>
 *         <li>{@link SpeechController#QUEUE_MODE_INTERRUPT}
 *         <li>{@link SpeechController#QUEUE_MODE_QUEUE}
 *         <li>{@link SpeechController#QUEUE_MODE_UNINTERRUPTIBLE}
 *         </ul>
 */
private int computeQueuingMode(Utterance utterance, AccessibilityEvent event) {
    final Bundle metadata = utterance.getMetadata();
    final int eventType = event.getEventType();

    // Queue events that occur automatically after window state changes.
    if (((event.getEventType() & AccessibilityEventProcessor.AUTOMATIC_AFTER_STATE_CHANGE) != 0)
            && ((event.getEventTime()
                    - mLastWindowStateChanged) < AccessibilityEventProcessor.DELAY_AUTO_AFTER_STATE)) {
        return SpeechController.QUEUE_MODE_QUEUE;
    }

    if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
        AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
        AccessibilityNodeInfoCompat node = record.getSource();
        if (node != null) {
            int liveRegionMode = node.getLiveRegion();
            if (liveRegionMode == View.ACCESSIBILITY_LIVE_REGION_POLITE) {
                return SpeechController.QUEUE_MODE_QUEUE;
            }
        }
    }

    int queueMode = metadata.getInt(Utterance.KEY_METADATA_QUEUING, SpeechController.QUEUE_MODE_INTERRUPT);

    // Always collapse events of the same type.
    if (mLastEventType == eventType && queueMode != SpeechController.QUEUE_MODE_UNINTERRUPTIBLE) {
        return SpeechController.QUEUE_MODE_INTERRUPT;
    }

    mLastEventType = eventType;

    return queueMode;
}

From source file:com.android.talkback.eventprocessor.AccessibilityEventProcessor.java

/**
 * Helper method for {@link #shouldDropEvent} that filters out selected events that occur
 * in close proximity to focused events.
 *
 * A selected event should be kept if:/*from  w ww  . ja va2  s.  co  m*/
 * - The most recent focused event occurred over {@link #DELAY_SELECTED_AFTER_FOCUS} ms ago.
 * - The most recent focused event occurred on a different branch of the accessibility node
 *   tree, i.e., not in an ancestor or descendant of the selected event.
 *
 * @param event The view-selected event to consider retaining.
 * @return Whether to retain the event.
 */
private boolean shouldKeepViewSelectedEvent(final AccessibilityEvent event) {
    if (mLastFocusedEvent == null) {
        return true;
    }

    if (event.getEventTime() - mLastFocusedEvent.getEventTime() > DELAY_SELECTED_AFTER_FOCUS) {
        return true;
    }

    // AccessibilityEvent.getSource will obtain() an AccessibilityNodeInfo, so it is our
    // responsibility to recycle() it.
    AccessibilityNodeInfo selectedSource = event.getSource();
    AccessibilityNodeInfo focusedSource = mLastFocusedEvent.getSource();

    try {
        // Note: AccessibilityNodeInfoCompat constructor will silently succeed when wrapping
        // a null object.
        if (selectedSource != null && focusedSource != null) {
            AccessibilityNodeInfoCompat selectedSourceCompat = new AccessibilityNodeInfoCompat(selectedSource);
            AccessibilityNodeInfoCompat focusedSourceCompat = new AccessibilityNodeInfoCompat(focusedSource);

            if (AccessibilityNodeInfoUtils.areInSameBranch(selectedSourceCompat, focusedSourceCompat)) {
                return false;
            }
        }

        // In different branch (or we could not check branches of accessibility node tree).
        return true;
    } finally {
        if (selectedSource != null) {
            selectedSource.recycle();
        }
        if (focusedSource != null) {
            focusedSource.recycle();
        }
    }
}

From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java

private void handleWindowStateChange(AccessibilityEvent event) {
    mLastWindowStateChangedEvent = event.getEventTime();

    // Invalidate scrolling information.
    if (mLastScrollSource != null) {
        mLastScrollSource.recycle();/*w ww.  java 2  s  . co  m*/
        mLastScrollSource = null;
    }
    mLastScrollAction = 0;
    mLastScrollFromIndex = -1;
    mLastScrollToIndex = -1;

    // Since we may get WINDOW_STATE_CHANGE events from the keyboard even
    // though the active window is still another app, only clear focus if
    // the event's window ID matches the cursor's window ID.
    final AccessibilityNodeInfoCompat cursor = mCursorController.getCursor();
    if ((cursor != null) && (cursor.getWindowId() == event.getWindowId())) {
        mCursorController.clearCursor();
    }

    AccessibilityNodeInfoUtils.recycleNodes(cursor);
}

From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java

private boolean shouldDropFocusEvent(AccessibilityEvent event, AccessibilityNodeInfoCompat node) {
    final long eventTime = event.getEventTime();

    return ((eventTime - mLastViewScrolledEvent) < TIMEOUT_VIEW_SCROLLED)
            || ((eventTime - mLastWindowStateChangedEvent) < TIMEOUT_WINDOW_STATE_CHANGED);
}

From source file:com.google.android.marvin.mytalkback.ProcessorFocusAndSingleTap.java

private void handleViewScrolled(AccessibilityEvent event, AccessibilityRecordCompat record) {
    mLastViewScrolledEvent = event.getEventTime();

    final AccessibilityNodeInfoCompat source = record.getSource();
    if (source == null) {
        LogUtils.log(this, Log.ERROR, "Drop scroll with no source node");
        return;//from  w  w w.  jav a  2 s  .  c  om
    }

    // Only move focus if we've already seen the source.
    if (source.equals(mLastScrollSource)) {
        final boolean isMovingForward = (mLastScrollAction == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)
                || (event.getFromIndex() > mLastScrollFromIndex) || (event.getToIndex() > mLastScrollToIndex);
        final boolean wasScrollAction = (mLastScrollAction != 0);
        mHandler.followScrollDelayed(source, isMovingForward, wasScrollAction);

        // Performing a scroll action results in smooth scrolling, which may
        // send multiple events spaced at least 100ms apart.
        mHandler.clearScrollActionDelayed();
    } else {
        setScrollActionImmediately(0);
    }

    if (mLastScrollSource != null) {
        mLastScrollSource.recycle();
    }

    mLastScrollSource = source;
    mLastScrollFromIndex = record.getFromIndex();
    mLastScrollToIndex = record.getToIndex();
}

From source file:com.android.talkback.eventprocessor.ProcessorFocusAndSingleTap.java

public boolean isFromRefocusAction(AccessibilityEvent event) {
    long eventTime = event.getEventTime();
    int eventType = event.getEventType();
    if (eventType != AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
            && eventType != AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED) {
        return false;
    }//from w ww.j a  va2 s. c  om
    AccessibilityNodeInfo source = event.getSource();
    try {
        return mLastRefocusStartTime < eventTime
                && (mLastRefocusEndTime > eventTime || mLastRefocusEndTime < mLastRefocusStartTime)
                && mLastRefocusedNode != null && mLastRefocusedNode.getInfo().equals(source);
    } finally {
        if (source != null) {
            source.recycle();
        }
    }
}

From source file:com.android.screenspeak.eventprocessor.AccessibilityEventProcessor.java

/**
 * Returns whether the device should drop this event. Caches notifications
 * if necessary.//from   w  w  w  .j  av a  2 s . c o  m
 *
 * @param event The current event.
 * @return {@code true} if the event should be dropped.
 */
private boolean shouldDropEvent(AccessibilityEvent event) {
    // Always drop null events.
    if (event == null) {
        return true;
    }

    // Always drop events if the service is suspended.
    if (!ScreenSpeakService.isServiceActive()) {
        return true;
    }

    // If touch exploration is enabled, drop automatically generated events
    // that are sent immediately after a window state change... unless we
    // decide to keep the event.
    if (AccessibilityManagerCompat.isTouchExplorationEnabled(mAccessibilityManager)
            && ((event.getEventType() & AUTOMATIC_AFTER_STATE_CHANGE) != 0)
            && ((event.getEventTime() - mLastWindowStateChanged) < DELAY_AUTO_AFTER_STATE)
            && !shouldKeepAutomaticEvent(event)) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop event after window state change");
        }
        return true;
    }

    // Real notification events always have parcelable data.
    final boolean isNotification = (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
            && (event.getParcelableData() != null);

    final boolean isPhoneActive = (mCallStateMonitor != null)
            && (mCallStateMonitor.getCurrentCallState() != TelephonyManager.CALL_STATE_IDLE);
    final boolean shouldSpeakCallerId = (mSpeakCallerId && (mCallStateMonitor != null)
            && (mCallStateMonitor.getCurrentCallState() == TelephonyManager.CALL_STATE_RINGING));

    if (mRingerModeAndScreenMonitor != null && !mRingerModeAndScreenMonitor.isScreenOn()
            && !shouldSpeakCallerId) {
        if (!mSpeakWhenScreenOff) {
            // If the user doesn't allow speech when the screen is
            // off, drop the event immediately.
            if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
                Log.v(LOGTAG, "Drop event due to screen state and user pref");
            }
            return true;
        } else if (!isNotification) {
            // If the user allows speech when the screen is off, drop
            // all non-notification events.
            if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
                Log.v(LOGTAG, "Drop non-notification event due to screen state");
            }
            return true;
        }
    }

    final boolean canInterruptRadialMenu = AccessibilityEventUtils.eventMatchesAnyType(event,
            MASK_EVENT_TYPES_INTERRUPT_RADIAL_MENU);
    final boolean silencedByRadialMenu = (mService.getMenuManager().isMenuShowing() && !canInterruptRadialMenu);

    // Don't speak events that cannot interrupt the radial menu, if showing
    if (silencedByRadialMenu) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop event due to radial menu state");
        }
        return true;
    }

    // Don't speak notification events if the user is touch exploring or a phone call is active.
    if (isNotification && (mIsUserTouchExploring || isPhoneActive)) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop notification due to touch or phone state");
        }
        return true;
    }

    final int touchscreenState = mService.getResources().getConfiguration().touchscreen;
    final boolean isTouchInteractionStateChange = AccessibilityEventUtils.eventMatchesAnyType(event,
            MASK_EVENT_TYPES_TOUCH_STATE_CHANGES);

    // Drop all events related to touch interaction state on devices that don't support touch.
    return (touchscreenState == Configuration.TOUCHSCREEN_NOTOUCH) && isTouchInteractionStateChange;
}

From source file:com.ucmap.dingdinghelper.services.DingDingHelperAccessibilityService.java

/**
 * ???//from  www . j a v  a 2s  .  c o  m
 */
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    tag_callback_time = System.currentTimeMillis();
    int eventType = event.getEventType();

    Log.i("Info",
            " eventType: " + eventType + "   getEventTime:  " + event.getEventTime() + "     getAction"
                    + event.getAction() + "getContentChangeTypes:" + event.getContentChangeTypes()
                    + " getText :" + event.getText().toString() + "getPackageName :" + event.getPackageName()
                    + "getRecordCount : " + event.getRecordCount() + "  getClassName:" + event.getClassName()
                    + "  :" + event.getClass() + "   getParcelableData:" + event.getParcelableData());

    switch (eventType) {
    /*??*/
    case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
        windowContentChanged();
        break;
    //???
    case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
        notificationChanged(event);
        break;
    //Activity???
    case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
        windowChanged(event);
        break;
    }
}

From source file:com.android.talkback.eventprocessor.AccessibilityEventProcessor.java

/**
 * Returns whether the device should drop this event. Caches notifications
 * if necessary.// w w w .  j av  a 2 s .c om
 *
 * @param event The current event.
 * @return {@code true} if the event should be dropped.
 */
private boolean shouldDropEvent(AccessibilityEvent event) {
    // Always drop null events.
    if (event == null) {
        return true;
    }

    // Always drop events if the service is suspended.
    if (!TalkBackService.isServiceActive()) {
        return true;
    }

    // If touch exploration is enabled, drop automatically generated events
    // that are sent immediately after a window state change... unless we
    // decide to keep the event.
    if (AccessibilityManagerCompat.isTouchExplorationEnabled(mAccessibilityManager)
            && ((event.getEventType() & AUTOMATIC_AFTER_STATE_CHANGE) != 0)
            && ((event.getEventTime() - mLastWindowStateChanged) < DELAY_AUTO_AFTER_STATE)
            && !shouldKeepAutomaticEvent(event)) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop event after window state change");
        }
        return true;
    }

    // Some view-selected events are spurious if sent immediately after a focused event.
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SELECTED && !shouldKeepViewSelectedEvent(event)) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop selected event after focused event");
        }
        return true;
    }

    // Real notification events always have parcelable data.
    final boolean isNotification = (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
            && (event.getParcelableData() != null);

    final boolean isPhoneActive = (mCallStateMonitor != null)
            && (mCallStateMonitor.getCurrentCallState() != TelephonyManager.CALL_STATE_IDLE);
    final boolean isPhoneRinging = (mCallStateMonitor != null)
            && (mCallStateMonitor.getCurrentCallState() == TelephonyManager.CALL_STATE_RINGING);

    // Sometimes the dialer's window-state-changed event gets sent right before the
    // TelephonyManager transitions to CALL_STATE_RINGING, so we need to check isDialerEvent().
    final boolean shouldSpeakCallerId = isPhoneRinging || isDialerEvent(event);

    if (mRingerModeAndScreenMonitor != null && !mRingerModeAndScreenMonitor.isScreenOn()
            && !shouldSpeakCallerId) {
        if (!mSpeakWhenScreenOff) {
            // If the user doesn't allow speech when the screen is
            // off, drop the event immediately.
            if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
                Log.v(LOGTAG, "Drop event due to screen state and user pref");
            }
            return true;
        } else if (!isNotification) {
            // If the user allows speech when the screen is off, drop
            // all non-notification events.
            if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
                Log.v(LOGTAG, "Drop non-notification event due to screen state");
            }
            return true;
        }
    }

    final boolean canInterruptRadialMenu = AccessibilityEventUtils.eventMatchesAnyType(event,
            MASK_EVENT_TYPES_INTERRUPT_RADIAL_MENU);
    final boolean silencedByRadialMenu = (mService.getMenuManager().isMenuShowing() && !canInterruptRadialMenu);

    // Don't speak events that cannot interrupt the radial menu, if showing
    if (silencedByRadialMenu) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop event due to radial menu state");
        }
        return true;
    }

    // Don't speak notification events if the user is touch exploring or a phone call is active.
    if (isNotification && (mIsUserTouchExploring || isPhoneActive)) {
        if (LogUtils.LOG_LEVEL <= Log.VERBOSE) {
            Log.v(LOGTAG, "Drop notification due to touch or phone state");
        }
        return true;
    }

    final int touchscreenState = mService.getResources().getConfiguration().touchscreen;
    final boolean isTouchInteractionStateChange = AccessibilityEventUtils.eventMatchesAnyType(event,
            MASK_EVENT_TYPES_TOUCH_STATE_CHANGES);

    // Drop all events related to touch interaction state on devices that don't support touch.
    return (touchscreenState == Configuration.TOUCHSCREEN_NOTOUCH) && isTouchInteractionStateChange;
}

From source file:Main.java

/**
 * @return If the <code>first</code> event is equal to the <code>second</code>.
 *///from w w w  .j  a  v  a  2  s  .  co m
public static boolean eventEquals(AccessibilityEvent first, AccessibilityEvent second) {
    // TODO: The framework should implement AccessibilityEvent#equals()
    if (first == null || second == null) {
        return false;
    }
    if (first.getEventType() != second.getEventType()) {
        return false;
    }
    if (first.getPackageName() == null) {
        if (second.getPackageName() != null) {
            return false;
        }
    } else if (!first.getPackageName().equals(second.getPackageName())) {
        return false;
    }
    if (first.getClassName() == null) {
        if (second.getClassName() != null) {
            return false;
        }
    } else if (!first.getClassName().equals(second.getClassName())) {
        return false;
    }
    if (!first.getText().equals(second.getText())) {
        // The result of getText() is never null.
        return false;
    }
    if (first.getContentDescription() == null) {
        if (second.getContentDescription() != null) {
            return false;
        }
    } else if (!first.getContentDescription().equals(second.getContentDescription())) {
        return false;
    }
    if (first.getBeforeText() == null) {
        if (second.getBeforeText() != null) {
            return false;
        }
    } else if (!first.getBeforeText().equals(second.getBeforeText())) {
        return false;
    }
    if (first.getParcelableData() != null) {
        // Parcelable data may not implement equals() correctly.
        return false;
    }
    if (first.getAddedCount() != second.getAddedCount()) {
        return false;
    }
    if (first.isChecked() != second.isChecked()) {
        return false;
    }
    if (first.isEnabled() != second.isEnabled()) {
        return false;
    }
    if (first.getFromIndex() != second.getFromIndex()) {
        return false;
    }
    if (first.isFullScreen() != second.isFullScreen()) {
        return false;
    }
    if (first.getCurrentItemIndex() != second.getCurrentItemIndex()) {
        return false;
    }
    if (first.getItemCount() != second.getItemCount()) {
        return false;
    }
    if (first.isPassword() != second.isPassword()) {
        return false;
    }
    if (first.getRemovedCount() != second.getRemovedCount()) {
        return false;
    }
    if (first.getEventTime() != second.getEventTime()) {
        return false;
    }
    return true;
}