List of usage examples for android.view.accessibility AccessibilityEvent getEventType
public @EventType int getEventType()
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; }