Java Code Examples for android.view.accessibility.AccessibilityEvent#getSource()

The following examples show how to use android.view.accessibility.AccessibilityEvent#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: TreeDebugNavigationMode.java    From brailleback with Apache License 2.0 6 votes vote down vote up
@Override
public void onObserveAccessibilityEvent(AccessibilityEvent event) {
    AccessibilityNodeInfo source = event.getSource();
    if (source == null) {
        return;
    }
    boolean isNewWindow = false;
    if (mCurrentNode == null ||
            mCurrentNode.getWindowId() != source.getWindowId()) {
        isNewWindow = true;
    }
    int t = event.getEventType();
    boolean isInterestingEventType = false;
    if (t == AccessibilityEvent.TYPE_VIEW_SELECTED
            || t == AccessibilityEvent.TYPE_VIEW_FOCUSED
            || t == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
            || t != AccessibilityEvent.TYPE_VIEW_HOVER_ENTER) {
        isInterestingEventType = true;
    }
    if (isNewWindow || isInterestingEventType) {
        setPendingNode(source);
    }
}
 
Example 2
Source File: SilentInstallAccessibilityService.java    From android-silent-installer with Apache License 2.0 6 votes vote down vote up
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    AccessibilityNodeInfo nodeInfo = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        nodeInfo = event.getSource();
        if (nodeInfo != null) {
            int eventType = event.getEventType();
            if (eventType== AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED ||
                    eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                if (handledMap.get(event.getWindowId()) == null) {
                    boolean handled = iterateNodesAndHandle(nodeInfo);
                    if (handled) {
                        handledMap.put(event.getWindowId(), true);
                    }
                }
            }
        }
    }

}
 
Example 3
Source File: MainService.java    From Anti-recall with GNU Affero General Public License v3.0 6 votes vote down vote up
private void onClick(AccessibilityEvent event) {
    Log.i(TAG, "onClick " + event.getText());
    if (event.getSource() == null) {
        Log.i(TAG, "onClick: event.getSource() is null, return");
        return;
    }
    AccessibilityNodeInfo root = getRootInActiveWindow();
    switch (packageName) {
        case pkgTim:
            new TimClient(this).findRecalls(root, event);
            break;
        case pkgQQ:
            NodesInfo.show(root, TAG);
            new QQClient(this).findRecalls(root, event);
            break;
        case pkgWX:
            NodesInfo.show(root, TAG);
            break;
        case pkgThis:
            App.timeCheckAccessibilityServiceIsWorking = new Date().getTime();
            break;
    }
}
 
Example 4
Source File: AccessibilityEventUtils.java    From talkback with Apache License 2.0 6 votes vote down vote up
/** Returns window id from event, or WINDOW_ID_NONE. */
public static int getWindowId(@Nullable AccessibilityEvent event) {
  if (event == null) {
    return WINDOW_ID_NONE;
  }
  // Try to get window id from event.
  int windowId = event.getWindowId();
  if (windowId != WINDOW_ID_NONE) {
    return windowId;
  }
  // Try to get window id from event source.
  AccessibilityNodeInfo source = event.getSource();
  try {
    return (source == null) ? WINDOW_ID_NONE : source.getWindowId();
  } finally {
    AccessibilityNodeInfoUtils.recycleNodes(source);
  }
}
 
Example 5
Source File: ProcessorPhoneticLetters.java    From talkback with Apache License 2.0 6 votes vote down vote up
private boolean isKeyboardEvent(AccessibilityEvent event) {
  if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
    return false;
  }

  // For platform since lollipop, check that the current window is an
  // Input Method.
  final AccessibilityNodeInfo source = event.getSource();
  if (source == null) {
    return false;
  }

  int windowId = source.getWindowId();
  source.recycle();
  WindowManager manager = new WindowManager(service);
  return manager.getWindowType(windowId) == AccessibilityWindowInfo.TYPE_INPUT_METHOD;
}
 
Example 6
Source File: HongbaoService.java    From WeChatHongBao with Apache License 2.0 6 votes vote down vote up
private boolean watchList(AccessibilityEvent event) {
    // Not a message
    if ((event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && event.getEventType() != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) || event.getSource() == null)
        return false;

    List<AccessibilityNodeInfo> nodes = event.getSource().findAccessibilityNodeInfosByText(WECHAT_NOTIFICATION_TIP);
    if (!nodes.isEmpty()) {
        CharSequence contentDescription;
        AccessibilityNodeInfo nodeToClick;
        synchronized (this) {
            nodeToClick = nodes.get(0);
            if (nodeToClick == null) return false;
            contentDescription = nodeToClick.getContentDescription();
            if (contentDescription != null)
                if (!lastContentDescription.equals(contentDescription)) {
                    nodeToClick.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    lastContentDescription = contentDescription.toString();
                    return true;
                }
        }
    }
    return false;
}
 
Example 7
Source File: TamicInstallService.java    From Autoinstall with Apache License 2.0 6 votes vote down vote up
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {

        if (event.getSource() == null) {
            Log.d(LOG_TAG, "the source = null");
            return;
        }
        switch (INVOKE_TYPE) {
            case TYPE_INSTALL_APP:
                try {
                    processAccessibilityEvent(event);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case TYPE_UNINSTALL_APP:
                 //processUninstallApplication(event);
                break;
            default:
                break;
        }
    }
}
 
Example 8
Source File: ScrollFeedbackManager.java    From talkback with Apache License 2.0 5 votes vote down vote up
/** Posts the delayed scroll position feedback. Call this for every VIEW_SCROLLED event. */
private void postScrollFeedback(
    AccessibilityEvent event, Performance.@Nullable EventId eventId) {
  cancelScrollFeedback();
  AccessibilityEvent eventClone;
  try {
    eventClone = AccessibilityEvent.obtain(event);
  } catch (NullPointerException e) {
    LogUtils.i(
        TAG,
        "A NullPointerException is expected to be thrown in the Robolectric tests when we try"
            + " to create a clone of the mocking AccessibilityEvent instance. This exception"
            + " should never occur when the program is running on actual Android devices.");
    eventClone = event;
  }

  final EventIdAnd<AccessibilityEvent> eventAndId =
      new EventIdAnd<AccessibilityEvent>(eventClone, eventId);
  final Message msg = obtainMessage(SCROLL_FEEDBACK, eventAndId);

  AccessibilityNodeInfo source = event.getSource();
  if (Role.getRole(source) == Role.ROLE_PAGER) {
    sendMessageDelayed(msg, DELAY_PAGE_FEEDBACK);
  } else {
    sendMessageDelayed(msg, DELAY_SCROLL_FEEDBACK);
  }
  if (source != null) {
    source.recycle();
  }
}
 
Example 9
Source File: USSDServiceKT.java    From VoIpUSSD with Apache License 2.0 5 votes vote down vote up
private static List<AccessibilityNodeInfo> getLeaves(AccessibilityEvent event) {
    List<AccessibilityNodeInfo> leaves = new ArrayList<>();
    if (event.getSource() != null) {
        getLeaves(leaves, event.getSource());
    }
    return leaves;
}
 
Example 10
Source File: ScrollFeedbackManager.java    From talkback with Apache License 2.0 5 votes vote down vote up
/**
 * Given an {@link AccessibilityEvent}, speaks a scroll position.
 *
 * @param event The source event.
 */
private void handleScrollFeedback(AccessibilityEvent event, Performance.EventId eventId) {
  final CharSequence text;
  final int flags;
  AccessibilityNodeInfo source = event.getSource();

  boolean isVisibleToUser = source != null && source.isVisibleToUser();

  if (Role.getRole(source) == Role.ROLE_PAGER) {
    text = getDescriptionForPageEvent(event, source);
    flags = FeedbackItem.FLAG_FORCED_FEEDBACK;
  } else {
    text = getDescriptionForScrollEvent(event);
    flags = 0;
  }

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

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

  // don't pronounce non-visible nodes
  if (!isVisibleToUser) {
    return;
  }

  // Use QUEUE mode so that we don't interrupt more important messages.
  speechController.speak(
      text, /* Text */
      SpeechController.QUEUE_MODE_QUEUE, /* QueueMode */
      flags, /* Flags */
      speechParams, /* SpeechParams */
      eventId);
}
 
Example 11
Source File: AccessibilityEventUtils.java    From talkback with Apache License 2.0 5 votes vote down vote up
public static boolean hasSourceNode(AccessibilityEvent event) {
  if (event == null) {
    return false;
  }
  AccessibilityNodeInfo source = event.getSource();
  try {
    return source != null;
  } finally {
    AccessibilityNodeInfoUtils.recycleNodes(source);
  }
}
 
Example 12
Source File: TextEventInterpreter.java    From talkback with Apache License 2.0 5 votes vote down vote up
/**
 * Returns {@code true} if it's a junky {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} when
 * typing pin code in unlock screen.
 *
 * <p>Starting from P, pin entry at lock screen files text changed event when the digit typed in
 * is visually replaced by bullet. We don't want to announce this change.
 *
 * <p>Fortunately, password field at lock screen doesn't have this issue.
 */
private static boolean isJunkyCharacterReplacedByBulletInUnlockPinEntry(
    AccessibilityEvent event) {
  if (!BuildVersionUtils.isAtLeastP()
      || (event.getAddedCount() != 1)
      || (event.getRemovedCount() != 1)) {
    return false;
  }
  AccessibilityNodeInfo source = event.getSource();
  try {
    return AccessibilityNodeInfoUtils.isPinEntry(source);
  } finally {
    AccessibilityNodeInfoUtils.recycleNodes(source);
  }
}
 
Example 13
Source File: UiChangeHandler.java    From talkback with Apache License 2.0 5 votes vote down vote up
private void sendWindowChangeEventsToWindowChangedListener(
    WindowChangedListener windowChangedListener, List<AccessibilityEvent> windowChangeEventList) {
  if (isRunning) {
    while (!windowChangeEventList.isEmpty()) {
      AccessibilityEvent event = windowChangeEventList.get(0);

      CharSequence packageName = event.getPackageName();
      if (service.getPackageName().equals(packageName)) {
        AccessibilityNodeInfo info = event.getSource();
        if (info != null) {
          CharSequence className = info.getClassName();
          // Check whether the window events in the event list are triggered by opening the
          // Switch Access menu window. If so, clears the event list and calls
          // WindowChangeListener#onSwitchAccessMenuShown to generate screen feedback for
          // the Switch Access menu.
          //
          // We use two criteria to check if a window is a Switch Access menu window:
          // 1. The package of the event is the same as the Switch Access Accessibility
          //    Service.
          // 2. The source AccessibilityNodeInfoCompat of the event has the same class name
          //    as SwitchAccessMenuOverlay.
          if (switchAccessMenus.containsKey(className)) {
            windowChangedListener.onSwitchAccessMenuShown(switchAccessMenus.get(className));
            windowChangeEventList.clear();
            return;
          }
        }
      }

      windowChangedListener.onWindowChangedAndIsNowStable(
          windowChangeEventList.get(0), Performance.EVENT_ID_UNTRACKED);
      windowChangeEventList.remove(0);
    }
  }
}
 
Example 14
Source File: TamicInstallService.java    From Autoinstall with Apache License 2.0 5 votes vote down vote up
/**
 * containNodeWithText.
 * @param aAccessibilityEvent aAccessibilityEvent
 * @param aText               aText
 * @return                    Text
 */
private boolean containNodeWithText(AccessibilityEvent aAccessibilityEvent, String aText) {
    List<AccessibilityNodeInfo> extractList = null;
    if ((aAccessibilityEvent != null) && (aAccessibilityEvent.getSource()) != null) {
        extractList = aAccessibilityEvent.getSource().findAccessibilityNodeInfosByText(aText);
    } else {
        AccessibilityNodeInfo rootNode = this.getRootInActiveWindow();
        if (rootNode != null) {
            extractList = rootNode.findAccessibilityNodeInfosByText(aText);
        }
    }

    return !(extractList == null || extractList.isEmpty());

}
 
Example 15
Source File: EventFilter.java    From talkback with Apache License 2.0 5 votes vote down vote up
private boolean isValidScrollEvent(AccessibilityEvent event) {
  AccessibilityNodeInfo source = event.getSource();
  if (source == null) {
    return true; // Cannot check source validity, so assume that it's scrollable.
  }

  boolean valid =
      source.isScrollable() || event.getMaxScrollX() != -1 || event.getMaxScrollY() != -1;
  source.recycle();
  return valid;
}
 
Example 16
Source File: ScrollEventInterpreter.java    From talkback with Apache License 2.0 5 votes vote down vote up
private void cacheScrollPositionInfo(AccessibilityEvent event) {
  AccessibilityNodeInfo sourceNode = event.getSource();
  if (sourceNode == null) {
    return;
  }

  cachedPositionInfo.put(new NodeIdentifier(sourceNode), new PositionInfo(event));
  AccessibilityNodeInfoUtils.recycleNodes(sourceNode);
}
 
Example 17
Source File: TimeCatMonitorService.java    From timecat with Apache License 2.0 4 votes vote down vote up
private synchronized void getText(AccessibilityEvent event) {
        LogUtil.d(TAG, "getText:" + event);
        if (!monitorClick || event == null) {
            return;
        }
        if (showFloatView && !isRun) {
            return;
        }
        int type = getClickType(event);
        CharSequence className = event.getClassName();
        if (mWindowClassName == null) {
            return;
        }
        if (mWindowClassName.toString().startsWith("com.time.timecat")) {
            //自己的应用不监控
            return;
        }
        if (mCurrentPackage.equals(event.getPackageName())) {
            if (type != mCurrentType) {
                //点击方式不匹配,直接返回
                return;
            }
        } else {
            //包名不匹配,直接返回
            return;
        }
        if (className == null || className.equals("android.widget.EditText")) {
            //输入框不监控
            return;
        }
        if (onlyText) {
            //onlyText方式下,只获取TextView的内容
            if (!className.equals("android.widget.TextView")) {
                if (!hasShowTipToast) {
                    ToastUtil.i(R.string.toast_tip_content);
                    hasShowTipToast = true;
                }
                return;
            }
        }
        AccessibilityNodeInfo info = event.getSource();
        if (info == null) {
            return;
        }
        CharSequence txt = info.getText();
        if (TextUtils.isEmpty(txt) && !onlyText) {
            //非onlyText方式下获取文字更多,但是可能并不是想要的文字
            //比如系统短信页面需要这样才能获取到内容。
            List<CharSequence> txts = event.getText();
            if (txts != null) {
                StringBuilder sb = new StringBuilder();
                for (CharSequence t : txts) {
                    sb.append(t);
                }
                txt = sb.toString();
            }
        }
        if (!TextUtils.isEmpty(txt)) {
            if (txt.length() <= 2) {
                //对于太短的词进行屏蔽,因为这些词往往是“发送”等功能按钮,其实应该根据不同的activity进行区分
                if (!hasShowTooShortToast) {
                    ToastUtil.w(R.string.too_short_to_split);
                    hasShowTooShortToast = true;
                }
                return;
            }
            Intent intent = new Intent(this, TimeCatActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(TimeCatActivity.TO_SPLIT_STR, txt.toString());
//            startActivity(intent);
            //放到ArcTipViewController中触发试试
            ArcTipViewController.getInstance().showTipViewForStartActivity(intent);
        }
    }
 
Example 18
Source File: TamicInstallService.java    From Autoinstall with Apache License 2.0 4 votes vote down vote up
/**
 * processAccessibilityEvent.
 * @param aAccessibilityEvent   aAccessibilityEvent
 */
private void processAccessibilityEvent(AccessibilityEvent aAccessibilityEvent) {
    if(aAccessibilityEvent.getSource() != null) {
        String packageName = aAccessibilityEvent.getPackageName().toString();
        String className = aAccessibilityEvent.getClassName().toString();
        String nodeText = aAccessibilityEvent.getSource().getText() == null ? "" : aAccessibilityEvent.getSource().getText().toString().trim();

        if(packageName.equals("com.android.packageinstaller")) {
            if(className.equalsIgnoreCase("android.app.AlertDialog")) {
               // handleAlertDialog(aAccessibilityEvent, className, nodeText); //should for uninstall
                Log.e("test", "onAccessibilityEvent alert dialog");
                return;
            }

            if(containUninstallInfo(aAccessibilityEvent, className, nodeText)) {
                //skip
                Log.e("test", "onAccessibilityEvent uninstall 1");
                return;
            }

            if(isInstalledFinish(aAccessibilityEvent, className, nodeText)) {
                closeInstalledUI(null);
                return;
            }

            if(isUninstallUI(aAccessibilityEvent, className, nodeText)) {
                //skip
                Log.e("test", "onAccessibilityEvent uninstall 2");
                return;
            }

            if(isInstallUI(aAccessibilityEvent, className, nodeText)) {
                Log.e("test", "onAccessibilityEvent install");
                autoInstall(null);
                return;
            }

            if (!containNodeWithText(null, this.getString(R.string.str_accessibility_install_blocked))) {
                Log.e("test", "onAccessibilityEvent not contain block");
                return;
            }

            autoInstall(null);
            return;
        }

        if(packageName.equals("com.lenovo.safecenter")) {
            processAccessibilityEventForLenvo(aAccessibilityEvent, className, nodeText);
        }
    }
}
 
Example 19
Source File: ScrollEventInterpreter.java    From talkback with Apache License 2.0 4 votes vote down vote up
private ScrollEventInterpretation interpret(AccessibilityEvent event) {
  AccessibilityNodeInfo sourceNode = event.getSource();
  if (sourceNode == null) {
    return ScrollEventInterpretation.DEFAULT_INTERPRETATION;
  }

  // . We get scroll position WINDOW_CONTENT_CHANGED events to provide more fine-grained
  // scroll action detection. We need to carefully handle these events. Event if the position
  // changes, it might not result from scroll action. We need a solid strategy to protect against
  // this issue. It's difficult. The least effort we can do is to filter out non-scrollable node.
  if ((event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)
      && !AccessibilityNodeInfoUtils.isScrollable(AccessibilityNodeInfoCompat.wrap(sourceNode))) {
    return ScrollEventInterpretation.DEFAULT_INTERPRETATION;
  }

  final NodeIdentifier sourceNodeIdentifier = new NodeIdentifier(sourceNode);
  AccessibilityNodeInfoUtils.recycleNodes(sourceNode);

  @SearchDirectionOrUnknown
  final int scrollDirection = getScrollDirection(sourceNodeIdentifier, event);
  @UserAction final int userAction;
  final int scrollInstanceId;

  @Nullable AutoScrollRecord autoScrollRecord = isFromAutoScrollAction(event);
  if (autoScrollRecord == null) {
    scrollInstanceId = SCROLL_INSTANCE_ID_UNDEFINED;
    // Note that TYPE_WINDOW_CONTENT_CHANGED events can also be interpreted as manual scroll
    // action. TYPE_VIEW_SCROLLED events are filed at very coarse granularity. If we rely only on
    // TYPE_VIEW_SCROLLED events to detect manual scroll action, it happens when the user slightly
    // scroll a list and accessibility focus goes off screen, we don't receive
    // TYPE_VIEW_SCROLLED event thus we don't update accessibility focus. If user performs linear
    // navigation after that, accessibility focus might go to the beginning of screen.
    // We take into account TYPE_WINDOW_CONTENT_CHANGED events to provide more
    // fine-grained manual scroll callback.
    userAction =
        scrollDirection == TraversalStrategy.SEARCH_FOCUS_UNKNOWN
            ? ACTION_UNKNOWN
            : ACTION_MANUAL_SCROLL;
  } else {
    scrollInstanceId = autoScrollRecord.scrollInstanceId;
    userAction = autoScrollRecord.userAction;
  }

  final boolean hasValidIndex = hasValidIndex(event);
  final boolean isDuplicateEvent = hasValidIndex && isDuplicateEvent(sourceNodeIdentifier, event);

  return new ScrollEventInterpretation(
      userAction, scrollDirection, hasValidIndex, isDuplicateEvent, scrollInstanceId);
}
 
Example 20
Source File: TaskBackService.java    From codeexamples-android with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Processes an AccessibilityEvent, by traversing the View's tree and
 * putting together a message to speak to the user.
 */
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (!mTextToSpeechInitialized) {
        Log.e(LOG_TAG, "Text-To-Speech engine not ready.  Bailing out.");
        return;
    }

    // This AccessibilityNodeInfo represents the view that fired the
    // AccessibilityEvent. The following code will use it to traverse the
    // view hierarchy, using this node as a starting point.
    //
    // NOTE: Every method that returns an AccessibilityNodeInfo may return null,
    // because the explored window is in another process and the
    // corresponding View might be gone by the time your request reaches the
    // view hierarchy.
    AccessibilityNodeInfo source = event.getSource();
    if (source == null) {
        return;
    }

    // Grab the parent of the view that fired the event.
    AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
    if (rowNode == null) {
        return;
    }

    // Using this parent, get references to both child nodes, the label and the checkbox.
    AccessibilityNodeInfo labelNode = rowNode.getChild(0);
    if (labelNode == null) {
        rowNode.recycle();
        return;
    }

    AccessibilityNodeInfo completeNode = rowNode.getChild(1);
    if (completeNode == null) {
        rowNode.recycle();
        return;
    }

    // Determine what the task is and whether or not it's complete, based on
    // the text inside the label, and the state of the check-box.
    if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {
        rowNode.recycle();
        return;
    }

    CharSequence taskLabel = labelNode.getText();
    final boolean isComplete = completeNode.isChecked();

    String completeStr = null;
    if (isComplete) {
        completeStr = getString(R.string.task_complete);
    } else {
        completeStr = getString(R.string.task_not_complete);
    }

    String taskStr = getString(R.string.task_complete_template, taskLabel, completeStr);
    StringBuilder utterance = new StringBuilder(taskStr);

    // The custom ListView added extra context to the event by adding an
    // AccessibilityRecord to it. Extract that from the event and read it.
    final int records = event.getRecordCount();
    for (int i = 0; i < records; i++) {
        AccessibilityRecord record = event.getRecord(i);
        CharSequence contentDescription = record.getContentDescription();
        if (!TextUtils.isEmpty(contentDescription )) {
            utterance.append(SEPARATOR);
            utterance.append(contentDescription);
        }
    }

    // Announce the utterance.
    mTts.speak(utterance.toString(), TextToSpeech.QUEUE_FLUSH, null);
    Log.d(LOG_TAG, utterance.toString());
}