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

Side by Side Diff: chrome/renderer/extensions/automation_internal_custom_bindings.cc

Issue 1761633002: One accessibility tree per frame. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Android Created 4 years, 9 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/renderer/extensions/automation_internal_custom_bindings.h" 5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 if (parent->data().role == ui::AX_ROLE_WEB_AREA || 129 if (parent->data().role == ui::AX_ROLE_WEB_AREA ||
130 parent->data().role == ui::AX_ROLE_ROOT_WEB_AREA) { 130 parent->data().role == ui::AX_ROLE_ROOT_WEB_AREA) {
131 int sx = 0; 131 int sx = 0;
132 int sy = 0; 132 int sy = 0;
133 if (parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && 133 if (parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) &&
134 parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { 134 parent->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) {
135 bounds.Offset(-sx, -sy); 135 bounds.Offset(-sx, -sy);
136 } 136 }
137 need_to_offset_web_area = true; 137 need_to_offset_web_area = true;
138 } 138 }
139 parent = parent->parent(); 139 parent = cache->owner->GetParent(parent, &cache);
140 } 140 }
141 141
142 return bounds; 142 return bounds;
143 } 143 }
144 144
145 ui::AXNode* FindNodeWithChildTreeId(ui::AXNode* node, int child_tree_id) {
David Tseng 2016/03/04 16:50:20 Would it make sense to have the AXTree maintain a
dmazzoni 2016/03/07 21:35:31 I debated that but I'm not convinced it would actu
146 if (child_tree_id == node->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID))
147 return node;
148
149 for (int i = 0; i < node->child_count(); ++i) {
150 ui::AXNode* result =
151 FindNodeWithChildTreeId(node->ChildAtIndex(i), child_tree_id);
152 if (result)
153 return result;
154 }
155
156 return nullptr;
157 }
158
145 // 159 //
146 // Helper class that helps implement bindings for a JavaScript function 160 // Helper class that helps implement bindings for a JavaScript function
147 // that takes a single input argument consisting of a Tree ID. Looks up 161 // that takes a single input argument consisting of a Tree ID. Looks up
148 // the TreeCache and passes it to the function passed to the constructor. 162 // the TreeCache and passes it to the function passed to the constructor.
149 // 163 //
150 164
151 typedef void (*TreeIDFunction)(v8::Isolate* isolate, 165 typedef void (*TreeIDFunction)(v8::Isolate* isolate,
152 v8::ReturnValue<v8::Value> result, 166 v8::ReturnValue<v8::Value> result,
153 TreeCache* cache); 167 TreeCache* cache);
154 168
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 } 778 }
765 779
766 bool AutomationInternalCustomBindings::GetFocusInternal(TreeCache* cache, 780 bool AutomationInternalCustomBindings::GetFocusInternal(TreeCache* cache,
767 TreeCache** out_cache, 781 TreeCache** out_cache,
768 ui::AXNode** out_node) { 782 ui::AXNode** out_node) {
769 int focus_id = cache->tree.data().focus_id; 783 int focus_id = cache->tree.data().focus_id;
770 ui::AXNode* focus = cache->tree.GetFromId(focus_id); 784 ui::AXNode* focus = cache->tree.GetFromId(focus_id);
771 if (!focus) 785 if (!focus)
772 return false; 786 return false;
773 787
788 // If the focused node is the owner of a child tree, that indicates
789 // a node within the child tree is the one that actually has focus.
774 while (focus->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) { 790 while (focus->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
775 // Try to keep following focus recursively, by letting |tree_id| be the 791 // Try to keep following focus recursively, by letting |tree_id| be the
776 // new subtree to search in, while keeping |focus_tree_id| set to the tree 792 // new subtree to search in, while keeping |focus_tree_id| set to the tree
777 // where we know we found a focused node. 793 // where we know we found a focused node.
778 int child_tree_id = 794 int child_tree_id =
779 focus->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID); 795 focus->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID);
780 796
781 TreeCache* child_cache = GetTreeCacheFromTreeID(child_tree_id); 797 TreeCache* child_cache = GetTreeCacheFromTreeID(child_tree_id);
782 if (!child_cache) 798 if (!child_cache)
783 break; 799 break;
784 800
801 // If the child cache is a frame tree that indicates a focused frame,
802 // jump to that frame if possible.
803 if (child_cache->tree.data().focused_tree_id > 0) {
804 TreeCache* focused_cache =
805 GetTreeCacheFromTreeID(child_cache->tree.data().focused_tree_id);
806 if (focused_cache)
807 child_cache = focused_cache;
808 }
809
785 int child_focus_id = child_cache->tree.data().focus_id; 810 int child_focus_id = child_cache->tree.data().focus_id;
786 ui::AXNode* child_focus = child_cache->tree.GetFromId(child_focus_id); 811 ui::AXNode* child_focus = child_cache->tree.GetFromId(child_focus_id);
787 if (!child_focus) 812 if (!child_focus)
788 break; 813 break;
789 814
790 focus = child_focus; 815 focus = child_focus;
791 cache = child_cache; 816 cache = child_cache;
792 } 817 }
793 818
794 *out_cache = cache; 819 *out_cache = cache;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 896
872 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { 897 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() {
873 tree_change_observer_overall_filter_ = 898 tree_change_observer_overall_filter_ =
874 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; 899 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES;
875 for (const auto& observer : tree_change_observers_) { 900 for (const auto& observer : tree_change_observers_) {
876 tree_change_observer_overall_filter_ = 901 tree_change_observer_overall_filter_ =
877 std::max(observer.filter, tree_change_observer_overall_filter_); 902 std::max(observer.filter, tree_change_observer_overall_filter_);
878 } 903 }
879 } 904 }
880 905
906 ui::AXNode* AutomationInternalCustomBindings::GetParent(ui::AXNode* node,
907 TreeCache** cache) {
David Tseng 2016/03/04 16:50:20 out_cache
dmazzoni 2016/03/07 21:35:31 Made it in_out_cache
908 if (node->parent())
909 return node->parent();
910
911 int parent_tree_id = (*cache)->tree.data().parent_tree_id;
912 if (parent_tree_id <= 0)
David Tseng 2016/03/04 16:50:20 Doesn't the desktop tree have id 0?
dmazzoni 2016/03/07 21:35:32 Done.
913 return nullptr;
914
915 TreeCache* parent_cache = GetTreeCacheFromTreeID(parent_tree_id);
916 if (!parent_cache)
David Tseng 2016/03/04 16:50:20 Should |cache| be set to nullptr?
dmazzoni 2016/03/07 21:35:32 No, because it's an input and output parameter
917 return nullptr;
918
919 // Try to use the cached parent node from the most recent time this
920 // was called.
921 if (parent_cache->parent_node_id_from_parent_tree > 0) {
922 ui::AXNode* parent = parent_cache->tree.GetFromId(
923 parent_cache->parent_node_id_from_parent_tree);
924 if (parent) {
925 int parent_child_tree_id =
926 parent->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID);
927 if (parent_child_tree_id == (*cache)->tree_id) {
928 *cache = parent_cache;
929 return parent;
930 }
931 }
932 }
933
934 // If that fails, search for it and cache it for next time.
935 ui::AXNode* parent =
936 FindNodeWithChildTreeId(parent_cache->tree.root(), (*cache)->tree_id);
937 if (parent) {
David Tseng 2016/03/04 16:50:20 Is it an error if |parent| is null?
dmazzoni 2016/03/07 21:35:32 No, it's possible the child frame is loaded before
938 (*cache)->parent_node_id_from_parent_tree = parent->id();
939 *cache = parent_cache;
940 return parent;
941 }
942
943 return nullptr;
944 }
945
881 void AutomationInternalCustomBindings::RouteTreeIDFunction( 946 void AutomationInternalCustomBindings::RouteTreeIDFunction(
882 const std::string& name, 947 const std::string& name,
883 TreeIDFunction callback) { 948 TreeIDFunction callback) {
884 scoped_refptr<TreeIDWrapper> wrapper = new TreeIDWrapper(this, callback); 949 scoped_refptr<TreeIDWrapper> wrapper = new TreeIDWrapper(this, callback);
885 RouteFunction(name, base::Bind(&TreeIDWrapper::Run, wrapper)); 950 RouteFunction(name, base::Bind(&TreeIDWrapper::Run, wrapper));
886 } 951 }
887 952
888 void AutomationInternalCustomBindings::RouteNodeIDFunction( 953 void AutomationInternalCustomBindings::RouteNodeIDFunction(
889 const std::string& name, 954 const std::string& name,
890 NodeIDFunction callback) { 955 NodeIDFunction callback) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 const ExtensionMsg_AccessibilityEventParams& params, 1011 const ExtensionMsg_AccessibilityEventParams& params,
947 bool is_active_profile) { 1012 bool is_active_profile) {
948 is_active_profile_ = is_active_profile; 1013 is_active_profile_ = is_active_profile;
949 int tree_id = params.tree_id; 1014 int tree_id = params.tree_id;
950 TreeCache* cache; 1015 TreeCache* cache;
951 auto iter = tree_id_to_tree_cache_map_.find(tree_id); 1016 auto iter = tree_id_to_tree_cache_map_.find(tree_id);
952 if (iter == tree_id_to_tree_cache_map_.end()) { 1017 if (iter == tree_id_to_tree_cache_map_.end()) {
953 cache = new TreeCache(); 1018 cache = new TreeCache();
954 cache->tab_id = -1; 1019 cache->tab_id = -1;
955 cache->tree_id = params.tree_id; 1020 cache->tree_id = params.tree_id;
1021 cache->parent_node_id_from_parent_tree = -1;
956 cache->tree.SetDelegate(this); 1022 cache->tree.SetDelegate(this);
1023 cache->owner = this;
957 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); 1024 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache));
958 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache)); 1025 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache));
959 } else { 1026 } else {
960 cache = iter->second; 1027 cache = iter->second;
961 } 1028 }
962 1029
963 // Update the internal state whether it's the active profile or not. 1030 // Update the internal state whether it's the active profile or not.
964 cache->location_offset = params.location_offset; 1031 cache->location_offset = params.location_offset;
965 deleted_node_ids_.clear(); 1032 deleted_node_ids_.clear();
966 if (!cache->tree.Unserialize(params.update)) { 1033 if (!cache->tree.Unserialize(params.update)) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); 1227 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U));
1161 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); 1228 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id));
1162 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); 1229 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size()));
1163 args->Set(1U, nodes); 1230 args->Set(1U, nodes);
1164 for (size_t i = 0; i < ids.size(); ++i) 1231 for (size_t i = 0; i < ids.size(); ++i)
1165 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); 1232 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i]));
1166 context()->DispatchEvent("automationInternal.onNodesRemoved", args); 1233 context()->DispatchEvent("automationInternal.onNodesRemoved", args);
1167 } 1234 }
1168 1235
1169 } // namespace extensions 1236 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698