Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2a0157b90002e9f7367530770488644399b89f03 |
| --- /dev/null |
| +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java |
| @@ -0,0 +1,531 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.content.browser.accessibility; |
| + |
| +import android.content.Context; |
| +import android.graphics.Rect; |
| +import android.os.Bundle; |
| +import android.view.MotionEvent; |
| +import android.view.View; |
| +import android.view.accessibility.AccessibilityEvent; |
| +import android.view.accessibility.AccessibilityManager; |
| +import android.view.accessibility.AccessibilityNodeInfo; |
| +import android.view.accessibility.AccessibilityNodeProvider; |
| +import android.view.inputmethod.InputMethodManager; |
| + |
| +import org.chromium.base.CalledByNative; |
| +import org.chromium.base.JNINamespace; |
| +import org.chromium.content.browser.ContentViewCore; |
| +import org.chromium.content.browser.RenderCoordinates; |
| + |
| +import java.util.ArrayList; |
| +import java.util.List; |
| + |
| +/** |
| + * Native accessibility for a {@link ContentViewCore}. |
| + */ |
| +@JNINamespace("content") |
| +public class BrowserAccessibilityManager extends AccessibilityNodeProvider { |
| + private static final String TAG = BrowserAccessibilityManager.class.getSimpleName(); |
| + |
| + private ContentViewCore mContentViewCore; |
| + private AccessibilityManager mAccessibilityManager; |
| + private RenderCoordinates mRenderCoordinates; |
| + private int mNativeObj; |
| + private int mAccessibilityFocusId; |
| + private final int[] mTempLocation = new int[2]; |
| + private View mView; |
| + private boolean mUserHasTouchExplored; |
| + private boolean mFrameInfoInitialized; |
| + |
| + // If this is true, enables an experimental feature that focuses the web page after it |
| + // finishes loading. Disabled for now because it can be confusing if the user was |
| + // trying to do something when this happens. |
| + private boolean mFocusPageOnLoad; |
| + |
| + /** |
| + * Create a BrowserAccessibilityManager object, which is owned by the C++ |
| + * BrowserAccessibilityManagerAndroid instance, and connects to the content view. |
| + * @param nativeBrowserAccessibilityManagerAndroid A pointer to the counterpart native |
| + * C++ object that owns this object. |
| + * @param contentViewCore The content view that this object provides accessibility for. |
| + */ |
| + @CalledByNative |
| + private static BrowserAccessibilityManager create(int nativeBrowserAccessibilityManagerAndroid, |
| + ContentViewCore contentViewCore) { |
| + return new BrowserAccessibilityManager( |
| + nativeBrowserAccessibilityManagerAndroid, contentViewCore); |
| + } |
| + |
| + private BrowserAccessibilityManager(int nativeBrowserAccessibilityManagerAndroid, |
| + ContentViewCore contentViewCore) { |
| + mNativeObj = nativeBrowserAccessibilityManagerAndroid; |
| + mContentViewCore = contentViewCore; |
| + mContentViewCore.setBrowserAccessibilityManager(this); |
| + mAccessibilityFocusId = View.NO_ID; |
| + mView = mContentViewCore.getContainerView(); |
| + mRenderCoordinates = mContentViewCore.getRenderCoordinates(); |
| + mAccessibilityManager = |
| + (AccessibilityManager) mContentViewCore.getContext() |
| + .getSystemService(Context.ACCESSIBILITY_SERVICE); |
| + } |
| + |
| + @CalledByNative |
| + private void onNativeObjectDestroyed() { |
| + if (mContentViewCore.getBrowserAccessibilityManager() == this) { |
| + mContentViewCore.setBrowserAccessibilityManager(null); |
| + } |
| + mNativeObj = 0; |
| + mContentViewCore = null; |
| + } |
| + |
| + /** @inheritDoc */ |
|
bulach
2013/06/20 09:18:42
nit: maybe @Override ?
dmazzoni
2013/06/21 05:38:55
Done.
|
| + public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { |
| + if (!mAccessibilityManager.isEnabled() || mNativeObj == 0 || !mFrameInfoInitialized) { |
| + return null; |
| + } |
| + |
| + int rootId = nativeGetRootId(mNativeObj); |
| + if (virtualViewId == View.NO_ID) { |
| + virtualViewId = rootId; |
| + } |
| + if (mAccessibilityFocusId == View.NO_ID) { |
| + mAccessibilityFocusId = rootId; |
| + } |
| + |
| + final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(mView); |
| + info.setPackageName(mContentViewCore.getContext().getPackageName()); |
| + info.setSource(mView, virtualViewId); |
| + |
| + if (nativePopulateAccessibilityNodeInfo(mNativeObj, info, virtualViewId)) |
| + return info; |
|
David Trainor- moved to gerrit
2013/06/20 16:57:11
{} {}
dmazzoni
2013/06/21 05:38:55
Done.
|
| + else |
| + return null; |
| + |
| + /*** |
|
bulach
2013/06/20 09:18:42
subtle :)
please remove this whole block.
dmazzoni
2013/06/21 05:38:55
Oops!
|
| + |
| + int nativeNode = nativeGetNativeNodeById(mNativeObj, virtualViewId); |
| + if (nativeNode == 0) { |
| + return null; |
| + } |
| + |
| + info.setClassName(BrowserAccessibility.nativeGetClassNameJNI(nativeNode)); |
| + info.setCheckable(BrowserAccessibility.nativeIsCheckableJNI(nativeNode)); |
| + info.setChecked(BrowserAccessibility.nativeIsCheckedJNI(nativeNode)); |
| + info.setEnabled(BrowserAccessibility.nativeIsEnabledJNI(nativeNode)); |
| + info.setFocused(BrowserAccessibility.nativeIsFocusedJNI(nativeNode)); |
| + info.setPassword(BrowserAccessibility.nativeIsPasswordJNI(nativeNode)); |
| + info.setScrollable(BrowserAccessibility.nativeIsScrollableJNI(nativeNode)); |
| + info.setSelected(BrowserAccessibility.nativeIsSelectedJNI(nativeNode)); |
| + info.setVisibleToUser(BrowserAccessibility.nativeIsVisibleJNI(nativeNode)); |
| + info.setContentDescription(BrowserAccessibility.nativeGetNameJNI(nativeNode)); |
| + |
| + boolean focusable = BrowserAccessibility.nativeIsFocusableJNI(nativeNode); |
| + info.setFocusable(focusable); |
| + if (focusable) { |
| + if (BrowserAccessibility.nativeIsFocusedJNI(nativeNode)) |
| + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS); |
| + else |
| + info.addAction(AccessibilityNodeInfo.ACTION_FOCUS); |
| + } |
| + |
| + if (mAccessibilityFocusId == virtualViewId) { |
| + info.setAccessibilityFocused(true); |
| + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); |
| + } else { |
| + info.setAccessibilityFocused(false); |
| + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); |
| + } |
| + |
| + boolean clickable = BrowserAccessibility.nativeGetClickableJNI(nativeNode); |
| + if (clickable) |
| + info.addAction(AccessibilityNodeInfo.ACTION_CLICK); |
| + |
| + int childCount = BrowserAccessibility.nativeGetChildCountJNI(nativeNode); |
| + for (int i = 0; i < childCount; i++) |
| + info.addChild(mView, BrowserAccessibility.nativeGetChildIdAtJNI(nativeNode, i)); |
| + |
| + |
| + if (virtualViewId != rootId) |
| + info.setParent(mView, BrowserAccessibility.nativeGetParentJNI(nativeNode)); |
| + |
| + Rect boundsInParent = (Rect) BrowserAccessibility.nativeGetRectInParentJNI(nativeNode); |
| + if (virtualViewId == rootId) { |
| + // Offset of the web content relative to the View. |
| + boundsInParent.offset(0, (int) mRenderCoordinates.getContentOffsetYPix()); |
| + } |
| + info.setBoundsInParent(boundsInParent); |
| + Rect rect = (Rect) BrowserAccessibility.nativeGetAbsoluteRectJNI(nativeNode); |
| + |
| + // Offset by the scroll position. |
| + rect.offset(-(int) mRenderCoordinates.getScrollX(), |
| + -(int) mRenderCoordinates.getScrollY()); |
| + |
| + // Convert CSS (web) pixels to Android View pixels |
| + rect.left = (int) mRenderCoordinates.fromLocalCssToPix(rect.left); |
| + rect.top = (int) mRenderCoordinates.fromLocalCssToPix(rect.top); |
| + rect.bottom = (int) mRenderCoordinates.fromLocalCssToPix(rect.bottom); |
| + rect.right = (int) mRenderCoordinates.fromLocalCssToPix(rect.right); |
| + |
| + // Offset by the location of the web content within the view. |
| + rect.offset(0, |
| + (int) mRenderCoordinates.getContentOffsetYPix()); |
| + |
| + // Additionally offset by the location of the view within the screen. |
| + final int[] viewLocation = new int[2]; |
| + mView.getLocationOnScreen(viewLocation); |
| + rect.offset(viewLocation[0], viewLocation[1]); |
| + info.setBoundsInScreen(rect); |
| + |
| + return info; |
| + ***/ |
| + } |
| + |
| + /** @inheritDoc */ |
| + public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text, |
| + int virtualViewId) { |
| + return new ArrayList<AccessibilityNodeInfo>(); |
| + } |
| + |
| + /** @inheritDoc */ |
| + public boolean performAction(int virtualViewId, int action, Bundle arguments) { |
| + if (!mAccessibilityManager.isEnabled() || mNativeObj == 0) { |
| + return false; |
| + } |
| + |
| + switch (action) { |
| + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: |
| + if (mAccessibilityFocusId == virtualViewId) { |
| + return true; |
| + } |
| + |
| + if (mAccessibilityFocusId != View.NO_ID) { |
| + sendAccessibilityEvent(mAccessibilityFocusId, |
| + AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); |
| + } |
| + mAccessibilityFocusId = virtualViewId; |
| + sendAccessibilityEvent(mAccessibilityFocusId, |
| + AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); |
| + return true; |
| + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: |
| + if (mAccessibilityFocusId == virtualViewId) { |
| + mAccessibilityFocusId = View.NO_ID; |
| + } |
| + return true; |
| + case AccessibilityNodeInfo.ACTION_CLICK: |
| + nativeClick(mNativeObj, virtualViewId); |
| + break; |
| + case AccessibilityNodeInfo.ACTION_FOCUS: |
| + nativeFocus(mNativeObj, virtualViewId); |
| + break; |
| + case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: |
| + nativeFocus(mNativeObj, nativeGetRootId(mNativeObj)); |
|
bulach
2013/06/20 09:18:42
nit: maybe better to have a "nativeClearFocus(mNat
dmazzoni
2013/06/21 05:38:55
Good idea, done - I'll call it nativeBlur to match
|
| + break; |
| + default: |
| + break; |
| + } |
| + return false; |
| + } |
| + |
| + /** |
| + * @see View#dispatchHoverEvent(MotionEvent) |
| + */ |
| + public boolean dispatchHoverEvent(MotionEvent event) { |
| + if (!mAccessibilityManager.isEnabled() || mNativeObj == 0) { |
| + return false; |
| + } |
| + |
| + mUserHasTouchExplored = true; |
| + float x = event.getX(); |
| + float y = event.getY(); |
| + |
| + // Offset by the location of the web content within the view. |
| + // Note: the MotionEvent has view-relative coordinates already, |
| + // so we don't have to offset by the view relative to the screen. |
| + y -= mRenderCoordinates.getContentOffsetYPix(); |
| + |
| + // Convert to CSS coordinates. |
| + int cssX = (int) (mRenderCoordinates.fromPixToLocalCss(x) + |
| + mRenderCoordinates.getScrollX()); |
| + int cssY = (int) (mRenderCoordinates.fromPixToLocalCss(y) + |
| + mRenderCoordinates.getScrollY()); |
| + int id = nativeHitTest(mNativeObj, cssX, cssY); |
| + if (mAccessibilityFocusId != id) { |
| + mAccessibilityFocusId = id; |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
| + } |
| + |
| + return true; |
| + } |
| + |
| + /** |
| + * Called by ContentViewCore to notify us when the frame info is initialized, |
| + * the first time, since until that point, we can't use mRenderCoordinates to transform |
| + * web coordinates to screen coordinates. |
| + */ |
| + public void notifyFrameInfoInitialized() { |
| + if (mFrameInfoInitialized) return; |
| + |
| + mFrameInfoInitialized = true; |
| + // (Re-) focus focused element, since we weren't able to create an |
| + // AccessibilityNodeInfo for this element before. |
| + if (mAccessibilityFocusId != View.NO_ID) { |
| + sendAccessibilityEvent(mAccessibilityFocusId, |
| + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
| + } |
| + } |
| + |
| + private void sendAccessibilityEvent(int virtualViewId, int eventType) { |
| + if (!mAccessibilityManager.isEnabled() || mNativeObj == 0) return; |
| + |
| + final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); |
| + event.setPackageName(mContentViewCore.getContext().getPackageName()); |
| + int rootId = nativeGetRootId(mNativeObj); |
| + if (virtualViewId == rootId) { |
| + virtualViewId = View.NO_ID; |
| + } |
| + event.setSource(mView, virtualViewId); |
| + if (!nativePopulateAccessibilityEvent(mNativeObj, event, virtualViewId, eventType)) return; |
| + |
| + /** |
|
bulach
2013/06/20 09:18:42
nuke it from orbit, it's the only way to be sure.
dmazzoni
2013/06/21 05:38:55
Done.
|
| + event.setClassName(BrowserAccessibility.nativeGetClassNameJNI(nativeNode)); |
| + event.setChecked(BrowserAccessibility.nativeIsCheckedJNI(nativeNode)); |
| + event.setEnabled(BrowserAccessibility.nativeIsEnabledJNI(nativeNode)); |
| + event.setPassword(BrowserAccessibility.nativeIsPasswordJNI(nativeNode)); |
| + event.setScrollable(BrowserAccessibility.nativeIsScrollableJNI(nativeNode)); |
| + event.setCurrentItemIndex(BrowserAccessibility.nativeGetItemIndexJNI(nativeNode)); |
| + event.setItemCount(BrowserAccessibility.nativeGetItemCountJNI(nativeNode)); |
| + event.setScrollX(BrowserAccessibility.nativeGetScrollXJNI(nativeNode)); |
| + event.setScrollY(BrowserAccessibility.nativeGetScrollYJNI(nativeNode)); |
| + event.setMaxScrollX(BrowserAccessibility.nativeGetScrollXJNI(nativeNode)); |
| + event.setMaxScrollY(BrowserAccessibility.nativeGetScrollYJNI(nativeNode)); |
| + |
| + switch (eventType) { |
| + case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: |
| + event.setFromIndex( |
| + BrowserAccessibility.nativeGetTextChangeFromIndexJNI(nativeNode)); |
| + event.setAddedCount( |
| + BrowserAccessibility.nativeGetTextChangeAddedCountJNI(nativeNode)); |
| + event.setRemovedCount( |
| + BrowserAccessibility.nativeGetTextChangeRemovedCountJNI(nativeNode)); |
| + event.setBeforeText( |
| + BrowserAccessibility.nativeGetTextChangeBeforeTextJNI(nativeNode)); |
| + event.getText().add(BrowserAccessibility.nativeGetNameJNI(nativeNode)); |
| + break; |
| + case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: |
| + event.setFromIndex(BrowserAccessibility.nativeGetSelectionStartJNI(nativeNode)); |
| + event.setToIndex(BrowserAccessibility.nativeGetSelectionEndJNI(nativeNode)); |
| + event.setItemCount(BrowserAccessibility.nativeGetEditableTextLengthJNI(nativeNode)); |
| + event.getText().add(BrowserAccessibility.nativeGetNameJNI(nativeNode)); |
| + break; |
| + default: |
| + break; |
| + } |
| + **/ |
| + |
| + // This is currently needed if we want Android to draw the yellow box around |
| + // the item that has accessibility focus. In practice, this doesn't seem to slow |
| + // things down, because it's only called when the accessibility focus moves. |
| + // TODO(dmazzoni): remove this if/when Android framework fixes bug. |
|
bulach
2013/06/20 09:18:42
there was some discussions about "postInvalidate()
David Trainor- moved to gerrit
2013/06/20 16:57:11
That is probably correct. Also just to make sure,
dmazzoni
2013/06/21 05:38:55
I'll try it with postInvalidate but leave the TODO
|
| + mContentViewCore.getContainerView().invalidate(); |
| + |
| + mContentViewCore.getContainerView().requestSendAccessibilityEvent(mView, event); |
| + } |
| + |
| + @CalledByNative |
| + private void handlePageLoaded(int id) { |
| + if (mUserHasTouchExplored) return; |
| + |
| + if (mFocusPageOnLoad) { |
| + // Focus the natively focused node (usually document), |
| + // if this feature is enabled. |
| + mAccessibilityFocusId = id; |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_FOCUSED); |
| + } |
| + } |
| + |
| + @CalledByNative |
| + private void handleFocusChanged(int id) { |
| + if (mAccessibilityFocusId == id) return; |
| + |
| + mAccessibilityFocusId = id; |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_FOCUSED); |
| + } |
| + |
| + @CalledByNative |
| + private void handleCheckStateChanged(int id) { |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_CLICKED); |
| + } |
| + |
| + @CalledByNative |
| + private void handleTextSelectionChanged(int id) { |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED); |
| + } |
| + |
| + @CalledByNative |
| + private void handleEditableTextChanged(int id) { |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); |
| + } |
| + |
| + @CalledByNative |
| + private void handleContentChanged(int id) { |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); |
| + } |
| + |
| + @CalledByNative |
| + private void handleNavigate() { |
| + mAccessibilityFocusId = View.NO_ID; |
| + mUserHasTouchExplored = false; |
| + mFrameInfoInitialized = false; |
| + } |
| + |
| + @CalledByNative |
| + private void handleScrolledToAnchor(int id) { |
| + if (mAccessibilityFocusId == id) { |
| + return; |
| + } |
| + |
| + mAccessibilityFocusId = id; |
| + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
| + } |
| + |
| + @CalledByNative |
| + private void announceLiveRegionText(String text) { |
| + mView.announceForAccessibility(text); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityNodeInfoParent(AccessibilityNodeInfo node, int parentId) { |
| + node.setParent(mView, parentId); |
| + } |
| + |
| + @CalledByNative |
| + private void addAccessibilityNodeInfoChild(AccessibilityNodeInfo node, int child_id) { |
| + node.addChild(mView, child_id); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfo node, |
| + boolean checkable, boolean checked, boolean clickable, |
| + boolean enabled, boolean focusable, boolean focused, boolean password, |
| + boolean scrollable, boolean selected, boolean visibleToUser) { |
| + node.setCheckable(checkable); |
| + node.setChecked(checked); |
| + node.setClickable(clickable); |
| + node.setEnabled(enabled); |
| + node.setFocusable(focusable); |
| + node.setFocused(focused); |
| + node.setPassword(password); |
| + node.setScrollable(scrollable); |
| + node.setSelected(selected); |
| + node.setVisibleToUser(visibleToUser); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityNodeInfoStringAttributes(AccessibilityNodeInfo node, |
| + String className, String contentDescription) { |
| + node.setClassName(className); |
| + node.setContentDescription(contentDescription); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityNodeInfoLocation(AccessibilityNodeInfo node, |
| + int absoluteLeft, int absoluteTop, int parentRelativeLeft, int parentRelativeTop, |
| + int width, int height, boolean isRootNode) { |
| + // First set the bounds in parent. |
| + Rect boundsInParent = new Rect(parentRelativeLeft, parentRelativeTop, |
| + parentRelativeLeft + width, parentRelativeTop + height); |
| + if (isRootNode) { |
| + // Offset of the web content relative to the View. |
| + boundsInParent.offset(0, (int) mRenderCoordinates.getContentOffsetYPix()); |
| + } |
| + node.setBoundsInParent(boundsInParent); |
| + |
| + // Now set the absolute rect, which requires several transformations. |
| + Rect rect = new Rect(absoluteLeft, absoluteTop, absoluteLeft + width, absoluteTop + height); |
| + |
| + // Offset by the scroll position. |
| + rect.offset(-(int) mRenderCoordinates.getScrollX(), |
| + -(int) mRenderCoordinates.getScrollY()); |
| + |
| + // Convert CSS (web) pixels to Android View pixels |
| + rect.left = (int) mRenderCoordinates.fromLocalCssToPix(rect.left); |
| + rect.top = (int) mRenderCoordinates.fromLocalCssToPix(rect.top); |
| + rect.bottom = (int) mRenderCoordinates.fromLocalCssToPix(rect.bottom); |
| + rect.right = (int) mRenderCoordinates.fromLocalCssToPix(rect.right); |
| + |
| + // Offset by the location of the web content within the view. |
| + rect.offset(0, |
| + (int) mRenderCoordinates.getContentOffsetYPix()); |
| + |
| + // Finally offset by the location of the view within the screen. |
| + final int[] viewLocation = new int[2]; |
| + mView.getLocationOnScreen(viewLocation); |
| + rect.offset(viewLocation[0], viewLocation[1]); |
| + |
| + node.setBoundsInScreen(rect); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityEventBooleanAttributes(AccessibilityEvent event, |
| + boolean checked, boolean enabled, boolean password, boolean scrollable) { |
| + event.setChecked(checked); |
| + event.setEnabled(enabled); |
| + event.setPassword(password); |
| + event.setScrollable(scrollable); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityEventClassName(AccessibilityEvent event, String className) { |
| + event.setClassName(className); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityEventListAttributes(AccessibilityEvent event, |
| + int currentItemIndex, int itemCount) { |
| + event.setCurrentItemIndex(currentItemIndex); |
| + event.setItemCount(itemCount); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityEventScrollAttributes(AccessibilityEvent event, |
| + int scrollX, int scrollY, int maxScrollX, int maxScrollY) { |
| + event.setScrollX(scrollX); |
| + event.setScrollY(scrollY); |
| + event.setMaxScrollX(maxScrollX); |
| + event.setMaxScrollY(maxScrollY); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityEventTextChangedAttrs(AccessibilityEvent event, |
| + int fromIndex, int addedCount, int removedCount, String beforeText, String text) { |
| + event.setFromIndex(fromIndex); |
| + event.setAddedCount(addedCount); |
| + event.setRemovedCount(removedCount); |
| + event.setBeforeText(beforeText); |
| + event.getText().add(text); |
| + } |
| + |
| + @CalledByNative |
| + private void setAccessibilityEventSelectionAttrs(AccessibilityEvent event, |
| + int fromIndex, int addedCount, int itemCount, String text) { |
| + event.setFromIndex(fromIndex); |
| + event.setAddedCount(addedCount); |
| + event.setItemCount(itemCount); |
| + event.getText().add(text); |
| + } |
| + |
| + private native int nativeGetRootId(int nativeBrowserAccessibilityManagerAndroid); |
| + private native int nativeHitTest(int nativeBrowserAccessibilityManagerAndroid, int x, int y); |
| + private native boolean nativePopulateAccessibilityNodeInfo( |
| + int nativeBrowserAccessibilityManagerAndroid, AccessibilityNodeInfo info, int id); |
| + private native boolean nativePopulateAccessibilityEvent( |
| + int nativeBrowserAccessibilityManagerAndroid, AccessibilityEvent event, int id, |
| + int eventType); |
| + private native void nativeClick(int nativeBrowserAccessibilityManagerAndroid, int id); |
| + private native void nativeFocus(int nativeBrowserAccessibilityManagerAndroid, int id); |
| +} |