Example usage for android.view.accessibility AccessibilityEvent getEventType

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

Introduction

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

Prototype

public @EventType int getEventType() 

Source Link

Document

Gets the event type.

Usage

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

private void updateWindowTitlesMap(AccessibilityEvent event) {
    switch (event.getEventType()) {
    case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
        // If split screen mode is NOT available, we only need to care single window.
        if (!mIsSplitScreenModeAvailable) {
            mWindowTitlesMap.clear();/*from   w w w. j a va 2  s .c om*/
        }

        int windowId = getWindowId(event);
        boolean shouldAnnounceEvent = shouldAnnounceEvent(event, windowId);
        CharSequence title = getWindowTitleFromEvent(event, shouldAnnounceEvent /* useContentDescription */);
        if (title != null) {
            if (shouldAnnounceEvent) {
                // When software keyboard is shown or hidden, TYPE_WINDOW_STATE_CHANGED
                // is dispatched with text describing the visibility of the keyboard.
                speakWithFeedback(title);
            } else {
                mWindowTitlesMap.put(windowId, title);

                if (getWindowType(event) == AccessibilityWindowInfo.TYPE_SYSTEM) {
                    mSystemWindowIdsSet.add(windowId);
                }

                CharSequence eventWindowClassName = event.getClassName();
                mWindowToClassName.put(windowId, eventWindowClassName);
                mWindowToPackageName.put(windowId, event.getPackageName());
            }
        }
    }
        break;
    case AccessibilityEvent.TYPE_WINDOWS_CHANGED: {
        HashSet<Integer> windowIdsToBeRemoved = new HashSet<Integer>(mWindowTitlesMap.keySet());
        List<AccessibilityWindowInfo> windows = mService.getWindows();
        for (AccessibilityWindowInfo window : windows) {
            windowIdsToBeRemoved.remove(window.getId());
        }
        for (Integer windowId : windowIdsToBeRemoved) {
            mWindowTitlesMap.remove(windowId);
            mSystemWindowIdsSet.remove(windowId);
            mWindowToClassName.remove(windowId);
            mWindowToPackageName.remove(windowId);
        }
    }
        break;
    }
}

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

/**
 * Helper method for {@link #shouldDropEvent} to determine whether an event is the phone dialer
 * appearing for an incoming call./* w w  w .  j  a  va2  s. co  m*/
 *
 * @param event The event to check.
 * @return Whether the event represents an incoming call on the phone dialer.
 */
private boolean isDialerEvent(final AccessibilityEvent event) {
    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT
                && CLASS_DIALER_JELLY_BEAN.equals(event.getClassName())) {
            return true;
        } else if (CLASS_DIALER_KITKAT.equals(event.getClassName())) {
            return true;
        }
    }

    return false;
}

From source file:com.android.talkback.formatter.TouchExplorationFormatter.java

/**
 * Formatter that returns an utterance to announce touch exploration.
 *///from www. ja v  a 2  s  .co  m
@Override
public boolean format(AccessibilityEvent event, TalkBackService context, Utterance utterance) {
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED && EventState.getInstance()
            .checkAndClearRecentEvent(EventState.EVENT_SKIP_FOCUS_PROCESSING_AFTER_GRANULARITY_MOVE)) {
        return false;
    }
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED && EventState.getInstance()
            .checkAndClearRecentEvent(EventState.EVENT_SKIP_FOCUS_PROCESSING_AFTER_CURSOR_CONTROL)) {
        return false;
    }

    final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
    final AccessibilityNodeInfoCompat sourceNode = record.getSource();
    final AccessibilityNodeInfoCompat focusedNode = getFocusedNode(event.getEventType(), sourceNode);

    // Drop the event if the source node was non-null, but the focus
    // algorithm decided to drop the event by returning null.
    if ((sourceNode != null) && (focusedNode == null)) {
        AccessibilityNodeInfoUtils.recycleNodes(sourceNode);
        return false;
    }

    LogUtils.log(this, Log.VERBOSE, "Announcing node: %s", focusedNode);

    // Transition the collection state if necessary.
    mCollectionState.updateCollectionInformation(focusedNode, event);

    // Populate the utterance.
    addEarconWhenAccessibilityFocusMovesToTheDivider(utterance, focusedNode);
    addSpeechFeedback(utterance, focusedNode, event, sourceNode);
    addAuditoryHapticFeedback(utterance, focusedNode);

    // By default, touch exploration flushes all other events.
    utterance.getMetadata().putInt(Utterance.KEY_METADATA_QUEUING, DEFAULT_QUEUING_MODE);

    // Events formatted by this class should always advance continuous
    // reading, if active.
    utterance.addSpokenFlag(FeedbackItem.FLAG_ADVANCE_CONTINUOUS_READING);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        mLastFocusedWindowId = focusedNode.getWindowId();
    }

    AccessibilityNodeInfoUtils.recycleNodes(sourceNode, focusedNode);

    return true;
}

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

private void updateScreenState(AccessibilityEvent event) {
    switch (event.getEventType()) {
    case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
        // Do nothing if split screen mode is available since it can be covered by
        // TYPE_WINDOWS_CHANGED events.
        if (mIsSplitScreenModeAvailable) {
            return;
        }//ww  w . java 2 s.  c  o  m

        mWindowIdA = getWindowId(event);
        break;
    case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
        // Do nothing if split screen mode is NOT available since it can be covered by
        // TYPE_WINDOW_STATE_CHANGED events.
        if (!mIsSplitScreenModeAvailable) {
            return;
        }

        ArrayList<AccessibilityWindowInfo> applicationWindows = new ArrayList<>();
        ArrayList<AccessibilityWindowInfo> systemWindows = new ArrayList<>();
        ArrayList<AccessibilityWindowInfo> accessibilityOverlayWindows = new ArrayList<>();
        List<AccessibilityWindowInfo> windows = mService.getWindows();

        // If there are no windows available, clear the cached IDs.
        if (windows.isEmpty()) {
            mAccessibilityOverlayWindowId = WINDOW_ID_NONE;
            mWindowIdA = WINDOW_ID_NONE;
            mWindowIdB = WINDOW_ID_NONE;
            return;
        }

        for (int i = 0; i < windows.size(); i++) {
            AccessibilityWindowInfo window = windows.get(i);
            switch (window.getType()) {
            case AccessibilityWindowInfo.TYPE_APPLICATION:
                if (window.getParent() == null) {
                    applicationWindows.add(window);
                }
                break;
            case AccessibilityWindowInfo.TYPE_SYSTEM:
                systemWindows.add(window);
                break;
            case AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY:
                accessibilityOverlayWindows.add(window);
                break;
            }
        }

        if (accessibilityOverlayWindows.size() == windows.size()) {
            // TODO: investigate whether there is a case where we have more than one
            // accessibility overlay, and add a logic for it if there is.
            mAccessibilityOverlayWindowId = accessibilityOverlayWindows.get(0).getId();
            return;
        }

        mAccessibilityOverlayWindowId = WINDOW_ID_NONE;

        if (applicationWindows.size() == 0) {
            mWindowIdA = WINDOW_ID_NONE;
            mWindowIdB = WINDOW_ID_NONE;

            // If there is no application window but a system window, consider it as a
            // current window. This logic handles notification shade and lock screen.
            if (systemWindows.size() > 0) {
                Collections.sort(systemWindows,
                        new WindowManager.WindowPositionComparator(mService.isScreenLayoutRTL()));

                mWindowIdA = systemWindows.get(0).getId();
            }
        } else if (applicationWindows.size() == 1) {
            mWindowIdA = applicationWindows.get(0).getId();
            mWindowIdB = WINDOW_ID_NONE;
        } else if (applicationWindows.size() == 2) {
            Collections.sort(applicationWindows,
                    new WindowManager.WindowPositionComparator(mService.isScreenLayoutRTL()));

            mWindowIdA = applicationWindows.get(0).getId();
            mWindowIdB = applicationWindows.get(1).getId();
        } else {
            // If there are more than 2 windows, report the active window as the current
            // window.
            for (AccessibilityWindowInfo applicationWindow : applicationWindows) {
                if (applicationWindow.isActive()) {
                    mWindowIdA = applicationWindow.getId();
                    mWindowIdB = WINDOW_ID_NONE;
                    return;
                }
            }
        }
        break;
    }
}

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

/**
 * Returns whether the device should drop this event due to refocus issue.
 * Sometimes TalkBack will receive four consecutive events from one single node:.
 * 1. Accessibility_Focus_Cleared/*  ww  w  . j a  va  2 s .co m*/
 * 2. Accessibility_Focused
 * 3. Accessibility_Focus_Cleared
 * 4. Accessibility_Focused
 * <p/>
 * The cause of this issue could be:
 * i. Chrome clears and set a11y focus for each scroll event.
 * If it is an action to navigate to previous/next element and causes view scrolling. The
 * first two events are caused by navigation, and the last two events are caused by chrome
 * refocus issue. The last two events are not intended to be spoken.
 * If it is a scroll action. It might cause a lot of a11y_focus_cleared and a11y_focused
 * events. In this case all the events are not intended to be spoken.
 * <p/>
 * ii. User taps on screen to refocus on the a11y focused node. In this case event 2 and 4
 * should be spoken to the user.
 *
 * @param event The current event.
 * @return {@code true} if the event should be dropped.
 */
private boolean shouldDropRefocusEvent(AccessibilityEvent event) {
    int eventType = event.getEventType();
    if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED) {
        if (sGetSourceNodeIdMethod != null) {
            try {
                mLastClearedSourceId = (long) sGetSourceNodeIdMethod.invoke(event);
                mLastClearedWindowId = event.getWindowId();
                mLastClearA11yFocus = System.currentTimeMillis();
                if (mLastClearedSourceId != mLastPronouncedSourceId
                        || mLastClearedWindowId != mLastPronouncedWindowId
                        || mProcessorFocusAndSingleTap.isFromRefocusAction(event)) {
                    // something strange. not accessibility focused node sends clear focus event
                    // BUG
                    mLastClearedSourceId = -1;
                    mLastClearedWindowId = -1;
                    mLastClearA11yFocus = 0;
                }
            } catch (Exception e) {
                Log.d(LOGTAG, "Exception accessing field: " + e.toString());
            }
        }
        return true;
    }

    if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
        if (sGetSourceNodeIdMethod != null
                && !EventState.getInstance().checkAndClearRecentEvent(EventState.EVENT_NODE_REFOCUSED)) {
            try {
                long sourceId = (long) sGetSourceNodeIdMethod.invoke(event);
                int windowId = event.getWindowId();
                // If this event is fired by the "clear and set a11y focus" issue of Chrome,
                // ignore and don't speak to the user, otherwise update the node and window IDs
                // and then process the event.
                if (System.currentTimeMillis() - mLastClearA11yFocus < CLEAR_SET_A11Y_FOCUS_WINDOW
                        && sourceId == mLastClearedSourceId && windowId == mLastClearedWindowId) {
                    return true;
                } else {
                    mLastPronouncedSourceId = sourceId;
                    mLastPronouncedWindowId = windowId;
                }
            } catch (Exception e) {
                Log.d(LOGTAG, "Exception accessing field: " + e.toString());
            }
        }
    }
    return false;
}

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

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    int eventType = event.getEventType();
    if (eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
            && eventType != AccessibilityEvent.TYPE_WINDOWS_CHANGED) {
        return;/*w  w  w  .  j  ava  2 s  .co m*/
    }

    int windowIdABefore = mWindowIdA;
    CharSequence windowTitleABefore = getWindowTitle(mWindowIdA);
    int windowIdBBefore = mWindowIdB;
    CharSequence windowTitleBBefore = getWindowTitle(mWindowIdB);
    int accessibilityOverlayWindowIdBefore = mAccessibilityOverlayWindowId;
    CharSequence accessibilityOverlayWindowTitleBefore = getWindowTitle(mAccessibilityOverlayWindowId);

    updateWindowTitlesMap(event);
    updateScreenState(event);

    // If there is no screen update, do not provide spoken feedback.
    if (windowIdABefore == mWindowIdA && TextUtils.equals(windowTitleABefore, getWindowTitle(mWindowIdA))
            && windowIdBBefore == mWindowIdB && TextUtils.equals(windowTitleBBefore, getWindowTitle(mWindowIdB))
            && accessibilityOverlayWindowIdBefore == mAccessibilityOverlayWindowId && TextUtils.equals(
                    accessibilityOverlayWindowTitleBefore, getWindowTitle(mAccessibilityOverlayWindowId))) {
        return;
    }

    // If the user performs a cursor control(copy, paste, start selection mode, etc) in the
    // local context menu and lands back to the edit text, a TYPE_WINDOWS_CHANGED and a
    // TYPE_WINDOW_STATE_CHANGED events will be fired. We should skip these two events to
    // avoid announcing the window title.
    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED && EventState.getInstance()
            .checkAndClearRecentEvent(EventState.EVENT_SKIP_WINDOWS_CHANGED_PROCESSING_AFTER_CURSOR_CONTROL)) {
        return;
    }
    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
            && EventState.getInstance().checkAndClearRecentEvent(
                    EventState.EVENT_SKIP_WINDOW_STATE_CHANGED_PROCESSING_AFTER_CURSOR_CONTROL)) {
        return;
    }

    // Generate spoken feedback.
    CharSequence utterance;
    boolean isUiStabilized;
    if (mAccessibilityOverlayWindowId != WINDOW_ID_NONE) {
        // Case where accessibility overlay is shown. Use separated logic for accessibility
        // overlay not to say out of split screen mode, e.g. accessibility overlay is shown when
        // user is in split screen mode.
        utterance = getWindowTitleForFeedback(mAccessibilityOverlayWindowId);
        isUiStabilized = true;
    } else if (mWindowIdB == WINDOW_ID_NONE) {
        // Single window mode.
        CharSequence windowTitleA = getWindowTitle(mWindowIdA);
        if (windowTitleA == null) {
            // In single window mode, do not provide feedback if window title is not set.
            return;
        }

        utterance = getWindowTitleForFeedback(mWindowIdA);

        if (IS_IN_ARC) {
            // If windowIdABefore was WINDOW_ID_NONE, we consider it as the focus comes into Arc
            // window.
            utterance = formatAnnouncementForArc(utterance,
                    windowIdABefore == WINDOW_ID_NONE /* focusIntoArc */);
        }

        // Consider UI is stabilized if it's alert dialog to provide faster feedback.
        isUiStabilized = !mIsSplitScreenModeAvailable || isAlertDialog(mWindowIdA);
    } else {
        // Split screen mode.
        int feedbackTemplate;
        if (mService.isScreenOrientationLandscape()) {
            if (mService.isScreenLayoutRTL()) {
                feedbackTemplate = R.string.template_split_screen_mode_landscape_rtl;
            } else {
                feedbackTemplate = R.string.template_split_screen_mode_landscape_ltr;
            }
        } else {
            feedbackTemplate = R.string.template_split_screen_mode_portrait;
        }

        utterance = mService.getString(feedbackTemplate, getWindowTitleForFeedback(mWindowIdA),
                getWindowTitleForFeedback(mWindowIdB));
        isUiStabilized = !mIsSplitScreenModeAvailable || isAlertDialog(mWindowIdA) || isAlertDialog(mWindowIdB);
    }

    // Speak.
    if (!isUiStabilized) {
        // If UI is not stabilized, wait SCREEN_FEEDBACK_DELAY for next accessibility event.
        speakLater(utterance, SCREEN_FEEDBACK_DELAY);
    } else {
        speak(utterance);
    }
}

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

public void onAccessibilityEvent(AccessibilityEvent event) {
    if (mTestingListener != null) {
        mTestingListener.onAccessibilityEvent(event);
    }/*from  w  w  w . j  a v a 2 s .co  m*/

    // Chrome clears and set a11y focus for each scroll event, it is not intended to be spoken
    // to the user. Remove this when chromium is fixed.
    int eventType = event.getEventType();
    if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED) {
        if (sGetSourceNodeIdMethod != null) {
            try {
                mLastClearedSourceId = (long) sGetSourceNodeIdMethod.invoke(event);
                mLastClearedWindowId = event.getWindowId();
                mLastClearA11yFocus = System.currentTimeMillis();
                if (mLastClearedSourceId != mLastPronouncedSourceId
                        || mLastClearedWindowId != mLastPronouncedWindowId) {
                    // something strange. not accessibility focused node sends clear focus event
                    // b/22108305
                    mLastClearedSourceId = -1;
                    mLastClearedWindowId = -1;
                    mLastClearA11yFocus = 0;
                }
            } catch (Exception e) {
                Log.d(LOGTAG, "Exception accessing field: " + e.toString());
            }
        }

        return;
    }

    if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
        if (System.currentTimeMillis() - mLastClearA11yFocus < CLEAR_SET_A11Y_FOCUS_WINDOW) {
            if (sGetSourceNodeIdMethod != null) {
                try {
                    long sourceId = (long) sGetSourceNodeIdMethod.invoke(event);
                    int windowId = event.getWindowId();
                    if (sourceId == mLastClearedSourceId && windowId == mLastClearedWindowId) {
                        return;
                    }
                    mLastPronouncedSourceId = sourceId;
                    mLastPronouncedWindowId = windowId;
                } catch (Exception e) {
                    Log.d(LOGTAG, "Exception accessing field: " + e.toString());
                }
            }
        }
    }

    if (shouldDropEvent(event)) {
        return;
    }

    maintainExplorationState(event);

    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
            || event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
            || event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED) {
        mService.setRootDirty(true);
    }

    processEvent(event);
}

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

/**
 * Given an {@link AccessibilityEvent}, obtains the long hover utterance.
 *
 * @param event The source event.//from www  .  j  a  va2  s. c o  m
 */
private String getHintFromEvent(AccessibilityEvent event) {
    final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
    AccessibilityNodeInfoCompat source = record.getSource();

    if (source == null) {
        return null;
    }

    // If this was a HOVER_ENTER event, we need to compute the focused node.
    // TODO: We're already doing this in the touch exploration formatter --
    // maybe this belongs there instead?
    if (event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER) {
        source = AccessibilityNodeInfoUtils.findFocusFromHover(source);
        if (source == null) {
            return null;
        }
    }

    final CharSequence text = mRuleProcessor.getHintForNode(source);
    source.recycle();

    if (TextUtils.isEmpty(text)) {
        return null;
    }

    return text.toString();
}

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

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
        final AccessibilityNodeInfo node = event.getSource();
        if (node == null) {
            LogUtils.log(this, Log.WARN, "TYPE_VIEW_ACCESSIBILITY_FOCUSED event without a source.");
            return;
        }/* ww  w .j  a v  a 2  s. c o m*/

        // When a new view gets focus, clear the state of the granularity
        // manager if this event came from a different node than the locked
        // node but from the same window.
        final AccessibilityNodeInfoCompat nodeCompat = new AccessibilityNodeInfoCompat(node);
        mGranularityManager.onNodeFocused(nodeCompat);
        nodeCompat.recycle();
    }
}

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

/**
 * Helper method for {@link #shouldDropEvent} that handles events that
 * automatically occur immediately after a window state change.
 *
 * @param event The automatically generated event to consider retaining.
 * @return Whether to retain the event.//from  www  . j  a v a  2 s.  co m
 */
private boolean shouldKeepAutomaticEvent(AccessibilityEvent event) {
    final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);

    // Don't drop focus events from EditTexts.
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
        AccessibilityNodeInfoCompat node = null;

        try {
            node = record.getSource();
            if (Role.getRole(node) == Role.ROLE_EDIT_TEXT) {
                return true;
            }
        } finally {
            AccessibilityNodeInfoUtils.recycleNodes(node);
        }
    }

    return false;
}