Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: content/browser/accessibility/browser_accessibility_manager_android.cc

Issue 15741009: Native Android accessibility. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
6
7 #include <cmath>
8
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "content/browser/accessibility/browser_accessibility_android.h"
15 #include "content/common/accessibility_messages.h"
16 #include "jni/BrowserAccessibilityManager_jni.h"
17
18 using base::android::AttachCurrentThread;
19
20 namespace content {
21
22 namespace aria_strings {
23 const char kAriaLivePolite[] = "polite";
24 const char kAriaLiveAssertive[] = "assertive";
25 }
26
27 // static
28 BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
29 const AccessibilityNodeData& src,
30 BrowserAccessibilityDelegate* delegate,
31 BrowserAccessibilityFactory* factory) {
32 return new BrowserAccessibilityManagerAndroid(NULL, src, delegate, factory);
33 }
34
35 BrowserAccessibilityManagerAndroid::BrowserAccessibilityManagerAndroid(
36 ContentViewCoreImpl* content_view_core,
37 const AccessibilityNodeData& src,
38 BrowserAccessibilityDelegate* delegate,
39 BrowserAccessibilityFactory* factory)
40 : BrowserAccessibilityManager(src, delegate, factory),
41 content_view_core_(content_view_core) {
42 if (!content_view_core)
43 return;
44 JNIEnv* env = AttachCurrentThread();
45 base::android::ScopedJavaLocalRef<jobject> content_view_core_java =
46 content_view_core->GetJavaObject();
47 java_ref_.Reset(Java_BrowserAccessibilityManager_create(
48 env, reinterpret_cast<jint>(this), content_view_core_java.obj()));
49 }
50
51 BrowserAccessibilityManagerAndroid::~BrowserAccessibilityManagerAndroid() {
52 if (java_ref_.is_null())
53 return;
54 JNIEnv* env = AttachCurrentThread();
55 Java_BrowserAccessibilityManager_onNativeObjectDestroyed(
56 env, java_ref_.obj());
57 }
58
59 // static
60 AccessibilityNodeData BrowserAccessibilityManagerAndroid::GetEmptyDocument() {
61 AccessibilityNodeData empty_document;
62 empty_document.id = 0;
63 empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;
64 empty_document.state = 1 << AccessibilityNodeData::STATE_READONLY;
65 return empty_document;
66 }
67
68 void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
69 int type,
70 BrowserAccessibility* node) {
71 if (java_ref_.is_null())
72 return;
73
74 JNIEnv* env = AttachCurrentThread();
75 switch (type) {
76 case AccessibilityNotificationLoadComplete:
77 Java_BrowserAccessibilityManager_handlePageLoaded(
78 env, java_ref_.obj(), focus_->renderer_id());
79 break;
80 case AccessibilityNotificationFocusChanged:
81 Java_BrowserAccessibilityManager_handleFocusChanged(
82 env, java_ref_.obj(), node->renderer_id());
83 break;
84 case AccessibilityNotificationCheckStateChanged:
85 Java_BrowserAccessibilityManager_handleCheckStateChanged(
86 env, java_ref_.obj(), node->renderer_id());
87 break;
88 case AccessibilityNotificationScrolledToAnchor:
89 Java_BrowserAccessibilityManager_handleScrolledToAnchor(
90 env, java_ref_.obj(), node->renderer_id());
91 break;
92 case AccessibilityNotificationAlert:
93 Java_BrowserAccessibilityManager_announceObjectShow(
94 env, java_ref_.obj(), node->renderer_id(), JNI_TRUE);
95 case AccessibilityNotificationObjectShow:
96 Java_BrowserAccessibilityManager_announceObjectShow(
97 env, java_ref_.obj(), node->renderer_id(), JNI_FALSE);
98 case AccessibilityNotificationSelectedTextChanged:
99 Java_BrowserAccessibilityManager_handleTextSelectionChanged(
100 env, java_ref_.obj(), node->renderer_id());
101 break;
102 case AccessibilityNotificationChildrenChanged:
103 case AccessibilityNotificationTextChanged:
104 case AccessibilityNotificationValueChanged:
105 if (node->IsEditableText()) {
106 Java_BrowserAccessibilityManager_handleEditableTextChanged(
107 env, java_ref_.obj(), node->renderer_id());
108 } else {
109 Java_BrowserAccessibilityManager_handleContentChanged(
110 env, java_ref_.obj(), node->renderer_id());
111 }
112 break;
113 default:
114 break;
115 }
116 }
117
118 jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) {
119 return static_cast<jint>(root_->renderer_id());
120 }
121
122 jint BrowserAccessibilityManagerAndroid::HitTest(
123 JNIEnv* env, jobject obj, jint x, jint y) {
124 BrowserAccessibilityAndroid* result =
125 static_cast<BrowserAccessibilityAndroid*>(
126 root_->BrowserAccessibilityForPoint(gfx::Point(x, y)));
127
128 if (!result)
129 return root_->renderer_id();
130
131 if (result->IsFocusable())
132 return result->renderer_id();
133
134 // Examine the children of |result| to find the nearest accessibility focus
135 // candidate
136 BrowserAccessibility* nearest_node = FuzzyHitTest(x, y, result);
137 if (nearest_node)
138 return nearest_node->renderer_id();
139
140 return root_->renderer_id();
141 }
142
143 BrowserAccessibility* BrowserAccessibilityManagerAndroid::FuzzyHitTest(
144 int x, int y, BrowserAccessibility* start_node) {
145 BrowserAccessibility* nearest_node = NULL;
146 float min_distance = MAXFLOAT;
147 FuzzyHitTestImpl(x, y, start_node, &nearest_node, &min_distance);
148 return nearest_node;
149 }
150
151 void BrowserAccessibilityManagerAndroid::FuzzyHitTestImpl(
David Trainor- moved to gerrit 2013/06/04 20:27:18 Could this also be static?
dmazzoni 2013/06/07 20:23:16 Done.
152 int x, int y, BrowserAccessibility* start_node,
153 BrowserAccessibility** nearest_candidate, float* nearest_distance) {
154 BrowserAccessibilityAndroid* node =
155 static_cast<BrowserAccessibilityAndroid*>(start_node);
156 float distance = CalculateDistance(x, y, node);
157
158 if (node->IsFocusable()) {
159 if (distance < *nearest_distance) {
160 *nearest_candidate = node;
161 *nearest_distance = distance;
162 }
163 // Don't examine any more children of focusable node
164 // TODO(aboxhall): what about focusable children?
165 return;
166 }
167
168 if (!node->ComputeName().empty()) {
169 if (distance < *nearest_distance) {
170 *nearest_candidate = node;
171 *nearest_distance = distance;
172 }
173 return;
174 }
175
176 if (!node->IsLeaf()) {
177 for (uint32 i = 0; i < node->child_count(); i++) {
178 BrowserAccessibility* child = node->GetChild(i);
179 FuzzyHitTestImpl(x, y, child, nearest_candidate, nearest_distance);
180 }
181 }
182 }
183
184 // Restricts |val| to the range [min, max].
185 static int clamp(int val, int min, int max) {
David Trainor- moved to gerrit 2013/06/04 20:27:18 anonymous namespace instead of static?
dmazzoni 2013/06/07 20:23:16 Done.
186 if (val < min)
David Trainor- moved to gerrit 2013/06/04 20:27:18 Since you're std in most places: std::min(std::max
dmazzoni 2013/06/07 20:23:16 Done.
dmazzoni 2013/06/07 20:23:16 Done.
187 return min;
188 else if (val > max)
189 return max;
190 else
191 return val;
192 }
193
194 // static
195 float BrowserAccessibilityManagerAndroid::CalculateDistance(
196 int x, int y, BrowserAccessibility* node) {
197 gfx::Rect node_bounds = node->GetLocalBoundsRect();
198 int nearest_x = clamp(x, node_bounds.x(), node_bounds.right());
199 int nearest_y = clamp(y, node_bounds.y(), node_bounds.bottom());
200 float dx = std::abs(x - nearest_x);
201 float dy = std::abs(y - nearest_y);
202 return std::sqrt(dx * dx + dy * dy);
David Trainor- moved to gerrit 2013/06/04 20:27:18 You could always just track MinDistanceSquared ins
dmazzoni 2013/06/07 20:23:16 Done.
203 }
204
205 jint BrowserAccessibilityManagerAndroid::GetNativeNodeById(
206 JNIEnv* env, jobject obj, jint id) {
207 return reinterpret_cast<jint>(GetFromRendererID(id));
208 }
209
210 void BrowserAccessibilityManagerAndroid::NotifyRootChanged() {
211 JNIEnv* env = AttachCurrentThread();
212 Java_BrowserAccessibilityManager_handleNavigate(env, java_ref_.obj());
213 }
214
215 bool
216 BrowserAccessibilityManagerAndroid::UseRootScrollOffsetsWhenComputingBounds() {
217 // The Java layer handles the root scroll offset.
218 return false;
219 }
220
221 bool RegisterBrowserAccessibilityManager(JNIEnv* env) {
222 return RegisterNativesImpl(env);
223 }
224
225 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698