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..edc8246d70c7c3b8825b8b1aff2ffeeb15602d50 |
--- /dev/null |
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java |
@@ -0,0 +1,394 @@ |
+// 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.accessibilityservice.AccessibilityServiceInfo; |
+import android.content.Context; |
+import android.graphics.Rect; |
+import android.os.Build; |
+import android.os.Bundle; |
+import android.os.Vibrator; |
+import android.provider.Settings; |
+import android.speech.tts.TextToSpeech; |
+import android.util.Log; |
+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 RenderCoordinates mRenderCoordinates; |
+ private int mNativeObj; |
+ private int mA11yFocusId; |
+ private final int[] mTempLocation = new int[2]; |
+ private View mView; |
+ private boolean mUserHasTouchExplored = false; |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Don't need "= false;"
dmazzoni
2013/06/07 20:23:16
Done.
|
+ private boolean mFrameInfoInitialized = false; |
+ private boolean mWebFocusFollowsA11yFocus = false; |
+ |
+ @CalledByNative |
+ public static BrowserAccessibilityManager create(int nativeBrowserAccessibilityManagerAndroid, |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Javadoc or make private
dmazzoni
2013/06/07 20:23:16
Done.
|
+ ContentViewCore contentViewCore) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Java function format just indents by 8 on the next
dmazzoni
2013/06/07 20:23:16
Done.
|
+ Log.i("AX", "BrowserAccessibilityManager java create"); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Remove?
dmazzoni
2013/06/07 20:23:16
Done.
|
+ return new BrowserAccessibilityManager( |
+ nativeBrowserAccessibilityManagerAndroid, contentViewCore); |
+ } |
+ |
+ BrowserAccessibilityManager(int nativeBrowserAccessibilityManagerAndroid, |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Javadoc or just make private
dmazzoni
2013/06/07 20:23:16
Done.
|
+ ContentViewCore contentViewCore) { |
+ mNativeObj = nativeBrowserAccessibilityManagerAndroid; |
+ mContentViewCore = contentViewCore; |
+ mContentViewCore.setBrowserAccessibilityManager(this); |
+ mA11yFocusId = View.NO_ID; |
+ mView = mContentViewCore.getContainerView(); |
+ mRenderCoordinates = mContentViewCore.getRenderCoordinates(); |
+ } |
+ |
+ @CalledByNative |
+ private void onNativeObjectDestroyed() { |
+ Log.i("AX", "BrowserAccessibilityManager onNativeObjectDestroyed"); |
+ if (mContentViewCore.getBrowserAccessibilityManager() == this) |
+ mContentViewCore.setBrowserAccessibilityManager(null); |
+ mNativeObj = 0; |
+ mContentViewCore = null; |
+ } |
+ |
+ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Javadoc
dmazzoni
2013/06/07 20:23:16
This one is an interface implementation - I'm assu
|
+ int rootId = nativeGetRootId(mNativeObj); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Check if mNativeObj == 0 before using it everywher
dmazzoni
2013/06/07 20:23:16
Done.
|
+ if (virtualViewId == View.NO_ID) |
+ virtualViewId = rootId; |
David Trainor- moved to gerrit
2013/06/04 20:27:18
{ } around this and all one line if statements.
dmazzoni
2013/06/07 20:23:16
Fixed throughout.
|
+ if (mA11yFocusId == View.NO_ID) |
+ mA11yFocusId = rootId; |
+ |
+ int nativeNode = nativeGetNativeNodeById(mNativeObj, virtualViewId); |
+ if (nativeNode == 0) |
+ return null; |
+ if (!mFrameInfoInitialized) |
+ return null; |
+ |
+ final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(mView); |
+ info.setPackageName(mContentViewCore.getContext().getPackageName()); |
+ info.setClassName(BrowserAccessibility.nativeGetClassNameJNI(nativeNode)); |
+ |
+ info.setSource(mView, virtualViewId); |
+ Rect boundsInParent = (Rect)BrowserAccessibility.nativeGetRectInParentJNI(nativeNode); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
space after (Rect)
dmazzoni
2013/06/07 20:23:16
Done.
|
+ if (virtualViewId == rootId) { |
+ // Offset of the web content relative to the View. |
+ boundsInParent.offset(0, (int)mRenderCoordinates.getContentOffsetYPix()); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
space after (int)
dmazzoni
2013/06/07 20:23:16
Done.
|
+ } |
+ info.setBoundsInParent(boundsInParent); |
+ Rect rect = (Rect)BrowserAccessibility.nativeGetAbsoluteRectJNI(nativeNode); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Space after (Rect)
dmazzoni
2013/06/07 20:23:16
Done.
|
+ |
+ // Offset by the scroll position. |
+ rect.offset(-(int)mRenderCoordinates.getScrollX(), |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Space after (int) for all of this.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ -(int)mRenderCoordinates.getScrollY()); |
+ |
+ // Convert CSS (web) pixels to Android View pixels |
+ rect.left = (int)mRenderCoordinates.fromLocalCssToPix(rect.left); // TODO: from float |
+ 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); |
+ info.setContentDescription(BrowserAccessibility.nativeGetNameJNI(nativeNode)); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Maybe group all of these initial set* parameters i
dmazzoni
2013/06/07 20:23:16
Good idea.
|
+ info.setEnabled(true); |
+ info.setVisibleToUser(true); |
+ if (virtualViewId != rootId) |
+ info.setParent(mView, BrowserAccessibility.nativeGetParentJNI(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); |
+ } |
+ |
+ int childCount = BrowserAccessibility.nativeGetChildCountJNI(nativeNode); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Move this down below near the for loop.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ |
+ if (mA11yFocusId == 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); |
+ |
+ for (int i = 0; i < childCount; i++) |
+ info.addChild(mView, BrowserAccessibility.nativeGetChildIdAtJNI(nativeNode, i)); |
+ |
+ 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)); |
+ |
+ return info; |
+ } |
+ |
+ public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text, |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Javadoc
dmazzoni
2013/06/07 20:23:16
Done.
|
+ int virtualViewId) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Just indent by 8.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ return new ArrayList<AccessibilityNodeInfo>(); |
+ } |
+ |
+ public boolean dispatchHoverEvent(MotionEvent event) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Javadoc
dmazzoni
2013/06/07 20:23:16
Done.
|
+ mUserHasTouchExplored = true; |
+ float x = event.getX(); |
+ float y = event.getY(); |
+ // Note: the MotionEvent seems to have view-relative coordinates already. |
+ // Offset by the location of the web content within the view. |
+ y -= mRenderCoordinates.getContentOffsetYPix(); |
+ // Convert to CSS coordinates. |
+ int cssX = (int)(mRenderCoordinates.fromPixToLocalCss(x) + mRenderCoordinates.getScrollX()); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
space after (int)
dmazzoni
2013/06/07 20:23:16
Done.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ int cssY = (int)(mRenderCoordinates.fromPixToLocalCss(y) + mRenderCoordinates.getScrollY()); |
+ int id = nativeHitTest(mNativeObj, cssX, cssY); |
+ int nativeNode = nativeGetNativeNodeById(mNativeObj, id); |
+ if (nativeNode == 0) |
+ return false; |
+ |
+ if (mA11yFocusId != id) { |
+ mA11yFocusId = id; |
+ sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
+ } |
+ |
+ // If this is a hover end event, web-focus the element and pop up the keyboard |
+ // if necessary. TODO: figure out what happens when there's an ACTION_HOVER_EXIT |
David Trainor- moved to gerrit
2013/06/04 20:27:18
format of todo's:
// TODO(dmazzoni): ...
dmazzoni
2013/06/07 20:23:16
Done.
|
+ // because touch exploration exited the ContentViewCore. |
+ if (event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) |
+ focusAndHideOrShowKeyboardIfNecessary(id); |
+ return true; |
+ } |
+ |
+ public void focusAndHideOrShowKeyboardIfNecessary(int virtualViewId) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Javadoc. I'm also surprised the keyboard doesn't
dmazzoni
2013/06/07 20:23:16
I think it does show normally - auto-hiding was th
|
+ if (!mWebFocusFollowsA11yFocus) |
+ return; |
+ |
+ int nativeNode = nativeGetNativeNodeById(mNativeObj, virtualViewId); |
+ if (nativeNode == 0) |
+ return; |
+ |
+ InputMethodManager imm = |
+ (InputMethodManager)mContentViewCore.getContext().getSystemService( |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Space after (InputMethodManager). Indent +8 inste
dmazzoni
2013/06/07 20:23:16
Done.
|
+ Context.INPUT_METHOD_SERVICE); |
+ if (!BrowserAccessibility.nativeIsFocusableJNI(nativeNode)) { |
+ imm.hideSoftInputFromWindow(mView.getWindowToken(), |
+ InputMethodManager.HIDE_IMPLICIT_ONLY); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Just indent +8 instead of lining this up. Same fo
dmazzoni
2013/06/07 20:23:16
Done.
|
+ return; |
+ } |
+ |
+ if (BrowserAccessibility.nativeIsFocusedJNI(nativeNode)) |
+ return; |
+ |
+ BrowserAccessibility.nativeFocusJNI(nativeNode); |
+ sendAccessibilityEvent(virtualViewId, |
+ AccessibilityEvent.TYPE_VIEW_FOCUSED); |
+ // Show/hide keyboard |
+ if (BrowserAccessibility.nativeIsEditableTextJNI(nativeNode)) { |
+ imm.showSoftInput(mView, InputMethodManager.SHOW_IMPLICIT); |
+ } else { |
+ imm.hideSoftInputFromWindow(mView.getWindowToken(), |
+ InputMethodManager.HIDE_IMPLICIT_ONLY); |
+ } |
+ } |
+ |
+ public boolean performAction(int virtualViewId, int action, Bundle arguments) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
javadoc
dmazzoni
2013/06/07 20:23:16
Done.
|
+ int rootId = nativeGetRootId(mNativeObj); |
+ int nativeRootNode = nativeGetNativeNodeById(mNativeObj, rootId); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Can you just have a nativeGetRootNode()? Would sa
dmazzoni
2013/06/07 20:23:16
Is there any way we could do this and avoid it hav
|
+ int nativeNode = nativeGetNativeNodeById(mNativeObj, virtualViewId); |
+ if (nativeNode == 0 || nativeRootNode == 0) |
+ return false; |
+ |
+ String nodeName = BrowserAccessibility.nativeGetNameJNI(nativeNode); |
+ |
+ switch (action) { |
+ case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Fix switch statement indent.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ if (mA11yFocusId == virtualViewId) |
+ return true; |
+ mA11yFocusId = virtualViewId; |
+ focusAndHideOrShowKeyboardIfNecessary(virtualViewId); |
+ sendAccessibilityEvent(virtualViewId, |
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
+ return true; |
+ case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: |
+ if (mA11yFocusId == virtualViewId) |
+ mA11yFocusId = View.NO_ID; |
+ /* sendAccessibilityEvent(virtualViewId, |
David Trainor- moved to gerrit
2013/06/04 20:27:18
?
dmazzoni
2013/06/07 20:23:16
Done.
|
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); */ |
+ return true; |
+ case AccessibilityNodeInfo.ACTION_CLICK: |
+ BrowserAccessibility.nativeClickJNI(nativeNode); |
+ break; |
+ case AccessibilityNodeInfo.ACTION_FOCUS: |
+ BrowserAccessibility.nativeFocusJNI(nativeNode); |
+ break; |
+ case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: |
+ BrowserAccessibility.nativeFocusJNI(nativeRootNode); |
+ break; |
+ } |
+ return false; |
+ } |
+ |
+ private void sendAccessibilityEvent(int virtualViewId, int eventType) { |
+ int nativeNode = nativeGetNativeNodeById(mNativeObj, virtualViewId); |
+ if (nativeNode == 0) |
+ return; |
+ |
+ final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); |
+ event.setPackageName(mContentViewCore.getContext().getPackageName()); |
+ event.setClassName(BrowserAccessibility.nativeGetClassNameJNI(nativeNode)); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
This is going to be expensive :(.
dmazzoni
2013/06/07 20:23:16
Surprisingly it's okay in practice.
Probably the
|
+ 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)); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
indent +4 more.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ 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; |
+ } |
+ |
+ int rootId = nativeGetRootId(mNativeObj); |
+ if (virtualViewId == rootId) |
+ virtualViewId = View.NO_ID; |
+ event.setSource(mView, virtualViewId); |
+ |
+ mContentViewCore.getContainerView().invalidate(); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Why do we need to invalidate here?
dmazzoni
2013/06/07 20:23:16
I added a comment. It's a workaround for a known A
|
+ mContentViewCore.getContainerView().requestSendAccessibilityEvent( |
+ mView, event); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
+4 indent, should fit on line above though.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ } |
+ |
+ public void notifyFrameInfoInitialized() { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
javadoc
dmazzoni
2013/06/07 20:23:16
Done.
|
+ if (mFrameInfoInitialized) |
+ return; |
David Trainor- moved to gerrit
2013/06/04 20:27:18
put return on same line as if if it fits, etc.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ |
+ mFrameInfoInitialized = true; |
+ // (re-) focus focused element, since it didn't have correct coordinates before |
+ if (mA11yFocusId != View.NO_ID) |
+ sendAccessibilityEvent(mA11yFocusId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Line too long.
dmazzoni
2013/06/07 20:23:16
Done.
|
+ } |
+ |
+ @CalledByNative |
+ private void handlePageLoaded(int id) { |
+ if (mUserHasTouchExplored) |
+ return; |
+ |
+ // Otherwise, focus the natively focused node (usually document). |
+ mA11yFocusId = id; |
+ sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
David Trainor- moved to gerrit
2013/06/04 20:27:18
Will this drag focus from anywhere else in the app
dmazzoni
2013/06/07 20:23:16
Currently yes. We think this is usually good - but
|
+ } |
+ |
+ @CalledByNative |
+ private void handleFocusChanged(int id) { |
+ if (mA11yFocusId == id) |
+ return; |
+ mA11yFocusId = id; |
+ sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
benm (inactive)
2013/06/04 13:13:12
This seems to be called despite accessibility bein
David Trainor- moved to gerrit
2013/06/04 20:27:18
Also does focusChanged mean focused?
On 2013/06/0
dmazzoni
2013/06/07 20:23:16
sendAccessibilityEvent now checks.
dmazzoni
2013/06/07 20:23:16
It means that page focus changed to the node at th
|
+ } |
+ |
+ @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() { |
+ mA11yFocusId = View.NO_ID; |
+ mUserHasTouchExplored = false; |
+ mFrameInfoInitialized = false; |
+ } |
+ |
+ @CalledByNative |
+ private void handleScrolledToAnchor(int id) { |
+ if (mA11yFocusId == id) |
+ return; |
+ mA11yFocusId = id; |
+ sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); |
+ } |
+ |
+ @CalledByNative |
+ private void announceObjectShow(int id, boolean force_assertive) { |
David Trainor- moved to gerrit
2013/06/04 20:27:18
forceAssertive
dmazzoni
2013/06/07 20:23:16
Done.
|
+ int nativeNode = nativeGetNativeNodeById(mNativeObj, id); |
+ String nodeName = BrowserAccessibility.nativeGetNameJNI(nativeNode); |
+ boolean assertive = force_assertive; |
+ if (!force_assertive) { |
+ String ariaLive = BrowserAccessibility.nativeGetAriaLiveJNI(nativeNode); |
+ assertive = ariaLive == "assertive"; |
+ } |
+ // TODO(aboxhall): handle assertive once supported by framework |
+ mView.announceForAccessibility(nodeName); |
+ } |
+ |
+ private native int nativeGetRootId(int nativeBrowserAccessibilityManagerAndroid); |
+ private native int nativeHitTest(int nativeBrowserAccessibilityManagerAndroid, int x, int y); |
+ private native int nativeGetNativeNodeById( |
+ int nativeBrowserAccessibilityManagerAndroid, int id); |
+} |