OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/accessibility/browser_accessibility_manager_android.h" | 5 #include "content/browser/accessibility/browser_accessibility_manager_android.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 if (obj.is_null()) | 121 if (obj.is_null()) |
122 return; | 122 return; |
123 | 123 |
124 if (event_type == ui::AX_EVENT_HIDE) | 124 if (event_type == ui::AX_EVENT_HIDE) |
125 return; | 125 return; |
126 | 126 |
127 // Always send AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED to notify | 127 // Always send AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED to notify |
128 // the Android system that the accessibility hierarchy rooted at this | 128 // the Android system that the accessibility hierarchy rooted at this |
129 // node has changed. | 129 // node has changed. |
130 Java_BrowserAccessibilityManager_handleContentChanged( | 130 Java_BrowserAccessibilityManager_handleContentChanged( |
131 env, obj.obj(), node->renderer_id()); | 131 env, obj.obj(), node->GetId()); |
132 | 132 |
133 switch (event_type) { | 133 switch (event_type) { |
134 case ui::AX_EVENT_LOAD_COMPLETE: | 134 case ui::AX_EVENT_LOAD_COMPLETE: |
135 Java_BrowserAccessibilityManager_handlePageLoaded( | 135 Java_BrowserAccessibilityManager_handlePageLoaded( |
136 env, obj.obj(), focus_->renderer_id()); | 136 env, obj.obj(), focus_->GetId()); |
137 break; | 137 break; |
138 case ui::AX_EVENT_FOCUS: | 138 case ui::AX_EVENT_FOCUS: |
139 Java_BrowserAccessibilityManager_handleFocusChanged( | 139 Java_BrowserAccessibilityManager_handleFocusChanged( |
140 env, obj.obj(), node->renderer_id()); | 140 env, obj.obj(), node->GetId()); |
141 break; | 141 break; |
142 case ui::AX_EVENT_CHECKED_STATE_CHANGED: | 142 case ui::AX_EVENT_CHECKED_STATE_CHANGED: |
143 Java_BrowserAccessibilityManager_handleCheckStateChanged( | 143 Java_BrowserAccessibilityManager_handleCheckStateChanged( |
144 env, obj.obj(), node->renderer_id()); | 144 env, obj.obj(), node->GetId()); |
145 break; | 145 break; |
146 case ui::AX_EVENT_SCROLL_POSITION_CHANGED: | 146 case ui::AX_EVENT_SCROLL_POSITION_CHANGED: |
147 Java_BrowserAccessibilityManager_handleScrollPositionChanged( | 147 Java_BrowserAccessibilityManager_handleScrollPositionChanged( |
148 env, obj.obj(), node->renderer_id()); | 148 env, obj.obj(), node->GetId()); |
149 break; | 149 break; |
150 case ui::AX_EVENT_SCROLLED_TO_ANCHOR: | 150 case ui::AX_EVENT_SCROLLED_TO_ANCHOR: |
151 Java_BrowserAccessibilityManager_handleScrolledToAnchor( | 151 Java_BrowserAccessibilityManager_handleScrolledToAnchor( |
152 env, obj.obj(), node->renderer_id()); | 152 env, obj.obj(), node->GetId()); |
153 break; | 153 break; |
154 case ui::AX_EVENT_ALERT: | 154 case ui::AX_EVENT_ALERT: |
155 // An alert is a special case of live region. Fall through to the | 155 // An alert is a special case of live region. Fall through to the |
156 // next case to handle it. | 156 // next case to handle it. |
157 case ui::AX_EVENT_SHOW: { | 157 case ui::AX_EVENT_SHOW: { |
158 // This event is fired when an object appears in a live region. | 158 // This event is fired when an object appears in a live region. |
159 // Speak its text. | 159 // Speak its text. |
160 BrowserAccessibilityAndroid* android_node = | 160 BrowserAccessibilityAndroid* android_node = |
161 static_cast<BrowserAccessibilityAndroid*>(node); | 161 static_cast<BrowserAccessibilityAndroid*>(node); |
162 Java_BrowserAccessibilityManager_announceLiveRegionText( | 162 Java_BrowserAccessibilityManager_announceLiveRegionText( |
163 env, obj.obj(), | 163 env, obj.obj(), |
164 base::android::ConvertUTF16ToJavaString( | 164 base::android::ConvertUTF16ToJavaString( |
165 env, android_node->GetText()).obj()); | 165 env, android_node->GetText()).obj()); |
166 break; | 166 break; |
167 } | 167 } |
168 case ui::AX_EVENT_SELECTED_TEXT_CHANGED: | 168 case ui::AX_EVENT_SELECTED_TEXT_CHANGED: |
169 Java_BrowserAccessibilityManager_handleTextSelectionChanged( | 169 Java_BrowserAccessibilityManager_handleTextSelectionChanged( |
170 env, obj.obj(), node->renderer_id()); | 170 env, obj.obj(), node->GetId()); |
171 break; | 171 break; |
172 case ui::AX_EVENT_CHILDREN_CHANGED: | 172 case ui::AX_EVENT_CHILDREN_CHANGED: |
173 case ui::AX_EVENT_TEXT_CHANGED: | 173 case ui::AX_EVENT_TEXT_CHANGED: |
174 case ui::AX_EVENT_VALUE_CHANGED: | 174 case ui::AX_EVENT_VALUE_CHANGED: |
175 if (node->IsEditableText()) { | 175 if (node->IsEditableText()) { |
176 Java_BrowserAccessibilityManager_handleEditableTextChanged( | 176 Java_BrowserAccessibilityManager_handleEditableTextChanged( |
177 env, obj.obj(), node->renderer_id()); | 177 env, obj.obj(), node->GetId()); |
178 } | 178 } |
179 break; | 179 break; |
180 default: | 180 default: |
181 // There are some notifications that aren't meaningful on Android. | 181 // There are some notifications that aren't meaningful on Android. |
182 // It's okay to skip them. | 182 // It's okay to skip them. |
183 break; | 183 break; |
184 } | 184 } |
185 } | 185 } |
186 | 186 |
187 jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) { | 187 jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) { |
188 return static_cast<jint>(root_->renderer_id()); | 188 return static_cast<jint>(root_->GetId()); |
189 } | 189 } |
190 | 190 |
191 jboolean BrowserAccessibilityManagerAndroid::IsNodeValid( | 191 jboolean BrowserAccessibilityManagerAndroid::IsNodeValid( |
192 JNIEnv* env, jobject obj, jint id) { | 192 JNIEnv* env, jobject obj, jint id) { |
193 return GetFromRendererID(id) != NULL; | 193 return GetFromRendererID(id) != NULL; |
194 } | 194 } |
195 | 195 |
196 jint BrowserAccessibilityManagerAndroid::HitTest( | 196 jint BrowserAccessibilityManagerAndroid::HitTest( |
197 JNIEnv* env, jobject obj, jint x, jint y) { | 197 JNIEnv* env, jobject obj, jint x, jint y) { |
198 BrowserAccessibilityAndroid* result = | 198 BrowserAccessibilityAndroid* result = |
199 static_cast<BrowserAccessibilityAndroid*>( | 199 static_cast<BrowserAccessibilityAndroid*>( |
200 root_->BrowserAccessibilityForPoint(gfx::Point(x, y))); | 200 root_->BrowserAccessibilityForPoint(gfx::Point(x, y))); |
201 | 201 |
202 if (!result) | 202 if (!result) |
203 return root_->renderer_id(); | 203 return root_->GetId(); |
204 | 204 |
205 if (result->IsFocusable()) | 205 if (result->IsFocusable()) |
206 return result->renderer_id(); | 206 return result->GetId(); |
207 | 207 |
208 // Examine the children of |result| to find the nearest accessibility focus | 208 // Examine the children of |result| to find the nearest accessibility focus |
209 // candidate | 209 // candidate |
210 BrowserAccessibility* nearest_node = FuzzyHitTest(x, y, result); | 210 BrowserAccessibility* nearest_node = FuzzyHitTest(x, y, result); |
211 if (nearest_node) | 211 if (nearest_node) |
212 return nearest_node->renderer_id(); | 212 return nearest_node->GetId(); |
213 | 213 |
214 return root_->renderer_id(); | 214 return root_->GetId(); |
215 } | 215 } |
216 | 216 |
217 jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo( | 217 jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo( |
218 JNIEnv* env, jobject obj, jobject info, jint id) { | 218 JNIEnv* env, jobject obj, jobject info, jint id) { |
219 BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( | 219 BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( |
220 GetFromRendererID(id)); | 220 GetFromRendererID(id)); |
221 if (!node) | 221 if (!node) |
222 return false; | 222 return false; |
223 | 223 |
224 if (node->parent()) { | 224 if (node->GetParent()) { |
225 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoParent( | 225 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoParent( |
226 env, obj, info, node->parent()->renderer_id()); | 226 env, obj, info, node->GetParent()->GetId()); |
227 } | 227 } |
228 for (unsigned i = 0; i < node->PlatformChildCount(); ++i) { | 228 for (unsigned i = 0; i < node->PlatformChildCount(); ++i) { |
229 Java_BrowserAccessibilityManager_addAccessibilityNodeInfoChild( | 229 Java_BrowserAccessibilityManager_addAccessibilityNodeInfoChild( |
230 env, obj, info, node->children()[i]->renderer_id()); | 230 env, obj, info, node->InternalGetChild(i)->GetId()); |
231 } | 231 } |
232 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes( | 232 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes( |
233 env, obj, info, | 233 env, obj, info, |
234 id, | 234 id, |
235 node->IsCheckable(), | 235 node->IsCheckable(), |
236 node->IsChecked(), | 236 node->IsChecked(), |
237 node->IsClickable(), | 237 node->IsClickable(), |
238 node->IsEnabled(), | 238 node->IsEnabled(), |
239 node->IsFocusable(), | 239 node->IsFocusable(), |
240 node->IsFocused(), | 240 node->IsFocused(), |
241 node->IsPassword(), | 241 node->IsPassword(), |
242 node->IsScrollable(), | 242 node->IsScrollable(), |
243 node->IsSelected(), | 243 node->IsSelected(), |
244 node->IsVisibleToUser()); | 244 node->IsVisibleToUser()); |
245 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoClassName( | 245 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoClassName( |
246 env, obj, info, | 246 env, obj, info, |
247 base::android::ConvertUTF8ToJavaString(env, node->GetClassName()).obj()); | 247 base::android::ConvertUTF8ToJavaString(env, node->GetClassName()).obj()); |
248 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoContentDescription( | 248 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoContentDescription( |
249 env, obj, info, | 249 env, obj, info, |
250 base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj(), | 250 base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj(), |
251 node->IsLink()); | 251 node->IsLink()); |
252 | 252 |
253 gfx::Rect absolute_rect = node->GetLocalBoundsRect(); | 253 gfx::Rect absolute_rect = node->GetLocalBoundsRect(); |
254 gfx::Rect parent_relative_rect = absolute_rect; | 254 gfx::Rect parent_relative_rect = absolute_rect; |
255 if (node->parent()) { | 255 if (node->GetParent()) { |
256 gfx::Rect parent_rect = node->parent()->GetLocalBoundsRect(); | 256 gfx::Rect parent_rect = node->GetParent()->GetLocalBoundsRect(); |
257 parent_relative_rect.Offset(-parent_rect.OffsetFromOrigin()); | 257 parent_relative_rect.Offset(-parent_rect.OffsetFromOrigin()); |
258 } | 258 } |
259 bool is_root = node->parent() == NULL; | 259 bool is_root = node->GetParent() == NULL; |
260 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoLocation( | 260 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoLocation( |
261 env, obj, info, | 261 env, obj, info, |
262 absolute_rect.x(), absolute_rect.y(), | 262 absolute_rect.x(), absolute_rect.y(), |
263 parent_relative_rect.x(), parent_relative_rect.y(), | 263 parent_relative_rect.x(), parent_relative_rect.y(), |
264 absolute_rect.width(), absolute_rect.height(), | 264 absolute_rect.width(), absolute_rect.height(), |
265 is_root); | 265 is_root); |
266 | 266 |
267 // New KitKat APIs | 267 // New KitKat APIs |
268 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoKitKatAttributes( | 268 Java_BrowserAccessibilityManager_setAccessibilityNodeInfoKitKatAttributes( |
269 env, obj, info, | 269 env, obj, info, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 } | 403 } |
404 | 404 |
405 void BrowserAccessibilityManagerAndroid::Blur(JNIEnv* env, jobject obj) { | 405 void BrowserAccessibilityManagerAndroid::Blur(JNIEnv* env, jobject obj) { |
406 SetFocus(root_, true); | 406 SetFocus(root_, true); |
407 } | 407 } |
408 | 408 |
409 void BrowserAccessibilityManagerAndroid::ScrollToMakeNodeVisible( | 409 void BrowserAccessibilityManagerAndroid::ScrollToMakeNodeVisible( |
410 JNIEnv* env, jobject obj, jint id) { | 410 JNIEnv* env, jobject obj, jint id) { |
411 BrowserAccessibility* node = GetFromRendererID(id); | 411 BrowserAccessibility* node = GetFromRendererID(id); |
412 if (node) | 412 if (node) |
413 ScrollToMakeVisible(*node, gfx::Rect(node->location().size())); | 413 ScrollToMakeVisible(*node, gfx::Rect(node->GetLocation().size())); |
414 } | 414 } |
415 | 415 |
416 BrowserAccessibility* BrowserAccessibilityManagerAndroid::FuzzyHitTest( | 416 BrowserAccessibility* BrowserAccessibilityManagerAndroid::FuzzyHitTest( |
417 int x, int y, BrowserAccessibility* start_node) { | 417 int x, int y, BrowserAccessibility* start_node) { |
418 BrowserAccessibility* nearest_node = NULL; | 418 BrowserAccessibility* nearest_node = NULL; |
419 int min_distance = INT_MAX; | 419 int min_distance = INT_MAX; |
420 FuzzyHitTestImpl(x, y, start_node, &nearest_node, &min_distance); | 420 FuzzyHitTestImpl(x, y, start_node, &nearest_node, &min_distance); |
421 return nearest_node; | 421 return nearest_node; |
422 } | 422 } |
423 | 423 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 if (!node) | 471 if (!node) |
472 return 0; | 472 return 0; |
473 | 473 |
474 AndroidHtmlElementType element_type = HtmlElementTypeFromString( | 474 AndroidHtmlElementType element_type = HtmlElementTypeFromString( |
475 base::android::ConvertJavaStringToUTF16(env, element_type_str)); | 475 base::android::ConvertJavaStringToUTF16(env, element_type_str)); |
476 | 476 |
477 node = forwards ? NextInTreeOrder(node) : PreviousInTreeOrder(node); | 477 node = forwards ? NextInTreeOrder(node) : PreviousInTreeOrder(node); |
478 while (node) { | 478 while (node) { |
479 switch(element_type) { | 479 switch(element_type) { |
480 case HTML_ELEMENT_TYPE_SECTION: | 480 case HTML_ELEMENT_TYPE_SECTION: |
481 if (node->role() == ui::AX_ROLE_ARTICLE || | 481 if (node->GetRole() == ui::AX_ROLE_ARTICLE || |
482 node->role() == ui::AX_ROLE_APPLICATION || | 482 node->GetRole() == ui::AX_ROLE_APPLICATION || |
483 node->role() == ui::AX_ROLE_BANNER || | 483 node->GetRole() == ui::AX_ROLE_BANNER || |
484 node->role() == ui::AX_ROLE_COMPLEMENTARY || | 484 node->GetRole() == ui::AX_ROLE_COMPLEMENTARY || |
485 node->role() == ui::AX_ROLE_CONTENT_INFO || | 485 node->GetRole() == ui::AX_ROLE_CONTENT_INFO || |
486 node->role() == ui::AX_ROLE_HEADING || | 486 node->GetRole() == ui::AX_ROLE_HEADING || |
487 node->role() == ui::AX_ROLE_MAIN || | 487 node->GetRole() == ui::AX_ROLE_MAIN || |
488 node->role() == ui::AX_ROLE_NAVIGATION || | 488 node->GetRole() == ui::AX_ROLE_NAVIGATION || |
489 node->role() == ui::AX_ROLE_SEARCH || | 489 node->GetRole() == ui::AX_ROLE_SEARCH || |
490 node->role() == ui::AX_ROLE_REGION) { | 490 node->GetRole() == ui::AX_ROLE_REGION) { |
491 return node->renderer_id(); | 491 return node->GetId(); |
492 } | 492 } |
493 break; | 493 break; |
494 case HTML_ELEMENT_TYPE_LIST: | 494 case HTML_ELEMENT_TYPE_LIST: |
495 if (node->role() == ui::AX_ROLE_LIST || | 495 if (node->GetRole() == ui::AX_ROLE_LIST || |
496 node->role() == ui::AX_ROLE_GRID || | 496 node->GetRole() == ui::AX_ROLE_GRID || |
497 node->role() == ui::AX_ROLE_TABLE || | 497 node->GetRole() == ui::AX_ROLE_TABLE || |
498 node->role() == ui::AX_ROLE_TREE) { | 498 node->GetRole() == ui::AX_ROLE_TREE) { |
499 return node->renderer_id(); | 499 return node->GetId(); |
500 } | 500 } |
501 break; | 501 break; |
502 case HTML_ELEMENT_TYPE_CONTROL: | 502 case HTML_ELEMENT_TYPE_CONTROL: |
503 if (static_cast<BrowserAccessibilityAndroid*>(node)->IsFocusable()) | 503 if (static_cast<BrowserAccessibilityAndroid*>(node)->IsFocusable()) |
504 return node->renderer_id(); | 504 return node->GetId(); |
505 break; | 505 break; |
506 case HTML_ELEMENT_TYPE_ANY: | 506 case HTML_ELEMENT_TYPE_ANY: |
507 // In theory, the API says that an accessibility service could | 507 // In theory, the API says that an accessibility service could |
508 // jump to an element by element name, like 'H1' or 'P'. This isn't | 508 // jump to an element by element name, like 'H1' or 'P'. This isn't |
509 // currently used by any accessibility service, and we think it's | 509 // currently used by any accessibility service, and we think it's |
510 // better to keep them high-level like 'SECTION' or 'CONTROL', so we | 510 // better to keep them high-level like 'SECTION' or 'CONTROL', so we |
511 // just fall back on linear navigation when we don't recognize the | 511 // just fall back on linear navigation when we don't recognize the |
512 // element type. | 512 // element type. |
513 if (static_cast<BrowserAccessibilityAndroid*>(node)->IsClickable()) | 513 if (static_cast<BrowserAccessibilityAndroid*>(node)->IsClickable()) |
514 return node->renderer_id(); | 514 return node->GetId(); |
515 break; | 515 break; |
516 } | 516 } |
517 | 517 |
518 node = forwards ? NextInTreeOrder(node) : PreviousInTreeOrder(node); | 518 node = forwards ? NextInTreeOrder(node) : PreviousInTreeOrder(node); |
519 } | 519 } |
520 | 520 |
521 return 0; | 521 return 0; |
522 } | 522 } |
523 | 523 |
524 void BrowserAccessibilityManagerAndroid::NotifyRootChanged() { | 524 void BrowserAccessibilityManagerAndroid::NotifyRootChanged() { |
525 JNIEnv* env = AttachCurrentThread(); | 525 JNIEnv* env = AttachCurrentThread(); |
526 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 526 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
527 if (obj.is_null()) | 527 if (obj.is_null()) |
528 return; | 528 return; |
529 | 529 |
530 Java_BrowserAccessibilityManager_handleNavigate(env, obj.obj()); | 530 Java_BrowserAccessibilityManager_handleNavigate(env, obj.obj()); |
531 } | 531 } |
532 | 532 |
533 bool | 533 bool |
534 BrowserAccessibilityManagerAndroid::UseRootScrollOffsetsWhenComputingBounds() { | 534 BrowserAccessibilityManagerAndroid::UseRootScrollOffsetsWhenComputingBounds() { |
535 // The Java layer handles the root scroll offset. | 535 // The Java layer handles the root scroll offset. |
536 return false; | 536 return false; |
537 } | 537 } |
538 | 538 |
539 bool RegisterBrowserAccessibilityManager(JNIEnv* env) { | 539 bool RegisterBrowserAccessibilityManager(JNIEnv* env) { |
540 return RegisterNativesImpl(env); | 540 return RegisterNativesImpl(env); |
541 } | 541 } |
542 | 542 |
543 } // namespace content | 543 } // namespace content |
OLD | NEW |