Java Code Examples for androidx.core.view.accessibility.AccessibilityRecordCompat#getSource()

The following examples show how to use androidx.core.view.accessibility.AccessibilityRecordCompat#getSource() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Compositor.java    From talkback with Apache License 2.0 6 votes vote down vote up
/** Handles a standard AccessibilityEvent */
public void handleEvent(
    AccessibilityEvent event, @Nullable EventId eventId, EventInterpretation eventInterpreted) {

  final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
  @Event int eventType = eventInterpreted.getEvent();

  // TODO
  // Allocate source node & delegate which must be recycled.
  AccessibilityNodeInfoCompat sourceNode = record.getSource();
  ParseTree.VariableDelegate delegate =
      mVariablesFactory.createLocalVariableDelegate(event, sourceNode, eventInterpreted);

  // Compute speech and speech flags.
  HandleEventOptions options =
      new HandleEventOptions().object(event).interpretation(eventInterpreted).source(sourceNode);
  handleEvent(eventType, eventId, delegate, options);
  AccessibilityNodeInfoUtils.recycleNodes(sourceNode);
}
 
Example 2
Source File: Role.java    From talkback with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the source {@link Role} from the {@link AccessibilityEvent}.
 *
 * <p>It checks the role with {@link AccessibilityEvent#getClassName()}. If it returns {@link
 * #ROLE_NONE}, fallback to check {@link AccessibilityNodeInfoCompat#getClassName()} of the source
 * node.
 */
public static @RoleName int getSourceRole(AccessibilityEvent event) {
  if (event == null) {
    return ROLE_NONE;
  }

  // Try to get role from event's class name.
  @RoleName int role = sourceClassNameToRole(event);
  if (role != ROLE_NONE) {
    return role;
  }

  // Extract event's source node, and map source node class to role.
  AccessibilityRecordCompat eventRecord = AccessibilityEventCompat.asRecord(event);
  AccessibilityNodeInfoCompat source = eventRecord.getSource();
  try {
    return getRole(source);
  } finally {
    AccessibilityNodeInfoUtils.recycleNodes(source);
  }
}
 
Example 3
Source File: AccessibilityEventProcessor.java    From talkback with Apache License 2.0 6 votes vote down vote up
/**
 * 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.
 */
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;
}
 
Example 4
Source File: GlobalVariables.java    From talkback with Apache License 2.0 5 votes vote down vote up
public void updateStateFromEvent(AccessibilityEvent event) {
  switch (event.getEventType()) {
    case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
      {
        final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
        final AccessibilityNodeInfoCompat sourceNode = record.getSource();

        // Transition the collection state if necessary.
        mCollectionState.updateCollectionInformation(sourceNode, event);
        if (sourceNode != null) {
          final AccessibilityNodeInfoCompat scrollableNode =
              AccessibilityNodeInfoUtils.getSelfOrMatchingAncestor(
                  sourceNode, AccessibilityNodeInfoUtils.FILTER_SCROLLABLE);
          mIsLastFocusInScrollableNode = mIsCurrentFocusInScrollableNode;
          mIsCurrentFocusInScrollableNode = (scrollableNode != null);
          if (scrollableNode != null) {
            scrollableNode.recycle();
          }

          TraversalStrategy traversalStrategy = new SimpleTraversalStrategy();
          // TODO: TraversalStrategyUtils.isEdgeListItem() doesn't include Role check in
          // AccessibilityNodeInfoUtils.FILTER_AUTO_SCROLL. Shall we use
          // TraversalStrategyUtils.isAutoScrollEdgeListItem() instead?
          mIsFocusEdgeListItem =
              TraversalStrategyUtils.isEdgeListItem(sourceNode, traversalStrategy);
          traversalStrategy.recycle();

          mLastWindowId = mCurrentWindowId;
          mCurrentWindowId = sourceNode.getWindowId();
          sourceNode.recycle();
        }
      }
      break;
    default: // fall out
  }
}
 
Example 5
Source File: AccessibilityEventUtils.java    From talkback with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true if the event came from a non main window event, such as invisible, toast, or IME
 * window; otherwise returns false. Examples:
 *
 * <ul>
 *   <li>Returns false for main activity windows.
 *   <li>Returns true for the soft keyboard window in an IME.
 *   <li>Returns true for toasts.
 *   <li>Returns true for volume slider.
 * </ul>
 */
// TODO: Add window-types similar to AccessibilityWindowInfo.getType(), but more
// specific and more stable across android versions.
public static boolean isNonMainWindowEvent(AccessibilityEvent event) {
  // If there's an actual window ID, we need to check the window type (if window available).
  boolean isNonMainWindow = false;
  AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
  AccessibilityNodeInfoCompat source = record.getSource();
  if (source != null) {
    AccessibilityWindowInfoCompat window = AccessibilityNodeInfoUtils.getWindow(source);
    if (window == null) {
      // If window is not visible, we cannot know whether the window type is input method
      // or not. Let's assume that it comes from an IME. If window is visible but window
      // info is not available, it can be non-focusable visible window.
      isNonMainWindow = true;
    } else {
      switch (window.getType()) {
        case AccessibilityWindowInfoCompat.TYPE_INPUT_METHOD:
          // IME case.
          isNonMainWindow = true;
          break;
        case AccessibilityWindowInfoCompat.TYPE_SYSTEM:
          isNonMainWindow = isFromVolumeControlPanel(event);
          break;
        default: // fall out
      }
      window.recycle();
    }
    source.recycle();
  }
  return isNonMainWindow;
}
 
Example 6
Source File: ProcessorCursorState.java    From talkback with Apache License 2.0 5 votes vote down vote up
private void saveFocusedNode(AccessibilityRecordCompat record) {
  if (focusedNode != null) {
    focusedNode.recycle();
    focusedNode = null;
  }

  AccessibilityNodeInfoCompat source = record.getSource();
  if (source != null) {
    if (Role.getRole(source) == Role.ROLE_EDIT_TEXT) {
      focusedNode = source;
    } else {
      source.recycle();
    }
  }
}
 
Example 7
Source File: ProcessorCursorState.java    From talkback with Apache License 2.0 5 votes vote down vote up
private void resetNodeCursor(AccessibilityRecordCompat record, EventId eventId) {
  AccessibilityNodeInfoCompat source = record.getSource();
  if (source != null) {
    if (source.equals(focusedNode)) {
      // Reset cursor to end if there's text.
      if (!TextUtils.isEmpty(source.getText())) {
        int end = source.getText().length();

        Bundle bundle = new Bundle();
        bundle.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, end);
        bundle.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, end);

        globalVariables.setFlag(GlobalVariables.EVENT_SKIP_SELECTION_CHANGED_AFTER_FOCUSED);
        globalVariables.setFlag(GlobalVariables.EVENT_SKIP_SELECTION_CHANGED_AFTER_CURSOR_RESET);
        PerformActionUtils.performAction(
            source, AccessibilityNodeInfoCompat.ACTION_SET_SELECTION, bundle, eventId);

        SpeechController.SpeakOptions speakOptions =
            SpeechController.SpeakOptions.create()
                .setQueueMode(SpeechController.QUEUE_MODE_QUEUE)
                .setFlags(
                    FeedbackItem.FLAG_FORCED_FEEDBACK_AUDIO_PLAYBACK_ACTIVE
                        | FeedbackItem.FLAG_FORCED_FEEDBACK_MICROPHONE_ACTIVE
                        | FeedbackItem.FLAG_FORCED_FEEDBACK_SSB_ACTIVE);
        Feedback.Part.Builder part =
            Feedback.Part.builder()
                .speech(context.getString(R.string.notification_type_end_of_field), speakOptions)
                .setDelayMs(SPEECH_DELAY)
                .setInterruptGroup(CURSOR_STATE)
                .setInterruptLevel(1);
        // Not tracking performance because field feedback should already be
        // provided when field is focused.
        pipeline.returnFeedback(EVENT_ID_UNTRACKED, part);
      }
    }

    source.recycle();
  }
}
 
Example 8
Source File: ProcessorPermissionDialogs.java    From talkback with Apache License 2.0 5 votes vote down vote up
@Override
public void onAccessibilityEvent(AccessibilityEvent event, EventId eventId) {
  switch (event.getEventType()) {
    case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
      clearNode();
      AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
      AccessibilityNodeInfoCompat source = record.getSource();
      if (source != null) {
        if (ALLOW_BUTTON.equals(source.getViewIdResourceName())
            && dimScreenController.isDimmingEnabled()) {
          Rect sourceRect = new Rect();
          source.getBoundsInScreen(sourceRect);
          overlay.show(sourceRect);
          allowNode = source;
        } else {
          source.recycle();
        }
      }
      break;
    case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
    case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
      clearNode();
      break;
    default: // fall out
  }

  if (allowNode != null) {
    overlay.onAccessibilityEvent(event, eventId);
  }
}
 
Example 9
Source File: EventFilter.java    From talkback with Apache License 2.0 4 votes vote down vote up
private boolean shouldDropTextSelectionEvent(AccessibilityEvent event) {
  // Keep all events other than text-selection.
  final int eventType = event.getEventType();
  if (eventType != AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED) {
    return false;
  }

  // Drop selected events until we've matched the number of changed
  // events. This prevents TalkBack from speaking automatic cursor
  // movement events that result from typing.
  if (textEventHistory.getTextChangesAwaitingSelection() > 0) {
    final boolean hasDelayElapsed =
        ((event.getEventTime() - textEventHistory.getLastTextChangeTime())
            >= TEXT_SELECTION_DELAY);
    final boolean hasPackageChanged =
        !TextUtils.equals(
            event.getPackageName(), textEventHistory.getLastTextChangePackageName());

    // If the state is still consistent, update the count and drop the event.
    if (!hasDelayElapsed && !hasPackageChanged) {
      textEventHistory.incrementTextChangesAwaitingSelection(-1);
      textEventHistory.setLastFromIndex(event.getFromIndex());
      textEventHistory.setLastToIndex(event.getToIndex());
      textEventHistory.setLastNode(event.getSource());
      return true;
    }

    // The state became inconsistent, so reset the counter.
    textEventHistory.setTextChangesAwaitingSelection(0);
  }

  // Drop selection events from views that don't have input focus.
  final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
  final AccessibilityNodeInfoCompat source = record.getSource();
  boolean isFocused = source != null && source.isFocused();
  AccessibilityNodeInfoUtils.recycleNodes(source);
  if (!isFocused) {
    LogUtils.v(TAG, "Dropped text-selection event from non-focused field");
    return true;
  }

  return false;
}