summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java15
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_android.cc50
-rw-r--r--content/browser/accessibility/browser_accessibility_android.cc384
-rw-r--r--content/browser/accessibility/browser_accessibility_android.h89
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.cc210
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.h13
-rw-r--r--content/browser/android/browser_jni_registrar.cc4
-rw-r--r--content/browser/android/content_view_core_impl.cc14
-rw-r--r--content/browser/android/content_view_core_impl.h1
-rw-r--r--content/content_jni.gypi1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentView.java19
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java172
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java35
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java419
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java1
15 files changed, 398 insertions, 1029 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index c451d68..d7f3727 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -26,7 +26,6 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.webkit.GeolocationPermissions;
@@ -1131,13 +1130,6 @@ public class AwContents {
}
/**
- * @see android.view.View#dispatchHoverEvent()
- */
- public boolean dispatchHoverEvent(MotionEvent event) {
- return mContentViewCore.dispatchHoverEvent(event);
- }
-
- /**
* @see android.view.View#onConfigurationChanged()
*/
public void onConfigurationChanged(Configuration newConfig) {
@@ -1303,13 +1295,6 @@ public class AwContents {
}
/**
- * @see View#getAccessibilityNodeProvider()
- */
- public AccessibilityNodeProvider getAccessibilityNodeProvider() {
- return mContentViewCore.getAccessibilityNodeProvider();
- }
-
- /**
* @see android.webkit.WebView#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
*/
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
diff --git a/content/browser/accessibility/accessibility_tree_formatter_android.cc b/content/browser/accessibility/accessibility_tree_formatter_android.cc
index 11f4be6..cc1a852 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_android.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -52,36 +52,54 @@ void AccessibilityTreeFormatter::AddProperties(
const BrowserAccessibility& node, DictionaryValue* dict) {
const BrowserAccessibilityAndroid* android_node =
static_cast<const BrowserAccessibilityAndroid*>(&node);
+ JNIEnv* env = base::android::AttachCurrentThread();
// Class name.
- dict->SetString("class", android_node->GetClassName());
+ dict->SetString("class", base::android::ConvertJavaStringToUTF8(
+ android_node->GetClassNameJNI(env, NULL)));
// Bool attributes.
- dict->SetBoolean("focusable", android_node->IsFocusable());
- dict->SetBoolean("focused", android_node->IsFocused());
- dict->SetBoolean("clickable", android_node->IsClickable());
- dict->SetBoolean("editable_text", android_node->IsEditableText());
- dict->SetBoolean("checkable", android_node->IsCheckable());
- dict->SetBoolean("checked", android_node->IsChecked());
- dict->SetBoolean("disabled", !android_node->IsEnabled());
- dict->SetBoolean("scrollable", android_node->IsScrollable());
- dict->SetBoolean("password", android_node->IsPassword());
- dict->SetBoolean("selected", android_node->IsSelected());
- dict->SetBoolean("invisible", !android_node->IsVisibleToUser());
+ dict->SetBoolean("focusable",
+ android_node->IsFocusableJNI(env, NULL));
+ dict->SetBoolean("focused",
+ android_node->IsFocusedJNI(env, NULL));
+ dict->SetBoolean("clickable",
+ android_node->GetClickableJNI(env, NULL));
+ dict->SetBoolean("editable_text",
+ android_node->IsEditableTextJNI(env, NULL));
+ dict->SetBoolean("checkable",
+ android_node->IsCheckableJNI(env, NULL));
+ dict->SetBoolean("checked",
+ android_node->IsCheckedJNI(env, NULL));
+ dict->SetBoolean("disabled",
+ !android_node->IsEnabledJNI(env, NULL));
+ dict->SetBoolean("scrollable",
+ android_node->IsScrollableJNI(env, NULL));
+ dict->SetBoolean("password",
+ android_node->IsPasswordJNI(env, NULL));
+ dict->SetBoolean("selected",
+ android_node->IsSelectedJNI(env, NULL));
+ dict->SetBoolean("invisible",
+ !android_node->IsVisibleJNI(env, NULL));
// String attributes.
- dict->SetString("name", android_node->GetText());
+ dict->SetString("name", base::android::ConvertJavaStringToUTF8(
+ android_node->GetNameJNI(env, NULL)));
// Int attributes.
- dict->SetInteger("item_index", android_node->GetItemIndex());
- dict->SetInteger("item_count", android_node->GetItemCount());
+ dict->SetInteger("item_index",
+ android_node->GetItemIndexJNI(env, NULL));
+ dict->SetInteger("item_count",
+ android_node->GetItemCountJNI(env, NULL));
}
bool AccessibilityTreeFormatter::IncludeChildren(
const BrowserAccessibility& node) {
const BrowserAccessibilityAndroid* android_node =
static_cast<const BrowserAccessibilityAndroid*>(&node);
- return !android_node->IsLeaf();
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ return 0 != android_node->GetChildCountJNI(env, NULL);
}
string16 AccessibilityTreeFormatter::ToString(const DictionaryValue& dict,
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 8ff37ec..2f1ab2d 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -4,11 +4,17 @@
#include "content/browser/accessibility/browser_accessibility_android.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/common/accessibility_messages.h"
#include "content/common/accessibility_node_data.h"
+using base::android::ScopedJavaLocalRef;
+
namespace content {
// static
@@ -24,95 +30,101 @@ bool BrowserAccessibilityAndroid::IsNative() const {
return true;
}
-bool BrowserAccessibilityAndroid::IsLeaf() const {
- if (child_count() == 0)
- return true;
+//
+// Actions, called from Java.
+//
- // Iframes are always allowed to contain children.
- if (IsIframe() ||
- role() == AccessibilityNodeData::ROLE_ROOT_WEB_AREA ||
- role() == AccessibilityNodeData::ROLE_WEB_AREA) {
- return false;
- }
+void BrowserAccessibilityAndroid::FocusJNI(JNIEnv* env, jobject obj) {
+ manager_->SetFocus(this, true);
+}
- // If it has a focusable child, we definitely can't leave out children.
- if (HasFocusableChild())
- return false;
+void BrowserAccessibilityAndroid::ClickJNI(JNIEnv* env, jobject obj) {
+ manager_->DoDefaultAction(*this);
+}
- // Headings with text can drop their children.
- string16 name = GetText();
- if (role() == AccessibilityNodeData::ROLE_HEADING && !name.empty())
- return true;
+//
+// Const accessors, called from Java.
+//
- // Focusable nodes with text can drop their children.
- if (HasState(AccessibilityNodeData::STATE_FOCUSABLE) && !name.empty())
- return true;
+ScopedJavaLocalRef<jstring>
+BrowserAccessibilityAndroid::GetNameJNI(JNIEnv* env, jobject obj) const {
+ return base::android::ConvertUTF16ToJavaString(env, ComputeName());
+}
- // Nodes with only static text as children can drop their children.
- if (HasOnlyStaticTextChildren())
- return true;
+ScopedJavaLocalRef<jobject>
+BrowserAccessibilityAndroid::GetAbsoluteRectJNI(
+ JNIEnv* env, jobject obj) const {
+ gfx::Rect rect = GetLocalBoundsRect();
- return false;
+ // TODO(aboxhall): replace with non-stub implementation
+ return ScopedJavaLocalRef<jobject>(env, NULL);
}
-bool BrowserAccessibilityAndroid::IsCheckable() const {
- bool checkable = false;
- bool is_aria_pressed_defined;
- bool is_mixed;
- GetAriaTristate("aria-pressed", &is_aria_pressed_defined, &is_mixed);
- if (role() == AccessibilityNodeData::ROLE_CHECKBOX ||
- role() == AccessibilityNodeData::ROLE_RADIO_BUTTON ||
- is_aria_pressed_defined) {
- checkable = true;
+ScopedJavaLocalRef<jobject>
+BrowserAccessibilityAndroid::GetRectInParentJNI(
+ JNIEnv* env, jobject obj) const {
+ gfx::Rect rect = GetLocalBoundsRect();
+ if (parent()) {
+ gfx::Rect parent_rect = parent()->GetLocalBoundsRect();
+ rect.Offset(-parent_rect.OffsetFromOrigin());
}
- if (HasState(AccessibilityNodeData::STATE_CHECKED))
- checkable = true;
- return checkable;
-}
-bool BrowserAccessibilityAndroid::IsChecked() const {
- return HasState(AccessibilityNodeData::STATE_CHECKED);
+ // TODO(aboxhall): replace with non-stub implementation
+ return ScopedJavaLocalRef<jobject>(env, NULL);
}
-bool BrowserAccessibilityAndroid::IsClickable() const {
- return (IsLeaf() && !GetText().empty());
+jboolean
+BrowserAccessibilityAndroid::IsFocusableJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jboolean>(IsFocusable());
}
-bool BrowserAccessibilityAndroid::IsEnabled() const {
- return !HasState(AccessibilityNodeData::STATE_UNAVAILABLE);
+jboolean
+BrowserAccessibilityAndroid::IsEditableTextJNI(JNIEnv* env, jobject obj) const {
+ return IsEditableText();
}
-bool BrowserAccessibilityAndroid::IsFocusable() const {
- bool focusable = HasState(AccessibilityNodeData::STATE_FOCUSABLE);
- if (IsIframe() ||
- role() == AccessibilityNodeData::ROLE_WEB_AREA) {
- focusable = false;
- }
- return focusable;
-}
-
-bool BrowserAccessibilityAndroid::IsFocused() const {
- return manager()->GetFocus(manager()->GetRoot()) == this;
+jint BrowserAccessibilityAndroid::GetParentJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jint>(parent()->renderer_id());
}
-bool BrowserAccessibilityAndroid::IsPassword() const {
- return HasState(AccessibilityNodeData::STATE_PROTECTED);
+jint
+BrowserAccessibilityAndroid::GetChildCountJNI(JNIEnv* env, jobject obj) const {
+ if (IsLeaf())
+ return 0;
+ else
+ return static_cast<jint>(child_count());
}
-bool BrowserAccessibilityAndroid::IsScrollable() const {
- int dummy;
- return GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X_MAX, &dummy);
+jint BrowserAccessibilityAndroid::GetChildIdAtJNI(JNIEnv* env,
+ jobject obj,
+ jint child_index) const {
+ return static_cast<jint>(GetChild(child_index)->renderer_id());
}
-bool BrowserAccessibilityAndroid::IsSelected() const {
- return HasState(AccessibilityNodeData::STATE_SELECTED);
+jboolean
+BrowserAccessibilityAndroid::IsCheckableJNI(JNIEnv* env, jobject obj) const {
+ bool checkable = false;
+ bool is_aria_pressed_defined;
+ bool is_mixed;
+ GetAriaTristate("aria-pressed", &is_aria_pressed_defined, &is_mixed);
+ if (role() == AccessibilityNodeData::ROLE_CHECKBOX ||
+ role() == AccessibilityNodeData::ROLE_RADIO_BUTTON ||
+ is_aria_pressed_defined) {
+ checkable = true;
+ }
+ if (HasState(AccessibilityNodeData::STATE_CHECKED))
+ checkable = true;
+ return static_cast<jboolean>(checkable);
}
-bool BrowserAccessibilityAndroid::IsVisibleToUser() const {
- return !HasState(AccessibilityNodeData::STATE_INVISIBLE);
+jboolean
+BrowserAccessibilityAndroid::IsCheckedJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jboolean>(
+ HasState(AccessibilityNodeData::STATE_CHECKED));
}
-const char* BrowserAccessibilityAndroid::GetClassName() const {
+base::android::ScopedJavaLocalRef<jstring>
+BrowserAccessibilityAndroid::GetClassNameJNI(JNIEnv* env, jobject obj) const {
const char* class_name = NULL;
switch(role()) {
@@ -165,52 +177,53 @@ const char* BrowserAccessibilityAndroid::GetClassName() const {
break;
}
- return class_name;
+ return base::android::ConvertUTF8ToJavaString(env, class_name);
}
-string16 BrowserAccessibilityAndroid::GetText() const {
- if (IsIframe() ||
- role() == AccessibilityNodeData::ROLE_WEB_AREA) {
- return string16();
- }
+jboolean
+BrowserAccessibilityAndroid::IsEnabledJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jboolean>(
+ !HasState(AccessibilityNodeData::STATE_UNAVAILABLE));
+}
- string16 description;
- GetStringAttribute(AccessibilityNodeData::ATTR_DESCRIPTION, &description);
+jboolean
+BrowserAccessibilityAndroid::IsFocusedJNI(JNIEnv* env, jobject obj) const {
+ return manager()->GetFocus(manager()->GetRoot()) == this;
+}
- string16 text;
- if (!name().empty())
- text = name();
- else if (!description.empty())
- text = description;
- else if (!value().empty())
- text = value();
+jboolean
+BrowserAccessibilityAndroid::IsPasswordJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jboolean>(
+ HasState(AccessibilityNodeData::STATE_PROTECTED));
+}
- if (text.empty() && HasOnlyStaticTextChildren()) {
- for (uint32 i = 0; i < child_count(); i++) {
- BrowserAccessibility* child = GetChild(i);
- text += static_cast<BrowserAccessibilityAndroid*>(child)->GetText();
- }
- }
+jboolean
+BrowserAccessibilityAndroid::IsScrollableJNI(JNIEnv* env, jobject obj) const {
+ int dummy;
+ bool scrollable = GetIntAttribute(
+ AccessibilityNodeData::ATTR_SCROLL_X_MAX, &dummy);
+ return static_cast<jboolean>(scrollable);
+}
- switch(role()) {
- case AccessibilityNodeData::ROLE_IMAGE_MAP_LINK:
- case AccessibilityNodeData::ROLE_LINK:
- case AccessibilityNodeData::ROLE_WEBCORE_LINK:
- if (!text.empty())
- text += ASCIIToUTF16(" ");
- text += ASCIIToUTF16("Link");
- break;
- case AccessibilityNodeData::ROLE_HEADING:
- // Only append "heading" if this node already has text.
- if (!text.empty())
- text += ASCIIToUTF16(" Heading");
- break;
- }
+jboolean
+BrowserAccessibilityAndroid::IsSelectedJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jboolean>(
+ HasState(AccessibilityNodeData::STATE_SELECTED));
+}
- return text;
+jboolean
+BrowserAccessibilityAndroid::IsVisibleJNI(JNIEnv* env, jobject obj) const {
+ return static_cast<jboolean>(
+ !HasState(AccessibilityNodeData::STATE_INVISIBLE));
+}
+
+base::android::ScopedJavaLocalRef<jstring>
+BrowserAccessibilityAndroid::GetAriaLiveJNI(JNIEnv* env, jobject obj) const {
+ return base::android::ConvertUTF16ToJavaString(env, GetAriaLive());
}
-int BrowserAccessibilityAndroid::GetItemIndex() const {
+jint BrowserAccessibilityAndroid::GetItemIndexJNI(
+ JNIEnv* env, jobject obj) const {
int index = 0;
switch(role()) {
case AccessibilityNodeData::ROLE_LIST_ITEM:
@@ -227,10 +240,11 @@ int BrowserAccessibilityAndroid::GetItemIndex() const {
break;
}
}
- return index;
+ return static_cast<jint>(index);
}
-int BrowserAccessibilityAndroid::GetItemCount() const {
+jint
+BrowserAccessibilityAndroid::GetItemCountJNI(JNIEnv* env, jobject obj) const {
int count = 0;
switch(role()) {
case AccessibilityNodeData::ROLE_LIST:
@@ -247,34 +261,63 @@ int BrowserAccessibilityAndroid::GetItemCount() const {
break;
}
}
- return count;
+ return static_cast<jint>(count);
}
-int BrowserAccessibilityAndroid::GetScrollX() const {
+jint
+BrowserAccessibilityAndroid::GetScrollXJNI(JNIEnv* env, jobject obj) const {
int value = 0;
GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X, &value);
- return value;
+ return static_cast<jint>(value);
}
-int BrowserAccessibilityAndroid::GetScrollY() const {
+jint
+BrowserAccessibilityAndroid::GetScrollYJNI(JNIEnv* env, jobject obj) const {
int value = 0;
GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_Y, &value);
- return value;
+ return static_cast<jint>(value);
}
-int BrowserAccessibilityAndroid::GetMaxScrollX() const {
+jint
+BrowserAccessibilityAndroid::GetMaxScrollXJNI(JNIEnv* env, jobject obj) const {
int value = 0;
GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X_MAX, &value);
- return value;
+ return static_cast<jint>(value);
}
-int BrowserAccessibilityAndroid::GetMaxScrollY() const {
+jint
+BrowserAccessibilityAndroid::GetMaxScrollYJNI(JNIEnv* env, jobject obj) const {
int value = 0;
GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_Y_MAX, &value);
- return value;
+ return static_cast<jint>(value);
+}
+
+jboolean
+BrowserAccessibilityAndroid::GetClickableJNI(JNIEnv* env, jobject obj) const {
+ return (IsLeaf() && !ComputeName().empty());
+}
+
+jint BrowserAccessibilityAndroid::GetSelectionStartJNI(JNIEnv* env, jobject obj)
+ const {
+ int sel_start = 0;
+ GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_START, &sel_start);
+ return sel_start;
+}
+
+jint BrowserAccessibilityAndroid::GetSelectionEndJNI(JNIEnv* env, jobject obj)
+ const {
+ int sel_end = 0;
+ GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_END, &sel_end);
+ return sel_end;
+}
+
+jint BrowserAccessibilityAndroid::GetEditableTextLengthJNI(
+ JNIEnv* env, jobject obj) const {
+ return value().length();
}
-int BrowserAccessibilityAndroid::GetTextChangeFromIndex() const {
+int BrowserAccessibilityAndroid::GetTextChangeFromIndexJNI(
+ JNIEnv* env, jobject obj) const {
size_t index = 0;
while (index < old_value_.length() &&
index < new_value_.length() &&
@@ -284,7 +327,8 @@ int BrowserAccessibilityAndroid::GetTextChangeFromIndex() const {
return index;
}
-int BrowserAccessibilityAndroid::GetTextChangeAddedCount() const {
+jint BrowserAccessibilityAndroid::GetTextChangeAddedCountJNI(
+ JNIEnv* env, jobject obj) const {
size_t old_len = old_value_.length();
size_t new_len = new_value_.length();
size_t left = 0;
@@ -302,7 +346,8 @@ int BrowserAccessibilityAndroid::GetTextChangeAddedCount() const {
return (new_len - left - right);
}
-int BrowserAccessibilityAndroid::GetTextChangeRemovedCount() const {
+jint BrowserAccessibilityAndroid::GetTextChangeRemovedCountJNI(
+ JNIEnv* env, jobject obj) const {
size_t old_len = old_value_.length();
size_t new_len = new_value_.length();
size_t left = 0;
@@ -320,24 +365,62 @@ int BrowserAccessibilityAndroid::GetTextChangeRemovedCount() const {
return (old_len - left - right);
}
-string16 BrowserAccessibilityAndroid::GetTextChangeBeforeText() const {
- return old_value_;
+base::android::ScopedJavaLocalRef<jstring>
+BrowserAccessibilityAndroid::GetTextChangeBeforeTextJNI(
+ JNIEnv* env, jobject obj) const {
+ return base::android::ConvertUTF16ToJavaString(env, old_value_);
}
-int BrowserAccessibilityAndroid::GetSelectionStart() const {
- int sel_start = 0;
- GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_START, &sel_start);
- return sel_start;
-}
+string16 BrowserAccessibilityAndroid::ComputeName() const {
+ if (IsIframe() ||
+ role() == AccessibilityNodeData::ROLE_WEB_AREA) {
+ return string16();
+ }
-int BrowserAccessibilityAndroid::GetSelectionEnd() const {
- int sel_end = 0;
- GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_END, &sel_end);
- return sel_end;
+ string16 description;
+ GetStringAttribute(AccessibilityNodeData::ATTR_DESCRIPTION,
+ &description);
+
+ string16 text;
+ if (!name().empty())
+ text = name();
+ else if (!description.empty())
+ text = description;
+ else if (!value().empty())
+ text = value();
+
+ if (text.empty() && HasOnlyStaticTextChildren()) {
+ for (uint32 i = 0; i < child_count(); i++) {
+ BrowserAccessibility* child = GetChild(i);
+ text += static_cast<BrowserAccessibilityAndroid*>(child)->ComputeName();
+ }
+ }
+
+ switch(role()) {
+ case AccessibilityNodeData::ROLE_IMAGE_MAP_LINK:
+ case AccessibilityNodeData::ROLE_LINK:
+ case AccessibilityNodeData::ROLE_WEBCORE_LINK:
+ if (!text.empty())
+ text += ASCIIToUTF16(" ");
+ text += ASCIIToUTF16("Link");
+ break;
+ case AccessibilityNodeData::ROLE_HEADING:
+ // Only append "heading" if this node already has text.
+ if (!text.empty())
+ text += ASCIIToUTF16(" Heading");
+ break;
+ }
+
+ return text;
}
-int BrowserAccessibilityAndroid::GetEditableTextLength() const {
- return value().length();
+string16 BrowserAccessibilityAndroid::GetAriaLive() const {
+ string16 aria_live;
+ if (GetStringAttribute(AccessibilityNodeData::ATTR_CONTAINER_LIVE_STATUS,
+ &aria_live)) {
+ return aria_live;
+ }
+ return string16();
}
bool BrowserAccessibilityAndroid::HasFocusableChild() const {
@@ -366,6 +449,46 @@ bool BrowserAccessibilityAndroid::IsIframe() const {
return html_tag == ASCIIToUTF16("iframe");
}
+bool BrowserAccessibilityAndroid::IsFocusable() const {
+ bool focusable = HasState(AccessibilityNodeData::STATE_FOCUSABLE);
+ if (IsIframe() ||
+ role() == AccessibilityNodeData::ROLE_WEB_AREA) {
+ focusable = false;
+ }
+ return focusable;
+}
+
+bool BrowserAccessibilityAndroid::IsLeaf() const {
+ if (child_count() == 0)
+ return true;
+
+ // Iframes are always allowed to contain children.
+ if (IsIframe() ||
+ role() == AccessibilityNodeData::ROLE_ROOT_WEB_AREA ||
+ role() == AccessibilityNodeData::ROLE_WEB_AREA) {
+ return false;
+ }
+
+ // If it has a focusable child, we definitely can't leave out children.
+ if (HasFocusableChild())
+ return false;
+
+ // Headings with text can drop their children.
+ string16 name = ComputeName();
+ if (role() == AccessibilityNodeData::ROLE_HEADING && !name.empty())
+ return true;
+
+ // Focusable nodes with text can drop their children.
+ if (HasState(AccessibilityNodeData::STATE_FOCUSABLE) && !name.empty())
+ return true;
+
+ // Nodes with only static text as children can drop their children.
+ if (HasOnlyStaticTextChildren())
+ return true;
+
+ return false;
+}
+
void BrowserAccessibilityAndroid::PostInitialize() {
BrowserAccessibility::PostInitialize();
@@ -393,7 +516,7 @@ void BrowserAccessibilityAndroid::NotifyLiveRegionUpdate(string16& aria_live) {
!EqualsASCII(aria_live, aria_strings::kAriaLiveAssertive))
return;
- string16 text = GetText();
+ string16 text = ComputeName();
if (cached_text_ != text) {
if (!text.empty()) {
manager_->NotifyAccessibilityEvent(AccessibilityNotificationObjectShow,
@@ -403,4 +526,9 @@ void BrowserAccessibilityAndroid::NotifyLiveRegionUpdate(string16& aria_live) {
}
}
+bool RegisterBrowserAccessibility(JNIEnv* env) {
+ // TODO(aboxhall): replace with non-stub implementation
+ return false;
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h
index 8b4ed84..2de8c75 100644
--- a/content/browser/accessibility/browser_accessibility_android.h
+++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -16,48 +16,71 @@ class BrowserAccessibilityAndroid : public BrowserAccessibility {
virtual void PostInitialize() OVERRIDE;
virtual bool IsNative() const OVERRIDE;
- bool IsLeaf() const;
-
- bool IsCheckable() const;
- bool IsChecked() const;
- bool IsClickable() const;
- bool IsEnabled() const;
- bool IsFocusable() const;
- bool IsFocused() const;
- bool IsPassword() const;
- bool IsScrollable() const;
- bool IsSelected() const;
- bool IsVisibleToUser() const;
-
- const char* GetClassName() const;
- string16 GetText() const;
-
- int GetItemIndex() const;
- int GetItemCount() const;
-
- int GetScrollX() const;
- int GetScrollY() const;
- int GetMaxScrollX() const;
- int GetMaxScrollY() const;
-
- int GetTextChangeFromIndex() const;
- int GetTextChangeAddedCount() const;
- int GetTextChangeRemovedCount() const;
- string16 GetTextChangeBeforeText() const;
-
- int GetSelectionStart() const;
- int GetSelectionEnd() const;
- int GetEditableTextLength() const;
+ // --------------------------------------------------------------------------
+ // Methods called from Java via JNI
+ // --------------------------------------------------------------------------
+
+ // Actions
+ void FocusJNI(JNIEnv* env, jobject obj);
+ void ClickJNI(JNIEnv* env, jobject obj);
+
+ // Const accessors
+ jboolean GetClickableJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsFocusedJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsEditableTextJNI(JNIEnv* env, jobject obj) const;
+ base::android::ScopedJavaLocalRef<jstring> GetNameJNI(
+ JNIEnv* env, jobject obj) const;
+ base::android::ScopedJavaLocalRef<jobject> GetAbsoluteRectJNI(
+ JNIEnv* env, jobject obj) const;
+ base::android::ScopedJavaLocalRef<jobject> GetRectInParentJNI(
+ JNIEnv* env, jobject obj) const;
+ jboolean IsFocusableJNI(JNIEnv* env, jobject obj) const;
+ jint GetParentJNI(JNIEnv* env, jobject obj) const;
+ jint GetChildCountJNI(JNIEnv* env, jobject obj) const;
+ jint GetChildIdAtJNI(
+ JNIEnv* env, jobject obj, jint child_index) const;
+ jboolean IsCheckableJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsCheckedJNI(JNIEnv* env, jobject obj) const;
+ base::android::ScopedJavaLocalRef<jstring> GetClassNameJNI(
+ JNIEnv* env, jobject obj) const;
+ jboolean IsEnabledJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsPasswordJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsScrollableJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsSelectedJNI(JNIEnv* env, jobject obj) const;
+ jboolean IsVisibleJNI(JNIEnv* env, jobject obj) const;
+ jint GetItemIndexJNI(JNIEnv* env, jobject obj) const;
+ jint GetItemCountJNI(JNIEnv* env, jobject obj) const;
+ jint GetScrollXJNI(JNIEnv* env, jobject obj) const;
+ jint GetScrollYJNI(JNIEnv* env, jobject obj) const;
+ jint GetMaxScrollXJNI(JNIEnv* env, jobject obj) const;
+ jint GetMaxScrollYJNI(JNIEnv* env, jobject obj) const;
+ base::android::ScopedJavaLocalRef<jstring> GetAriaLiveJNI(
+ JNIEnv* env, jobject obj) const;
+ jint GetSelectionStartJNI(JNIEnv* env, jobject obj) const;
+ jint GetSelectionEndJNI(JNIEnv* env, jobject obj) const;
+ jint GetEditableTextLengthJNI(JNIEnv* env, jobject obj) const;
+ jint GetTextChangeFromIndexJNI(JNIEnv* env, jobject obj) const;
+ jint GetTextChangeAddedCountJNI(JNIEnv* env, jobject obj) const;
+ jint GetTextChangeRemovedCountJNI(JNIEnv* env, jobject obj) const;
+ base::android::ScopedJavaLocalRef<jstring> GetTextChangeBeforeTextJNI(
+ JNIEnv* env, jobject obj) const;
private:
// This gives BrowserAccessibility::Create access to the class constructor.
friend class BrowserAccessibility;
+ // Allow BrowserAccessibilityManagerAndroid to call these private methods.
+ friend class BrowserAccessibilityManagerAndroid;
+
BrowserAccessibilityAndroid();
+ string16 ComputeName() const;
+ string16 GetAriaLive() const;
+ bool IsFocusable() const;
bool HasFocusableChild() const;
bool HasOnlyStaticTextChildren() const;
bool IsIframe() const;
+ bool IsLeaf() const;
void NotifyLiveRegionUpdate(string16& aria_live);
@@ -69,6 +92,8 @@ class BrowserAccessibilityAndroid : public BrowserAccessibility {
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityAndroid);
};
+bool RegisterBrowserAccessibility(JNIEnv* env);
+
} // namespace content
#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_ANDROID_H_
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 112ffdb..861375c 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -13,19 +13,12 @@
#include "base/values.h"
#include "content/browser/accessibility/browser_accessibility_android.h"
#include "content/common/accessibility_messages.h"
-#include "jni/BrowserAccessibilityManager_jni.h"
using base::android::AttachCurrentThread;
using base::android::ScopedJavaLocalRef;
namespace {
-// These are enums from android.view.accessibility.AccessibilityEvent in Java:
-enum {
- ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_CHANGED = 16,
- ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192
-};
-
// Restricts |val| to the range [min, max].
int Clamp(int val, int min, int max) {
return std::min(std::max(val, min), max);
@@ -58,19 +51,16 @@ BrowserAccessibilityManagerAndroid::BrowserAccessibilityManagerAndroid(
if (content_view_core.is_null())
return;
- JNIEnv* env = AttachCurrentThread();
- java_ref_ = JavaObjectWeakGlobalRef(
- env, Java_BrowserAccessibilityManager_create(
- env, reinterpret_cast<jint>(this), content_view_core.obj()).obj());
+ // TODO(aboxhall): set up Java references
}
BrowserAccessibilityManagerAndroid::~BrowserAccessibilityManagerAndroid() {
- JNIEnv* env = AttachCurrentThread();
+ JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
return;
- Java_BrowserAccessibilityManager_onNativeObjectDestroyed(env, obj.obj());
+ // TODO(aboxhall): tear down Java references
}
// static
@@ -85,62 +75,13 @@ AccessibilityNodeData BrowserAccessibilityManagerAndroid::GetEmptyDocument() {
void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
int type,
BrowserAccessibility* node) {
- JNIEnv* env = AttachCurrentThread();
+ JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
return;
- switch (type) {
- case AccessibilityNotificationLoadComplete:
- Java_BrowserAccessibilityManager_handlePageLoaded(
- env, obj.obj(), focus_->renderer_id());
- break;
- case AccessibilityNotificationFocusChanged:
- Java_BrowserAccessibilityManager_handleFocusChanged(
- env, obj.obj(), node->renderer_id());
- break;
- case AccessibilityNotificationCheckStateChanged:
- Java_BrowserAccessibilityManager_handleCheckStateChanged(
- env, obj.obj(), node->renderer_id());
- break;
- case AccessibilityNotificationScrolledToAnchor:
- Java_BrowserAccessibilityManager_handleScrolledToAnchor(
- env, obj.obj(), node->renderer_id());
- break;
- case AccessibilityNotificationAlert:
- // An alert is a special case of live region. Fall through to the
- // next case to handle it.
- case AccessibilityNotificationObjectShow: {
- // This event is fired when an object appears in a live region.
- // Speak its text.
- BrowserAccessibilityAndroid* android_node =
- static_cast<BrowserAccessibilityAndroid*>(node);
- Java_BrowserAccessibilityManager_announceLiveRegionText(
- env, obj.obj(),
- base::android::ConvertUTF16ToJavaString(
- env, android_node->GetText()).obj());
- break;
- }
- case AccessibilityNotificationSelectedTextChanged:
- Java_BrowserAccessibilityManager_handleTextSelectionChanged(
- env, obj.obj(), node->renderer_id());
- break;
- case AccessibilityNotificationChildrenChanged:
- case AccessibilityNotificationTextChanged:
- case AccessibilityNotificationValueChanged:
- if (node->IsEditableText()) {
- Java_BrowserAccessibilityManager_handleEditableTextChanged(
- env, obj.obj(), node->renderer_id());
- } else {
- Java_BrowserAccessibilityManager_handleContentChanged(
- env, obj.obj(), node->renderer_id());
- }
- break;
- default:
- // There are some notifications that aren't meaningful on Android.
- // It's okay to skip them.
- break;
- }
+ // TODO(aboxhall): call into appropriate Java method for each type of
+ // notification
}
jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) {
@@ -168,128 +109,6 @@ jint BrowserAccessibilityManagerAndroid::HitTest(
return root_->renderer_id();
}
-jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo(
- JNIEnv* env, jobject obj, jobject info, jint id) {
- BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
- GetFromRendererID(id));
- if (!node)
- return false;
-
- if (node->parent()) {
- Java_BrowserAccessibilityManager_setAccessibilityNodeInfoParent(
- env, obj, info, node->parent()->renderer_id());
- }
- if (!node->IsLeaf()) {
- for (unsigned i = 0; i < node->child_count(); ++i) {
- Java_BrowserAccessibilityManager_addAccessibilityNodeInfoChild(
- env, obj, info, node->children()[i]->renderer_id());
- }
- }
- Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes(
- env, obj, info,
- node->IsCheckable(),
- node->IsChecked(),
- node->IsClickable(),
- node->IsEnabled(),
- node->IsFocusable(),
- node->IsFocused(),
- node->IsPassword(),
- node->IsScrollable(),
- node->IsSelected(),
- node->IsVisibleToUser());
- Java_BrowserAccessibilityManager_setAccessibilityNodeInfoStringAttributes(
- env, obj, info,
- base::android::ConvertUTF8ToJavaString(env, node->GetClassName()).obj(),
- base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj());
-
- gfx::Rect absolute_rect = node->GetLocalBoundsRect();
- gfx::Rect parent_relative_rect = absolute_rect;
- if (node->parent()) {
- gfx::Rect parent_rect = node->parent()->GetLocalBoundsRect();
- parent_relative_rect.Offset(-parent_rect.OffsetFromOrigin());
- }
- bool is_root = node->parent() == NULL;
- Java_BrowserAccessibilityManager_setAccessibilityNodeInfoLocation(
- env, obj, info,
- absolute_rect.x(), absolute_rect.y(),
- parent_relative_rect.x(), parent_relative_rect.y(),
- absolute_rect.width(), absolute_rect.height(),
- is_root);
-
- return true;
-}
-
-jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityEvent(
- JNIEnv* env, jobject obj, jobject event, jint id, jint event_type) {
- BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>(
- GetFromRendererID(id));
- if (!node)
- return false;
-
- Java_BrowserAccessibilityManager_setAccessibilityEventBooleanAttributes(
- env, obj, event,
- node->IsChecked(),
- node->IsEnabled(),
- node->IsPassword(),
- node->IsScrollable());
- Java_BrowserAccessibilityManager_setAccessibilityEventClassName(
- env, obj, event,
- base::android::ConvertUTF8ToJavaString(env, node->GetClassName()).obj());
- Java_BrowserAccessibilityManager_setAccessibilityEventListAttributes(
- env, obj, event,
- node->GetItemIndex(),
- node->GetItemCount());
- Java_BrowserAccessibilityManager_setAccessibilityEventScrollAttributes(
- env, obj, event,
- node->GetScrollX(),
- node->GetScrollY(),
- node->GetMaxScrollX(),
- node->GetMaxScrollY());
-
- switch (event_type) {
- case ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_CHANGED:
- Java_BrowserAccessibilityManager_setAccessibilityEventTextChangedAttrs(
- env, obj, event,
- node->GetTextChangeFromIndex(),
- node->GetTextChangeAddedCount(),
- node->GetTextChangeRemovedCount(),
- base::android::ConvertUTF16ToJavaString(
- env, node->GetTextChangeBeforeText()).obj(),
- base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj());
- break;
- case ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_SELECTION_CHANGED:
- Java_BrowserAccessibilityManager_setAccessibilityEventSelectionAttrs(
- env, obj, event,
- node->GetSelectionStart(),
- node->GetSelectionEnd(),
- node->GetEditableTextLength(),
- base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj());
- break;
- default:
- break;
- }
-
- return true;
-}
-
-void BrowserAccessibilityManagerAndroid::Click(
- JNIEnv* env, jobject obj, jint id) {
- BrowserAccessibility* node = GetFromRendererID(id);
- if (node)
- DoDefaultAction(*node);
-}
-
-void BrowserAccessibilityManagerAndroid::Focus(
- JNIEnv* env, jobject obj, jint id) {
- BrowserAccessibility* node = GetFromRendererID(id);
- if (node)
- SetFocus(node, true);
-}
-
-void BrowserAccessibilityManagerAndroid::Blur(JNIEnv* env, jobject obj) {
- SetFocus(root_, true);
-}
-
BrowserAccessibility* BrowserAccessibilityManagerAndroid::FuzzyHitTest(
int x, int y, BrowserAccessibility* start_node) {
BrowserAccessibility* nearest_node = NULL;
@@ -316,7 +135,7 @@ void BrowserAccessibilityManagerAndroid::FuzzyHitTestImpl(
return;
}
- if (!node->GetText().empty()) {
+ if (!node->ComputeName().empty()) {
if (distance < *nearest_distance) {
*nearest_candidate = node;
*nearest_distance = distance;
@@ -343,13 +162,13 @@ int BrowserAccessibilityManagerAndroid::CalculateDistanceSquared(
return dx * dx + dy * dy;
}
-void BrowserAccessibilityManagerAndroid::NotifyRootChanged() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
+jint BrowserAccessibilityManagerAndroid::GetNativeNodeById(
+ JNIEnv* env, jobject obj, jint id) {
+ return reinterpret_cast<jint>(GetFromRendererID(id));
+}
- Java_BrowserAccessibilityManager_handleNavigate(env, obj.obj());
+void BrowserAccessibilityManagerAndroid::NotifyRootChanged() {
+ // TODO(aboxhall): non-stub implementation
}
bool
@@ -359,7 +178,8 @@ BrowserAccessibilityManagerAndroid::UseRootScrollOffsetsWhenComputingBounds() {
}
bool RegisterBrowserAccessibilityManager(JNIEnv* env) {
- return RegisterNativesImpl(env);
+ // TODO(aboxhall): non-stub implementation
+ return false;
}
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h
index 2a6c291..0ca04e5 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -41,16 +41,9 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
jint GetRootId(JNIEnv* env, jobject obj);
jint HitTest(JNIEnv* env, jobject obj, jint x, jint y);
- // Populate Java accessibility data structures with info about a node.
- jboolean PopulateAccessibilityNodeInfo(
- JNIEnv* env, jobject obj, jobject info, jint id);
- jboolean PopulateAccessibilityEvent(
- JNIEnv* env, jobject obj, jobject event, jint id, jint event_type);
-
- // Perform actions.
- void Click(JNIEnv* env, jobject obj, jint id);
- void Focus(JNIEnv* env, jobject obj, jint id);
- void Blur(JNIEnv* env, jobject obj);
+ // Gets a temporary pointer to a specific node, only valid in this scope.
+ // May return 0 if that node id is no longer valid.
+ jint GetNativeNodeById(JNIEnv* env, jobject obj, jint id);
protected:
virtual void NotifyRootChanged() OVERRIDE;
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index b914a9a..1cd4061 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -6,8 +6,6 @@
#include "base/android/jni_android.h"
#include "base/android/jni_registrar.h"
-#include "content/browser/accessibility/browser_accessibility_android.h"
-#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/browser/android/android_browser_process.h"
#include "content/browser/android/child_process_launcher_android.h"
#include "content/browser/android/content_settings.h"
@@ -36,8 +34,6 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
{ "AndroidLocationApiAdapter",
content::AndroidLocationApiAdapter::RegisterGeolocationService },
{ "AndroidBrowserProcess", content::RegisterAndroidBrowserProcess },
- { "BrowserAccessibilityManager",
- content::RegisterBrowserAccessibilityManager },
{ "ChildProcessLauncher", content::RegisterChildProcessLauncher },
{ "ContentSettings", content::ContentSettings::RegisterContentSettings },
{ "ContentViewRenderView",
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 6ad7c47..790cc75 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -32,7 +32,6 @@
#include "content/browser/web_contents/web_contents_view_android.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
-#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/notification_details.h"
@@ -1573,19 +1572,6 @@ void ContentViewCoreImpl::SetUseDesktopUserAgent(
}
}
-void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv* env, jobject obj,
- bool enabled) {
- RenderWidgetHostImpl* host_impl = RenderWidgetHostImpl::From(
- GetRenderWidgetHostViewAndroid()->GetRenderWidgetHost());
- if (enabled) {
- BrowserAccessibilityState::GetInstance()->EnableAccessibility();
- host_impl->SetAccessibilityMode(AccessibilityModeComplete);
- } else {
- BrowserAccessibilityState::GetInstance()->DisableAccessibility();
- host_impl->SetAccessibilityMode(AccessibilityModeOff);
- }
-}
-
// This is called for each ContentView.
jint Init(JNIEnv* env, jobject obj,
jboolean hardware_accelerated,
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index b4d796f..94bff0a 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -221,7 +221,6 @@ class ContentViewCoreImpl : public ContentViewCore,
jint player_id,
jobject jsurface);
void DetachExternalVideoSurface(JNIEnv* env, jobject obj, jint player_id);
- void SetAccessibilityEnabled(JNIEnv* env, jobject obj, bool enabled);
// --------------------------------------------------------------------------
// Public methods that call to Java via JNI
diff --git a/content/content_jni.gypi b/content/content_jni.gypi
index c9b63cb..8520269 100644
--- a/content/content_jni.gypi
+++ b/content/content_jni.gypi
@@ -11,7 +11,6 @@
'public/android/java/src/org/chromium/content/app/ChildProcessService.java',
'public/android/java/src/org/chromium/content/app/ContentMain.java',
'public/android/java/src/org/chromium/content/app/LibraryLoader.java',
- 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java',
'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java',
'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java',
'public/android/java/src/org/chromium/content/browser/ContentSettings.java',
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentView.java b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
index 9db7c3c..22f8fe8 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
@@ -17,7 +17,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.FrameLayout;
@@ -489,14 +488,6 @@ public class ContentView extends FrameLayout
return mContentViewCore.onGenericMotionEvent(event);
}
- @Override
- public boolean dispatchHoverEvent(MotionEvent event) {
- if (mContentViewCore.dispatchHoverEvent(event)) {
- return true;
- }
- return super.dispatchHoverEvent(event);
- }
-
/**
* Sets the current amount to offset incoming touch events by. This is used to handle content
* moving and not lining up properly with the android input system.
@@ -588,16 +579,6 @@ public class ContentView extends FrameLayout
}
@Override
- public AccessibilityNodeProvider getAccessibilityNodeProvider() {
- AccessibilityNodeProvider provider = mContentViewCore.getAccessibilityNodeProvider();
- if (provider != null) {
- return provider;
- } else {
- return super.getAccessibilityNodeProvider();
- }
- }
-
- @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
mContentViewCore.onInitializeAccessibilityNodeInfo(info);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 896645a..eeebf03 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -9,18 +9,14 @@ import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
-import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
import android.text.Editable;
import android.util.Log;
import android.util.Pair;
@@ -34,10 +30,7 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
@@ -51,7 +44,6 @@ import org.chromium.base.WeakContext;
import org.chromium.content.R;
import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate;
import org.chromium.content.browser.accessibility.AccessibilityInjector;
-import org.chromium.content.browser.accessibility.BrowserAccessibilityManager;
import org.chromium.content.browser.input.AdapterInputConnection;
import org.chromium.content.browser.input.HandleView;
import org.chromium.content.browser.input.ImeAdapter;
@@ -66,8 +58,6 @@ import org.chromium.ui.WindowAndroid;
import org.chromium.ui.gfx.DeviceDisplayInfo;
import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -78,9 +68,7 @@ import java.util.Map;
* being tied to the view system.
*/
@JNINamespace("content")
- public class ContentViewCore implements MotionEventDelegate,
- NavigationClient,
- AccessibilityStateChangeListener {
+public class ContentViewCore implements MotionEventDelegate, NavigationClient {
/**
* Indicates that input events are batched together and delivered just before vsync.
*/
@@ -360,12 +348,6 @@ import java.util.Map;
// The AccessibilityInjector that handles loading Accessibility scripts into the web page.
private AccessibilityInjector mAccessibilityInjector;
- // Handles native accessibility, i.e. without any script injection.
- private BrowserAccessibilityManager mBrowserAccessibilityManager;
-
- // System accessibility service.
- private final AccessibilityManager mAccessibilityManager;
-
// Temporary notification to tell onSizeChanged to focus a form element,
// because the OSK was just brought up.
private boolean mUnfocusOnNextSizeChanged = false;
@@ -387,7 +369,6 @@ import java.util.Map;
private ViewAndroid mViewAndroid;
-
/**
* Constructs a new ContentViewCore. Embedders must call initialize() after constructing
* a ContentViewCore and before using it.
@@ -407,8 +388,6 @@ import java.util.Map;
mStartHandlePoint = mRenderCoordinates.createNormalizedPoint();
mEndHandlePoint = mRenderCoordinates.createNormalizedPoint();
mInsertionHandlePoint = mRenderCoordinates.createNormalizedPoint();
- mAccessibilityManager = (AccessibilityManager)
- getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
}
/**
@@ -654,24 +633,8 @@ import java.util.Map;
mContentSettings = new ContentSettings(this, mNativeContentViewCore);
initializeContainerView(internalDispatcher, inputEventDeliveryMode);
- try {
- Field field = Settings.Secure.class.getField("ACCESSIBILITY_SCRIPT_INJECTION");
- field.setAccessible(true);
- String accessibilityScriptInjection = (String) field.get(null);
- getContext().getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(accessibilityScriptInjection),
- false,
- new ContentObserver(new Handler()) {
- public void onChange(boolean selfChange, Uri uri) {
- setAccessibilityState(mAccessibilityManager.isEnabled());
- }
- });
- } catch (Exception e) {
- Log.e("chromium", "Could not add listener for script injection preference. " +
- "Defaulting to native accessibility.\n" + e.toString());
- }
-
mAccessibilityInjector = AccessibilityInjector.newInstance(this);
+ mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
String contentDescription = "Web View";
if (R.string.accessibility_content_view == 0) {
@@ -1325,6 +1288,7 @@ import java.util.Map;
TraceEvent.begin();
hidePopupDialog();
nativeOnHide(mNativeContentViewCore);
+ setAccessibilityState(false);
TraceEvent.end();
}
@@ -1333,7 +1297,7 @@ import java.util.Map;
*/
public void onActivityResume() {
nativeOnShow(mNativeContentViewCore);
- setAccessibilityState(mAccessibilityManager.isEnabled());
+ setAccessibilityState(true);
}
/**
@@ -1341,7 +1305,7 @@ import java.util.Map;
*/
public void onShow() {
nativeOnShow(mNativeContentViewCore);
- setAccessibilityState(mAccessibilityManager.isEnabled());
+ setAccessibilityState(true);
}
/**
@@ -1349,7 +1313,7 @@ import java.util.Map;
*/
public void onHide() {
hidePopupDialog();
- setInjectedAccessibility(false);
+ setAccessibilityState(false);
nativeOnHide(mNativeContentViewCore);
}
@@ -1402,7 +1366,7 @@ import java.util.Map;
ChildProcessLauncher.bindAsHighPriority(pid);
}
}
- setAccessibilityState(mAccessibilityManager.isEnabled());
+ setAccessibilityState(true);
}
/**
@@ -1417,7 +1381,7 @@ import java.util.Map;
ChildProcessLauncher.unbindAsHighPriority(pid);
}
}
- setInjectedAccessibility(false);
+ setAccessibilityState(false);
hidePopupDialog();
mZoomControlsDelegate.dismissZoomPicker();
}
@@ -1682,23 +1646,6 @@ import java.util.Map;
}
/**
- * Any View that uses ContentViewCore should call override dispatchHoverEvent
- * and call this method first so that all hover events can be intercepted and
- * used for touch exploration if accessibility is on, and then only call the
- * inherited method if this returns false.
- *
- * @see View#dispatchHoverEvent(MotionEvent)
- */
- public boolean dispatchHoverEvent(MotionEvent event) {
- if (mBrowserAccessibilityManager != null) {
- return mBrowserAccessibilityManager.dispatchHoverEvent(event);
- } else {
- // The client view should call super.dispatchHoverEvent.
- return false;
- }
- }
-
- /**
* @see View#scrollBy(int, int)
* Currently the ContentView scrolling happens in the native side. In
* the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
@@ -2224,9 +2171,6 @@ import java.util.Map;
controlsOffsetPix, contentOffsetYPix, overdrawBottomHeightPix);
mPendingRendererFrame = true;
- if (mBrowserAccessibilityManager != null) {
- mBrowserAccessibilityManager.notifyFrameInfoInitialized();
- }
}
@SuppressWarnings("unused")
@@ -2609,11 +2553,6 @@ import java.util.Map;
getContentViewClient().onStartContentIntent(getContext(), contentUrl);
}
- @Override
- public void onAccessibilityStateChanged(boolean enabled) {
- setAccessibilityState(enabled);
- }
-
/**
* Determines whether or not this ContentViewCore can handle this accessibility action.
* @param action The action to perform.
@@ -2642,39 +2581,9 @@ import java.util.Map;
}
/**
- * Set the BrowserAccessibilityManager, used for native accessibility
- * (not script injection). This is only set when system accessibility
- * has been enabled.
- * @param manager The new BrowserAccessibilityManager.
- */
- public void setBrowserAccessibilityManager(BrowserAccessibilityManager manager) {
- mBrowserAccessibilityManager = manager;
- }
-
- /**
- * Get the BrowserAccessibilityManager, used for native accessibility
- * (not script injection). This will return null when system accessibility
- * is not enabled.
- * @return This view's BrowserAccessibilityManager.
- */
- public BrowserAccessibilityManager getBrowserAccessibilityManager() {
- return mBrowserAccessibilityManager;
- }
-
- /**
- * @see View#getAccessibilityNodeProvider(View host)
- */
- public AccessibilityNodeProvider getAccessibilityNodeProvider() {
- // Note: this is only used for native accessibility, i.e. without
- // script injection.
- return mBrowserAccessibilityManager;
- }
-
- /**
* @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
*/
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- // Note: this is only used by the script-injecting accessibility code.
mAccessibilityInjector.onInitializeAccessibilityNodeInfo(info);
}
@@ -2682,7 +2591,6 @@ import java.util.Map;
* @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
*/
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- // Note: this is only used by the script-injecting accessibility code.
event.setClassName(this.getClass().getName());
// Identify where the top-left of the screen currently points to.
@@ -2704,35 +2612,6 @@ import java.util.Map;
}
/**
- * Returns whether accessibility script injection is enabled on the device
- */
- public boolean isDeviceAccessibilityScriptInjectionEnabled() {
- try {
- if (!mContentSettings.getJavaScriptEnabled()) {
- return false;
- }
-
- int result = getContext().checkCallingOrSelfPermission(
- android.Manifest.permission.INTERNET);
- if (result != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
-
- Field field = Settings.Secure.class.getField("ACCESSIBILITY_SCRIPT_INJECTION");
- field.setAccessible(true);
- String accessibilityScriptInjection = (String) field.get(null);
-
- boolean onDeviceScriptInjectionEnabled =
- Settings.Secure.getInt(getContext().getContentResolver(),
- accessibilityScriptInjection, 0) == 1;
- return onDeviceScriptInjectionEnabled;
- } catch (NoSuchFieldException e) {
- } catch (IllegalAccessException e) {
- }
- return false;
- }
-
- /**
* Returns whether or not accessibility injection is being used.
*/
public boolean isInjectingAccessibilityScript() {
@@ -2740,38 +2619,10 @@ import java.util.Map;
}
/**
- * Turns browser accessibility on or off.
- * If |state| is |false|, this turns off both native and injected accessibility.
- * Otherwise, if accessibility script injection is enabled, this will enable the injected
- * accessibility scripts, and if it is disabled this will enable the native accessibility.
+ * Enable or disable accessibility features.
*/
public void setAccessibilityState(boolean state) {
- boolean injectedAccessibility = false;
- boolean nativeAccessibility = false;
- if (state) {
- if (isDeviceAccessibilityScriptInjectionEnabled()) {
- injectedAccessibility = true;
- } else {
- nativeAccessibility = true;
- }
- }
- setInjectedAccessibility(injectedAccessibility);
- setNativeAccessibilityState(nativeAccessibility);
- }
-
- /**
- * Enable or disable native accessibility features.
- */
- public void setNativeAccessibilityState(boolean enabled) {
- nativeSetAccessibilityEnabled(mNativeContentViewCore, enabled);
- }
-
- /**
- * Enable or disable injected accessibility features
- */
- public void setInjectedAccessibility(boolean enabled) {
- mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
- mAccessibilityInjector.setScriptEnabled(enabled);
+ mAccessibilityInjector.setScriptEnabled(state);
}
/**
@@ -3104,7 +2955,4 @@ import java.util.Map;
private native void nativeDetachExternalVideoSurface(
int nativeContentViewCoreImpl, int playerId);
-
- private native void nativeSetAccessibilityEnabled(
- int nativeContentViewCoreImpl, boolean enabled);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
index 2a85b4f..c0dcf03a 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
@@ -130,17 +130,27 @@ public class AccessibilityInjector extends WebContentsObserverAndroid {
if (!accessibilityIsAvailable()) return;
int axsParameterValue = getAxsUrlParameterValue();
- if (axsParameterValue != ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED) {
- return;
- }
-
- String js = getScreenReaderInjectingJs();
- if (mContentViewCore.isDeviceAccessibilityScriptInjectionEnabled() &&
- js != null && mContentViewCore.isAlive()) {
- addOrRemoveAccessibilityApisIfNecessary();
- mContentViewCore.evaluateJavaScript(js, null);
- mInjectedScriptEnabled = true;
- mScriptInjected = true;
+ if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED) {
+ try {
+ Field field = Settings.Secure.class.getField("ACCESSIBILITY_SCRIPT_INJECTION");
+ field.setAccessible(true);
+ String ACCESSIBILITY_SCRIPT_INJECTION = (String) field.get(null);
+
+ boolean onDeviceScriptInjectionEnabled = (Settings.Secure.getInt(
+ mContentViewCore.getContext().getContentResolver(),
+ ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
+ String js = getScreenReaderInjectingJs();
+
+ if (onDeviceScriptInjectionEnabled && js != null && mContentViewCore.isAlive()) {
+ addOrRemoveAccessibilityApisIfNecessary();
+ mContentViewCore.evaluateJavaScript(js, null);
+ mInjectedScriptEnabled = true;
+ mScriptInjected = true;
+ }
+ } catch (NoSuchFieldException ex) {
+ } catch (IllegalArgumentException ex) {
+ } catch (IllegalAccessException ex) {
+ }
}
}
@@ -188,11 +198,10 @@ public class AccessibilityInjector extends WebContentsObserverAndroid {
/**
* Sets whether or not the script is enabled. If the script is disabled, we also stop any
- * we output that is occurring. If the script has not yet been injected, injects it.
+ * we output that is occurring.
* @param enabled Whether or not to enable the script.
*/
public void setScriptEnabled(boolean enabled) {
- if (enabled && !mScriptInjected) injectAccessibilityScriptIntoPage();
if (!accessibilityIsAvailable() || mInjectedScriptEnabled == enabled) return;
mInjectedScriptEnabled = enabled;
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
deleted file mode 100644
index f25ae0b..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
+++ /dev/null
@@ -1,419 +0,0 @@
-// 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;
- }
-
- @Override
- 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;
- } else {
- return null;
- }
- }
-
- /** @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:
- nativeBlur(mNativeObj);
- 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;
-
- // 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.
- mContentViewCore.getContainerView().postInvalidate();
-
- 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);
- private native void nativeBlur(int nativeBrowserAccessibilityManagerAndroid);
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
index a065870..4dc2736 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
@@ -7,6 +7,7 @@ package org.chromium.content.browser.accessibility;
import android.content.Context;
import android.os.Bundle;
import android.os.SystemClock;
+import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import org.chromium.content.browser.ContentViewCore;