1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.content.browser.accessibility;
7 import android.content.Context;
8 import android.graphics.Rect;
9 import android.os.Build;
10 import android.os.Bundle;
11 import android.text.SpannableString;
12 import android.text.style.URLSpan;
13 import android.view.MotionEvent;
14 import android.view.View;
15 import android.view.ViewParent;
16 import android.view.accessibility.AccessibilityEvent;
17 import android.view.accessibility.AccessibilityManager;
18 import android.view.accessibility.AccessibilityNodeInfo;
19 import android.view.accessibility.AccessibilityNodeProvider;
21 import org.chromium.base.CalledByNative;
22 import org.chromium.base.JNINamespace;
23 import org.chromium.content.browser.ContentViewCore;
24 import org.chromium.content.browser.RenderCoordinates;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.Locale;
31 * Native accessibility for a {@link ContentViewCore}.
33 * This class is safe to load on ICS and can be used to run tests, but
34 * only the subclass, JellyBeanBrowserAccessibilityManager, actually
35 * has a AccessibilityNodeProvider implementation needed for native
38 @JNINamespace("content")
39 public class BrowserAccessibilityManager {
40 private static final String TAG = "BrowserAccessibilityManager";
42 private ContentViewCore mContentViewCore;
43 private final AccessibilityManager mAccessibilityManager;
44 private final RenderCoordinates mRenderCoordinates;
45 private long mNativeObj;
46 private int mAccessibilityFocusId;
47 private boolean mIsHovering;
48 private int mCurrentRootId;
49 private final int[] mTempLocation = new int[2];
50 private final View mView;
51 private boolean mUserHasTouchExplored;
52 private boolean mPendingScrollToMakeNodeVisible;
53 private boolean mFrameInfoInitialized;
56 * Create a BrowserAccessibilityManager object, which is owned by the C++
57 * BrowserAccessibilityManagerAndroid instance, and connects to the content view.
58 * @param nativeBrowserAccessibilityManagerAndroid A pointer to the counterpart native
59 * C++ object that owns this object.
60 * @param contentViewCore The content view that this object provides accessibility for.
63 private static BrowserAccessibilityManager create(long nativeBrowserAccessibilityManagerAndroid,
64 ContentViewCore contentViewCore) {
65 // A bug in the KitKat framework prevents us from using these new APIs.
66 // http://crbug.com/348088/
67 // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
68 // return new KitKatBrowserAccessibilityManager(
69 // nativeBrowserAccessibilityManagerAndroid, contentViewCore);
71 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
72 return new JellyBeanBrowserAccessibilityManager(
73 nativeBrowserAccessibilityManagerAndroid, contentViewCore);
75 return new BrowserAccessibilityManager(
76 nativeBrowserAccessibilityManagerAndroid, contentViewCore);
80 protected BrowserAccessibilityManager(long nativeBrowserAccessibilityManagerAndroid,
81 ContentViewCore contentViewCore) {
82 mNativeObj = nativeBrowserAccessibilityManagerAndroid;
83 mContentViewCore = contentViewCore;
84 mContentViewCore.setBrowserAccessibilityManager(this);
85 mAccessibilityFocusId = View.NO_ID;
87 mCurrentRootId = View.NO_ID;
88 mView = mContentViewCore.getContainerView();
89 mRenderCoordinates = mContentViewCore.getRenderCoordinates();
90 mAccessibilityManager =
91 (AccessibilityManager) mContentViewCore.getContext()
92 .getSystemService(Context.ACCESSIBILITY_SERVICE);
96 private void onNativeObjectDestroyed() {
97 if (mContentViewCore.getBrowserAccessibilityManager() == this) {
98 mContentViewCore.setBrowserAccessibilityManager(null);
101 mContentViewCore = null;
105 * @return An AccessibilityNodeProvider on JellyBean, and null on previous versions.
107 public AccessibilityNodeProvider getAccessibilityNodeProvider() {
112 * @see AccessibilityNodeProvider#createAccessibilityNodeInfo(int)
114 protected AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
115 if (!mAccessibilityManager.isEnabled() || mNativeObj == 0) {
119 int rootId = nativeGetRootId(mNativeObj);
121 if (virtualViewId == View.NO_ID) {
122 return createNodeForHost(rootId);
125 if (!mFrameInfoInitialized) {
129 final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(mView);
130 info.setPackageName(mContentViewCore.getContext().getPackageName());
131 info.setSource(mView, virtualViewId);
133 if (virtualViewId == rootId) {
134 info.setParent(mView);
137 if (nativePopulateAccessibilityNodeInfo(mNativeObj, info, virtualViewId)) {
146 * @see AccessibilityNodeProvider#findAccessibilityNodeInfosByText(String, int)
148 protected List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text,
150 return new ArrayList<AccessibilityNodeInfo>();
154 * @see AccessibilityNodeProvider#performAction(int, int, Bundle)
156 protected boolean performAction(int virtualViewId, int action, Bundle arguments) {
157 // We don't support any actions on the host view or nodes
158 // that are not (any longer) in the tree.
159 if (!mAccessibilityManager.isEnabled() || mNativeObj == 0
160 || !nativeIsNodeValid(mNativeObj, virtualViewId)) {
165 case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
166 if (mAccessibilityFocusId == virtualViewId) {
170 mAccessibilityFocusId = virtualViewId;
171 sendAccessibilityEvent(mAccessibilityFocusId,
172 AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
174 nativeScrollToMakeNodeVisible(
175 mNativeObj, mAccessibilityFocusId);
177 mPendingScrollToMakeNodeVisible = true;
180 case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
181 if (mAccessibilityFocusId == virtualViewId) {
182 sendAccessibilityEvent(mAccessibilityFocusId,
183 AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
184 mAccessibilityFocusId = View.NO_ID;
187 case AccessibilityNodeInfo.ACTION_CLICK:
188 nativeClick(mNativeObj, virtualViewId);
189 sendAccessibilityEvent(virtualViewId,
190 AccessibilityEvent.TYPE_VIEW_CLICKED);
192 case AccessibilityNodeInfo.ACTION_FOCUS:
193 nativeFocus(mNativeObj, virtualViewId);
195 case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS:
196 nativeBlur(mNativeObj);
199 case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT: {
200 if (arguments == null)
202 String elementType = arguments.getString(
203 AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
204 if (elementType == null)
206 elementType = elementType.toUpperCase(Locale.US);
207 return jumpToElementType(elementType, true);
209 case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT: {
210 if (arguments == null)
212 String elementType = arguments.getString(
213 AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
214 if (elementType == null)
216 elementType = elementType.toUpperCase(Locale.US);
217 return jumpToElementType(elementType, false);
227 * @see View#onHoverEvent(MotionEvent)
229 public boolean onHoverEvent(MotionEvent event) {
230 if (!mAccessibilityManager.isEnabled() || mNativeObj == 0) {
234 if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
236 if (mPendingScrollToMakeNodeVisible) {
237 nativeScrollToMakeNodeVisible(
238 mNativeObj, mAccessibilityFocusId);
240 mPendingScrollToMakeNodeVisible = false;
245 mUserHasTouchExplored = true;
246 float x = event.getX();
247 float y = event.getY();
249 // Convert to CSS coordinates.
250 int cssX = (int) (mRenderCoordinates.fromPixToLocalCss(x) +
251 mRenderCoordinates.getScrollX());
252 int cssY = (int) (mRenderCoordinates.fromPixToLocalCss(y) +
253 mRenderCoordinates.getScrollY());
254 int id = nativeHitTest(mNativeObj, cssX, cssY);
255 if (mAccessibilityFocusId != id) {
256 sendAccessibilityEvent(mAccessibilityFocusId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
257 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
264 * Called by ContentViewCore to notify us when the frame info is initialized,
265 * the first time, since until that point, we can't use mRenderCoordinates to transform
266 * web coordinates to screen coordinates.
268 public void notifyFrameInfoInitialized() {
269 if (mFrameInfoInitialized) return;
271 mFrameInfoInitialized = true;
272 // Invalidate the host, since the chrome accessibility tree is now
273 // ready and listed as the child of the host.
274 mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
276 // (Re-) focus focused element, since we weren't able to create an
277 // AccessibilityNodeInfo for this element before.
278 if (mAccessibilityFocusId != View.NO_ID) {
279 sendAccessibilityEvent(mAccessibilityFocusId,
280 AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
284 private boolean jumpToElementType(String elementType, boolean forwards) {
285 int id = nativeFindElementType(mNativeObj, mAccessibilityFocusId, elementType, forwards);
289 mAccessibilityFocusId = id;
290 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
294 private void sendAccessibilityEvent(int virtualViewId, int eventType) {
295 // If mFrameInfoInitialized is false, then the virtual hierarchy
296 // doesn't exist in the view of the Android framework, so should
297 // never send any events.
298 if (!mAccessibilityManager.isEnabled() || mNativeObj == 0
299 || !mFrameInfoInitialized) {
303 final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
304 event.setPackageName(mContentViewCore.getContext().getPackageName());
305 event.setSource(mView, virtualViewId);
306 if (!nativePopulateAccessibilityEvent(mNativeObj, event, virtualViewId, eventType)) {
311 // This is currently needed if we want Android to draw the yellow box around
312 // the item that has accessibility focus. In practice, this doesn't seem to slow
313 // things down, because it's only called when the accessibility focus moves.
314 // TODO(dmazzoni): remove this if/when Android framework fixes bug.
315 mContentViewCore.getContainerView().postInvalidate();
317 mContentViewCore.getContainerView().requestSendAccessibilityEvent(mView, event);
320 private Bundle getOrCreateBundleForAccessibilityEvent(AccessibilityEvent event) {
321 Bundle bundle = (Bundle) event.getParcelableData();
322 if (bundle == null) {
323 bundle = new Bundle();
324 event.setParcelableData(bundle);
329 private AccessibilityNodeInfo createNodeForHost(int rootId) {
330 // Since we don't want the parent to be focusable, but we can't remove
331 // actions from a node, copy over the necessary fields.
332 final AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(mView);
333 final AccessibilityNodeInfo source = AccessibilityNodeInfo.obtain(mView);
334 mView.onInitializeAccessibilityNodeInfo(source);
336 // Copy over parent and screen bounds.
337 Rect rect = new Rect();
338 source.getBoundsInParent(rect);
339 result.setBoundsInParent(rect);
340 source.getBoundsInScreen(rect);
341 result.setBoundsInScreen(rect);
343 // Set up the parent view, if applicable.
344 final ViewParent parent = mView.getParentForAccessibility();
345 if (parent instanceof View) {
346 result.setParent((View) parent);
349 // Populate the minimum required fields.
350 result.setVisibleToUser(source.isVisibleToUser());
351 result.setEnabled(source.isEnabled());
352 result.setPackageName(source.getPackageName());
353 result.setClassName(source.getClassName());
355 // Add the Chrome root node.
356 if (mFrameInfoInitialized) {
357 result.addChild(mView, rootId);
364 private void handlePageLoaded(int id) {
365 if (mUserHasTouchExplored) return;
367 mAccessibilityFocusId = id;
368 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
372 private void handleFocusChanged(int id) {
373 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_FOCUSED);
375 // Update accessibility focus if not already set to this node.
376 if (mAccessibilityFocusId != id) {
377 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
378 mAccessibilityFocusId = id;
383 private void handleCheckStateChanged(int id) {
384 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_CLICKED);
388 private void handleTextSelectionChanged(int id) {
389 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
393 private void handleEditableTextChanged(int id) {
394 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
398 private void handleContentChanged(int id) {
399 int rootId = nativeGetRootId(mNativeObj);
400 if (rootId != mCurrentRootId) {
401 mCurrentRootId = rootId;
402 mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
404 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
409 private void handleNavigate() {
410 mAccessibilityFocusId = View.NO_ID;
411 mUserHasTouchExplored = false;
412 mFrameInfoInitialized = false;
413 // Invalidate the host, since its child is now gone.
414 mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
418 private void handleScrollPositionChanged(int id) {
419 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_SCROLLED);
423 private void handleScrolledToAnchor(int id) {
424 if (mAccessibilityFocusId == id) {
428 mAccessibilityFocusId = id;
429 sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
433 private void announceLiveRegionText(String text) {
434 mView.announceForAccessibility(text);
438 private void setAccessibilityNodeInfoParent(AccessibilityNodeInfo node, int parentId) {
439 node.setParent(mView, parentId);
443 private void addAccessibilityNodeInfoChild(AccessibilityNodeInfo node, int childId) {
444 node.addChild(mView, childId);
448 private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfo node,
449 int virtualViewId, boolean checkable, boolean checked, boolean clickable,
450 boolean enabled, boolean focusable, boolean focused, boolean password,
451 boolean scrollable, boolean selected, boolean visibleToUser) {
452 node.setCheckable(checkable);
453 node.setChecked(checked);
454 node.setClickable(clickable);
455 node.setEnabled(enabled);
456 node.setFocusable(focusable);
457 node.setFocused(focused);
458 node.setPassword(password);
459 node.setScrollable(scrollable);
460 node.setSelected(selected);
461 node.setVisibleToUser(visibleToUser);
463 node.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
464 node.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
468 node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
470 node.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
474 if (mAccessibilityFocusId == virtualViewId) {
475 node.setAccessibilityFocused(true);
476 node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
478 node.setAccessibilityFocused(false);
479 node.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
483 node.addAction(AccessibilityNodeInfo.ACTION_CLICK);
488 private void setAccessibilityNodeInfoClassName(AccessibilityNodeInfo node,
490 node.setClassName(className);
494 private void setAccessibilityNodeInfoContentDescription(
495 AccessibilityNodeInfo node, String contentDescription, boolean annotateAsLink) {
496 if (annotateAsLink) {
497 SpannableString spannable = new SpannableString(contentDescription);
498 spannable.setSpan(new URLSpan(""), 0, spannable.length(), 0);
499 node.setContentDescription(spannable);
501 node.setContentDescription(contentDescription);
506 private void setAccessibilityNodeInfoLocation(AccessibilityNodeInfo node,
507 int absoluteLeft, int absoluteTop, int parentRelativeLeft, int parentRelativeTop,
508 int width, int height, boolean isRootNode) {
509 // First set the bounds in parent.
510 Rect boundsInParent = new Rect(parentRelativeLeft, parentRelativeTop,
511 parentRelativeLeft + width, parentRelativeTop + height);
513 // Offset of the web content relative to the View.
514 boundsInParent.offset(0, (int) mRenderCoordinates.getContentOffsetYPix());
516 node.setBoundsInParent(boundsInParent);
518 // Now set the absolute rect, which requires several transformations.
519 Rect rect = new Rect(absoluteLeft, absoluteTop, absoluteLeft + width, absoluteTop + height);
521 // Offset by the scroll position.
522 rect.offset(-(int) mRenderCoordinates.getScrollX(),
523 -(int) mRenderCoordinates.getScrollY());
525 // Convert CSS (web) pixels to Android View pixels
526 rect.left = (int) mRenderCoordinates.fromLocalCssToPix(rect.left);
527 rect.top = (int) mRenderCoordinates.fromLocalCssToPix(rect.top);
528 rect.bottom = (int) mRenderCoordinates.fromLocalCssToPix(rect.bottom);
529 rect.right = (int) mRenderCoordinates.fromLocalCssToPix(rect.right);
531 // Offset by the location of the web content within the view.
533 (int) mRenderCoordinates.getContentOffsetYPix());
535 // Finally offset by the location of the view within the screen.
536 final int[] viewLocation = new int[2];
537 mView.getLocationOnScreen(viewLocation);
538 rect.offset(viewLocation[0], viewLocation[1]);
540 node.setBoundsInScreen(rect);
544 protected void setAccessibilityNodeInfoKitKatAttributes(AccessibilityNodeInfo node,
545 boolean canOpenPopup,
546 boolean contentInvalid,
551 // Requires KitKat or higher.
555 protected void setAccessibilityNodeInfoCollectionInfo(AccessibilityNodeInfo node,
556 int rowCount, int columnCount, boolean hierarchical) {
557 // Requires KitKat or higher.
561 protected void setAccessibilityNodeInfoCollectionItemInfo(AccessibilityNodeInfo node,
562 int rowIndex, int rowSpan, int columnIndex, int columnSpan, boolean heading) {
563 // Requires KitKat or higher.
567 protected void setAccessibilityNodeInfoRangeInfo(AccessibilityNodeInfo node,
568 int rangeType, float min, float max, float current) {
569 // Requires KitKat or higher.
573 private void setAccessibilityEventBooleanAttributes(AccessibilityEvent event,
574 boolean checked, boolean enabled, boolean password, boolean scrollable) {
575 event.setChecked(checked);
576 event.setEnabled(enabled);
577 event.setPassword(password);
578 event.setScrollable(scrollable);
582 private void setAccessibilityEventClassName(AccessibilityEvent event, String className) {
583 event.setClassName(className);
587 private void setAccessibilityEventListAttributes(AccessibilityEvent event,
588 int currentItemIndex, int itemCount) {
589 event.setCurrentItemIndex(currentItemIndex);
590 event.setItemCount(itemCount);
594 private void setAccessibilityEventScrollAttributes(AccessibilityEvent event,
595 int scrollX, int scrollY, int maxScrollX, int maxScrollY) {
596 event.setScrollX(scrollX);
597 event.setScrollY(scrollY);
598 event.setMaxScrollX(maxScrollX);
599 event.setMaxScrollY(maxScrollY);
603 private void setAccessibilityEventTextChangedAttrs(AccessibilityEvent event,
604 int fromIndex, int addedCount, int removedCount, String beforeText, String text) {
605 event.setFromIndex(fromIndex);
606 event.setAddedCount(addedCount);
607 event.setRemovedCount(removedCount);
608 event.setBeforeText(beforeText);
609 event.getText().add(text);
613 private void setAccessibilityEventSelectionAttrs(AccessibilityEvent event,
614 int fromIndex, int addedCount, int itemCount, String text) {
615 event.setFromIndex(fromIndex);
616 event.setAddedCount(addedCount);
617 event.setItemCount(itemCount);
618 event.getText().add(text);
622 protected void setAccessibilityEventKitKatAttributes(AccessibilityEvent event,
623 boolean canOpenPopup,
624 boolean contentInvalid,
629 // Backwards compatibility for KitKat AccessibilityNodeInfo fields.
630 Bundle bundle = getOrCreateBundleForAccessibilityEvent(event);
631 bundle.putBoolean("AccessibilityNodeInfo.canOpenPopup", canOpenPopup);
632 bundle.putBoolean("AccessibilityNodeInfo.contentInvalid", contentInvalid);
633 bundle.putBoolean("AccessibilityNodeInfo.dismissable", dismissable);
634 bundle.putBoolean("AccessibilityNodeInfo.multiLine", multiLine);
635 bundle.putInt("AccessibilityNodeInfo.inputType", inputType);
636 bundle.putInt("AccessibilityNodeInfo.liveRegion", liveRegion);
640 protected void setAccessibilityEventCollectionInfo(AccessibilityEvent event,
641 int rowCount, int columnCount, boolean hierarchical) {
642 // Backwards compatibility for KitKat AccessibilityNodeInfo fields.
643 Bundle bundle = getOrCreateBundleForAccessibilityEvent(event);
644 bundle.putInt("AccessibilityNodeInfo.CollectionInfo.rowCount", rowCount);
645 bundle.putInt("AccessibilityNodeInfo.CollectionInfo.columnCount", columnCount);
646 bundle.putBoolean("AccessibilityNodeInfo.CollectionInfo.hierarchical", hierarchical);
650 protected void setAccessibilityEventCollectionItemInfo(AccessibilityEvent event,
651 int rowIndex, int rowSpan, int columnIndex, int columnSpan, boolean heading) {
652 // Backwards compatibility for KitKat AccessibilityNodeInfo fields.
653 Bundle bundle = getOrCreateBundleForAccessibilityEvent(event);
654 bundle.putInt("AccessibilityNodeInfo.CollectionItemInfo.rowIndex", rowIndex);
655 bundle.putInt("AccessibilityNodeInfo.CollectionItemInfo.rowSpan", rowSpan);
656 bundle.putInt("AccessibilityNodeInfo.CollectionItemInfo.columnIndex", columnIndex);
657 bundle.putInt("AccessibilityNodeInfo.CollectionItemInfo.columnSpan", columnSpan);
658 bundle.putBoolean("AccessibilityNodeInfo.CollectionItemInfo.heading", heading);
662 protected void setAccessibilityEventRangeInfo(AccessibilityEvent event,
663 int rangeType, float min, float max, float current) {
664 // Backwards compatibility for KitKat AccessibilityNodeInfo fields.
665 Bundle bundle = getOrCreateBundleForAccessibilityEvent(event);
666 bundle.putInt("AccessibilityNodeInfo.RangeInfo.type", rangeType);
667 bundle.putFloat("AccessibilityNodeInfo.RangeInfo.min", min);
668 bundle.putFloat("AccessibilityNodeInfo.RangeInfo.max", max);
669 bundle.putFloat("AccessibilityNodeInfo.RangeInfo.current", current);
672 private native int nativeGetRootId(long nativeBrowserAccessibilityManagerAndroid);
673 private native boolean nativeIsNodeValid(long nativeBrowserAccessibilityManagerAndroid, int id);
674 private native int nativeHitTest(long nativeBrowserAccessibilityManagerAndroid, int x, int y);
675 private native boolean nativePopulateAccessibilityNodeInfo(
676 long nativeBrowserAccessibilityManagerAndroid, AccessibilityNodeInfo info, int id);
677 private native boolean nativePopulateAccessibilityEvent(
678 long nativeBrowserAccessibilityManagerAndroid, AccessibilityEvent event, int id,
680 private native void nativeClick(long nativeBrowserAccessibilityManagerAndroid, int id);
681 private native void nativeFocus(long nativeBrowserAccessibilityManagerAndroid, int id);
682 private native void nativeBlur(long nativeBrowserAccessibilityManagerAndroid);
683 private native void nativeScrollToMakeNodeVisible(
684 long nativeBrowserAccessibilityManagerAndroid, int id);
685 private native int nativeFindElementType(long nativeBrowserAccessibilityManagerAndroid,
686 int startId, String elementType, boolean forwards);