List of usage examples for android.view.accessibility AccessibilityEvent TYPE_WINDOWS_CHANGED
int TYPE_WINDOWS_CHANGED
To view the source code for android.view.accessibility AccessibilityEvent TYPE_WINDOWS_CHANGED.
Click Source Link
From source file:com.android.talkback.eventprocessor.ProcessorAccessibilityHints.java
@Override public void onAccessibilityEvent(AccessibilityEvent event) { if (!areHintsEnabled()) { return;/*from w ww . j a v a 2 s .c om*/ } // Clear hints that were generated before a click or in an old window configuration. final int eventType = event.getEventType(); if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED || eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || eventType == AccessibilityEvent.TYPE_WINDOWS_CHANGED) { cancelA11yHint(); return; } if (eventType == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED) { EventState eventState = EventState.getInstance(); if (eventState.checkAndClearRecentEvent(EventState.EVENT_SKIP_HINT_AFTER_GRANULARITY_MOVE)) { return; } if (eventState.checkAndClearRecentEvent(EventState.EVENT_SKIP_HINT_AFTER_CURSOR_CONTROL)) { return; } AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event); AccessibilityNodeInfoCompat source = record.getSource(); if (source != null) { postA11yHintRunnable(source); // DO NOT RECYCLE. postA11yHintRunnable will save the node. } } }
From source file:com.android.screenspeak.SavedNode.java
@Override public void onAccessibilityEvent(AccessibilityEvent event) { switch (event.getEventType()) { case AccessibilityEvent.TYPE_WINDOWS_CHANGED: clearCache();/*from w w w . ja v a 2s . co m*/ break; case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: AccessibilityNodeInfo source = event.getSource(); if (source != null) { AccessibilityNodeInfoCompat copyNode = new AccessibilityNodeInfoCompat( AccessibilityNodeInfo.obtain(source)); Selection selection = new Selection(event.getFromIndex(), event.getToIndex()); mSelectionCache.put(copyNode, selection); } break; } }
From source file:com.android.utils.AccessibilityEventUtils.java
public static int[] getAllEventTypes() { return new int[] { AccessibilityEvent.TYPE_ANNOUNCEMENT, AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT, AccessibilityEvent.TYPE_GESTURE_DETECTION_END, AccessibilityEvent.TYPE_GESTURE_DETECTION_START, AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED, AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END, AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START, AccessibilityEvent.TYPE_TOUCH_INTERACTION_END, AccessibilityEvent.TYPE_TOUCH_INTERACTION_START, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED, AccessibilityEvent.TYPE_VIEW_CLICKED, AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED, AccessibilityEvent.TYPE_VIEW_FOCUSED, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED, AccessibilityEvent.TYPE_VIEW_SCROLLED, AccessibilityEvent.TYPE_VIEW_SELECTED, AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED, AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED, AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY, AccessibilityEvent.TYPE_WINDOWS_CHANGED, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED }; }
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;/* www .ja v a2s.c o 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.talkback.formatter.TouchExplorationFormatter.java
/** * Resets cached scrollable state when touch exploration after window state * changes.//from w ww.j a v a2s . co m */ @Override public void onAccessibilityEvent(AccessibilityEvent event) { switch (event.getEventType()) { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: // Reset cached scrollable state. mLastNodeWasScrollable = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Store window title in the map. List<CharSequence> titles = event.getText(); if (titles.size() > 0) { AccessibilityNodeInfo node = event.getSource(); if (node != null) { int windowType = getWindowType(node); if (windowType == AccessibilityWindowInfo.TYPE_APPLICATION || windowType == AccessibilityWindowInfo.TYPE_SYSTEM) { mWindowTitlesMap.put(node.getWindowId(), titles.get(0)); } node.recycle(); } } } break; case AccessibilityEvent.TYPE_WINDOWS_CHANGED: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Copy key set not to modify original map. HashSet<Integer> windowIdsToBeRemoved = new HashSet<Integer>(); windowIdsToBeRemoved.addAll(mWindowTitlesMap.keySet()); // Enumerate window ids to be removed. List<AccessibilityWindowInfo> windows = mService.getWindows(); for (AccessibilityWindowInfo window : windows) { windowIdsToBeRemoved.remove(window.getId()); } // Delete titles of non-existing window ids. for (Integer windowId : windowIdsToBeRemoved) { mWindowTitlesMap.remove(windowId); } } break; } }
From source file:com.android.screenspeak.eventprocessor.AccessibilityEventProcessor.java
public void onAccessibilityEvent(AccessibilityEvent event) { if (mTestingListener != null) { mTestingListener.onAccessibilityEvent(event); }//from w w w.ja v a 2 s . com // 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.talkback.eventprocessor.AccessibilityEventProcessor.java
public void onAccessibilityEvent(AccessibilityEvent event) { if (mTestingListener != null) { mTestingListener.onAccessibilityEvent(event); }//from w w w . j a v a 2s . com if ((mDumpEventMask & event.getEventType()) != 0) { Log.v(DUMP_EVNET_LOG_TAG, event.toString()); } if (shouldDropRefocusEvent(event)) { return; } 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); } // We need to save the last focused event so that we can filter out related selected events. if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) { if (mLastFocusedEvent != null) { mLastFocusedEvent.recycle(); } mLastFocusedEvent = AccessibilityEvent.obtain(event); } if (AccessibilityEventUtils.eventMatchesAnyType(event, MASK_DELAYED_EVENT_TYPES)) { mHandler.postProcessEvent(event); } else { processEvent(event); } if (mTestingListener != null) { mTestingListener.afterAccessibilityEvent(event); } }
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 ww. j a v a 2 s. c o m } 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.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; }//from w w w .ja v a 2 s .co 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.controller.CursorControllerApp.java
@Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); if (eventType == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED) { final AccessibilityNodeInfo node = event.getSource(); if (node == null) { if (LogUtils.LOG_LEVEL <= Log.WARN) { Log.w(LOGTAG, "TYPE_VIEW_ACCESSIBILITY_FOCUSED event without a source."); }/* w w w . ja v a 2 s. co m*/ return; } // 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); if (mSwitchNodeWithGranularityDirection == AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY) { mGranularityManager.navigate(AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); } else if (mSwitchNodeWithGranularityDirection == AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY) { mGranularityManager.startFromLastNode(); mGranularityManager.navigate(AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); } mSwitchNodeWithGranularityDirection = 0; nodeCompat.recycle(); mReachedEdge = false; mGranularityNavigationReachedEdge = false; } else if (eventType == AccessibilityEvent.TYPE_VIEW_FOCUSED) { final AccessibilityNodeInfo node = event.getSource(); if (node != null) { final AccessibilityNodeInfoCompat nodeCompat = new AccessibilityNodeInfoCompat(node); // Note: we also need to check ROLE_EDIT_TEXT for JB MR1 and lower and for // Chrome/WebView 51 and lower. We should check isEditable() first because it's // more semantically appropriate for what we want. if (nodeCompat.isEditable() || Role.getRole(nodeCompat) == Role.ROLE_EDIT_TEXT) { AccessibilityNodeInfoUtils.recycleNodes(mLastEditable); mLastEditable = nodeCompat; } else { nodeCompat.recycle(); } } } else if (mIsWindowNavigationAvailable && eventType == AccessibilityEvent.TYPE_WINDOWS_CHANGED) { // Remove last focused nodes of non-existing windows. Set<Integer> windowIdsToBeRemoved = new HashSet(mLastFocusedNodeMap.keySet()); for (AccessibilityWindowInfo window : mService.getWindows()) { windowIdsToBeRemoved.remove(window.getId()); } for (Integer windowIdToBeRemoved : windowIdsToBeRemoved) { AccessibilityNodeInfoCompat removedNode = mLastFocusedNodeMap.remove(windowIdToBeRemoved); if (removedNode != null) { removedNode.recycle(); } } } }