17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/browser/accessibility/browser_accessibility_manager_android.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <cmath> 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/android/jni_android.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/android/jni_string.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/utf_string_conversions.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/values.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/browser/accessibility/browser_accessibility_android.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/common/accessibility_messages.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "jni/BrowserAccessibilityManager_jni.h" 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::android::AttachCurrentThread; 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::android::ScopedJavaLocalRef; 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace { 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// These are enums from android.view.accessibility.AccessibilityEvent in Java: 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochenum { 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_CHANGED = 16, 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Restricts |val| to the range [min, max]. 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int Clamp(int val, int min, int max) { 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return std::min(std::max(val, min), max); 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // anonymous namespace 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace content { 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace aria_strings { 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kAriaLivePolite[] = "polite"; 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char kAriaLiveAssertive[] = "assertive"; 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BrowserAccessibilityManager* BrowserAccessibilityManager::Create( 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AccessibilityNodeData& src, 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibilityDelegate* delegate, 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibilityFactory* factory) { 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return new BrowserAccessibilityManagerAndroid(ScopedJavaLocalRef<jobject>(), 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) src, delegate, factory); 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)BrowserAccessibilityManagerAndroid* 530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)BrowserAccessibilityManager::ToBrowserAccessibilityManagerAndroid() { 540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return static_cast<BrowserAccessibilityManagerAndroid*>(this); 550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BrowserAccessibilityManagerAndroid::BrowserAccessibilityManagerAndroid( 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ScopedJavaLocalRef<jobject> content_view_core, 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AccessibilityNodeData& src, 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibilityDelegate* delegate, 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibilityFactory* factory) 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : BrowserAccessibilityManager(src, delegate, factory) { 630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) SetContentViewCore(content_view_core); 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BrowserAccessibilityManagerAndroid::~BrowserAccessibilityManagerAndroid() { 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env = AttachCurrentThread(); 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (obj.is_null()) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_onNativeObjectDestroyed(env, obj.obj()); 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)AccessibilityNodeData BrowserAccessibilityManagerAndroid::GetEmptyDocument() { 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AccessibilityNodeData empty_document; 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) empty_document.id = 0; 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) empty_document.role = blink::WebAXRoleRootWebArea; 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) empty_document.state = 1 << blink::WebAXStateReadonly; 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return empty_document; 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void BrowserAccessibilityManagerAndroid::SetContentViewCore( 850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScopedJavaLocalRef<jobject> content_view_core) { 860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (content_view_core.is_null()) 870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return; 880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) java_ref_ = JavaObjectWeakGlobalRef( 910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) env, Java_BrowserAccessibilityManager_create( 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) env, reinterpret_cast<intptr_t>(this), 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content_view_core.obj()).obj()); 940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent( 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebAXEvent event_type, 987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibility* node) { 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env = AttachCurrentThread(); 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (obj.is_null()) 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 104d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (event_type == blink::WebAXEventHide) 105d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return; 106d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Always send AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED to notify 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the Android system that the accessibility hierarchy rooted at this 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // node has changed. 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Java_BrowserAccessibilityManager_handleContentChanged( 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) env, obj.obj(), node->renderer_id()); 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (event_type) { 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventLoadComplete: 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handlePageLoaded( 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), focus_->renderer_id()); 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventFocus: 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handleFocusChanged( 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), node->renderer_id()); 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventCheckedStateChanged: 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handleCheckStateChanged( 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), node->renderer_id()); 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventScrolledToAnchor: 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handleScrolledToAnchor( 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), node->renderer_id()); 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventAlert: 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // An alert is a special case of live region. Fall through to the 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // next case to handle it. 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventShow: { 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This event is fired when an object appears in a live region. 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Speak its text. 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserAccessibilityAndroid* android_node = 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static_cast<BrowserAccessibilityAndroid*>(node); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_announceLiveRegionText( 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF16ToJavaString( 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, android_node->GetText()).obj()); 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventSelectedTextChanged: 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handleTextSelectionChanged( 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), node->renderer_id()); 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventChildrenChanged: 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventTextChanged: 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebAXEventValueChanged: 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (node->IsEditableText()) { 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handleEditableTextChanged( 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj.obj(), node->renderer_id()); 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // There are some notifications that aren't meaningful on Android. 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // It's okay to skip them. 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)jint BrowserAccessibilityManagerAndroid::GetRootId(JNIEnv* env, jobject obj) { 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return static_cast<jint>(root_->renderer_id()); 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 167d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)jboolean BrowserAccessibilityManagerAndroid::IsNodeValid( 168d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) JNIEnv* env, jobject obj, jint id) { 169d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return GetFromRendererID(id) != NULL; 170d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} 171d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)jint BrowserAccessibilityManagerAndroid::HitTest( 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) JNIEnv* env, jobject obj, jint x, jint y) { 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibilityAndroid* result = 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BrowserAccessibilityAndroid*>( 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) root_->BrowserAccessibilityForPoint(gfx::Point(x, y))); 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!result) 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return root_->renderer_id(); 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (result->IsFocusable()) 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return result->renderer_id(); 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Examine the children of |result| to find the nearest accessibility focus 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // candidate 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibility* nearest_node = FuzzyHitTest(x, y, result); 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (nearest_node) 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return nearest_node->renderer_id(); 1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return root_->renderer_id(); 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochjboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo( 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env, jobject obj, jobject info, jint id) { 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetFromRendererID(id)); 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!node) 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (node->parent()) { 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityNodeInfoParent( 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, info, node->parent()->renderer_id()); 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (unsigned i = 0; i < node->PlatformChildCount(); ++i) { 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Java_BrowserAccessibilityManager_addAccessibilityNodeInfoChild( 2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) env, obj, info, node->children()[i]->renderer_id()); 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes( 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, info, 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch id, 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsCheckable(), 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsChecked(), 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsClickable(), 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsEnabled(), 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsFocusable(), 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsFocused(), 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsPassword(), 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsScrollable(), 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsSelected(), 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsVisibleToUser()); 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityNodeInfoStringAttributes( 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, info, 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF8ToJavaString(env, node->GetClassName()).obj(), 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj()); 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect absolute_rect = node->GetLocalBoundsRect(); 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect parent_relative_rect = absolute_rect; 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (node->parent()) { 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect parent_rect = node->parent()->GetLocalBoundsRect(); 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_relative_rect.Offset(-parent_rect.OffsetFromOrigin()); 231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool is_root = node->parent() == NULL; 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityNodeInfoLocation( 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, info, 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch absolute_rect.x(), absolute_rect.y(), 236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_relative_rect.x(), parent_relative_rect.y(), 237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch absolute_rect.width(), absolute_rect.height(), 238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_root); 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // New KitKat APIs 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityNodeInfoKitKatAttributes( 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, info, 243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->CanOpenPopup(), 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsContentInvalid(), 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsDismissable(), 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsMultiLine(), 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->AndroidInputType(), 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->AndroidLiveRegionType()); 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (node->IsCollection()) { 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityNodeInfoCollectionInfo( 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, info, 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RowCount(), 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->ColumnCount(), 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsHierarchical()); 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (node->IsCollectionItem() || node->IsHeading()) { 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityNodeInfoCollectionItemInfo( 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, info, 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RowIndex(), 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RowSpan(), 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->ColumnIndex(), 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->ColumnSpan(), 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsHeading()); 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (node->IsRangeType()) { 266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityNodeInfoRangeInfo( 267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, info, 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->AndroidRangeType(), 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RangeMin(), 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RangeMax(), 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RangeCurrentValue()); 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochjboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityEvent( 278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env, jobject obj, jobject event, jint id, jint event_type) { 279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserAccessibilityAndroid* node = static_cast<BrowserAccessibilityAndroid*>( 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetFromRendererID(id)); 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!node) 282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityEventBooleanAttributes( 285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, event, 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsChecked(), 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsEnabled(), 288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsPassword(), 289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->IsScrollable()); 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityEventClassName( 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, event, 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF8ToJavaString(env, node->GetClassName()).obj()); 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityEventListAttributes( 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, event, 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetItemIndex(), 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetItemCount()); 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityEventScrollAttributes( 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, event, 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetScrollX(), 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetScrollY(), 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetMaxScrollX(), 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetMaxScrollY()); 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch (event_type) { 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_CHANGED: 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityEventTextChangedAttrs( 307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, event, 308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetTextChangeFromIndex(), 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetTextChangeAddedCount(), 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetTextChangeRemovedCount(), 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF16ToJavaString( 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, node->GetTextChangeBeforeText()).obj(), 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj()); 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case ANDROID_ACCESSIBILITY_EVENT_TYPE_VIEW_TEXT_SELECTION_CHANGED: 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_setAccessibilityEventSelectionAttrs( 317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch env, obj, event, 318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetSelectionStart(), 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetSelectionEnd(), 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch node->GetEditableTextLength(), 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertUTF16ToJavaString(env, node->GetText()).obj()); 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Backwards-compatible fallback for new KitKat APIs. 328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityEventKitKatAttributes( 329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, event, 330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->CanOpenPopup(), 331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsContentInvalid(), 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsDismissable(), 333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsMultiLine(), 334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->AndroidInputType(), 335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->AndroidLiveRegionType()); 336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (node->IsCollection()) { 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityEventCollectionInfo( 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, event, 339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RowCount(), 340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->ColumnCount(), 341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsHierarchical()); 342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (node->IsCollectionItem() || node->IsHeading()) { 344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityEventCollectionItemInfo( 345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, event, 346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RowIndex(), 347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RowSpan(), 348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->ColumnIndex(), 349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->ColumnSpan(), 350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->IsHeading()); 351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (node->IsRangeType()) { 353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_BrowserAccessibilityManager_setAccessibilityEventRangeInfo( 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, obj, event, 355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->AndroidRangeType(), 356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RangeMin(), 357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RangeMax(), 358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) node->RangeCurrentValue()); 359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid BrowserAccessibilityManagerAndroid::Click( 365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env, jobject obj, jint id) { 366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserAccessibility* node = GetFromRendererID(id); 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (node) 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DoDefaultAction(*node); 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid BrowserAccessibilityManagerAndroid::Focus( 372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env, jobject obj, jint id) { 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserAccessibility* node = GetFromRendererID(id); 374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (node) 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetFocus(node, true); 376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid BrowserAccessibilityManagerAndroid::Blur(JNIEnv* env, jobject obj) { 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetFocus(root_, true); 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BrowserAccessibility* BrowserAccessibilityManagerAndroid::FuzzyHitTest( 3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int x, int y, BrowserAccessibility* start_node) { 3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibility* nearest_node = NULL; 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int min_distance = INT_MAX; 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FuzzyHitTestImpl(x, y, start_node, &nearest_node, &min_distance); 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return nearest_node; 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BrowserAccessibilityManagerAndroid::FuzzyHitTestImpl( 3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int x, int y, BrowserAccessibility* start_node, 3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibility** nearest_candidate, int* nearest_distance) { 3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserAccessibilityAndroid* node = 3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BrowserAccessibilityAndroid*>(start_node); 3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int distance = CalculateDistanceSquared(x, y, node); 3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (node->IsFocusable()) { 3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (distance < *nearest_distance) { 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *nearest_candidate = node; 4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *nearest_distance = distance; 4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Don't examine any more children of focusable node 4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(aboxhall): what about focusable children? 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!node->GetText().empty()) { 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (distance < *nearest_distance) { 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *nearest_candidate = node; 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *nearest_distance = distance; 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (uint32 i = 0; i < node->PlatformChildCount(); i++) { 4170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserAccessibility* child = node->PlatformGetChild(i); 4180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FuzzyHitTestImpl(x, y, child, nearest_candidate, nearest_distance); 4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int BrowserAccessibilityManagerAndroid::CalculateDistanceSquared( 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int x, int y, BrowserAccessibility* node) { 4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gfx::Rect node_bounds = node->GetLocalBoundsRect(); 4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int nearest_x = Clamp(x, node_bounds.x(), node_bounds.right()); 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int nearest_y = Clamp(y, node_bounds.y(), node_bounds.bottom()); 4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int dx = std::abs(x - nearest_x); 4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int dy = std::abs(y - nearest_y); 4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return dx * dx + dy * dy; 4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BrowserAccessibilityManagerAndroid::NotifyRootChanged() { 434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JNIEnv* env = AttachCurrentThread(); 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (obj.is_null()) 437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Java_BrowserAccessibilityManager_handleNavigate(env, obj.obj()); 4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool 4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BrowserAccessibilityManagerAndroid::UseRootScrollOffsetsWhenComputingBounds() { 4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // The Java layer handles the root scroll offset. 4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool RegisterBrowserAccessibilityManager(JNIEnv* env) { 449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return RegisterNativesImpl(env); 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace content 453