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

Side by Side Diff: chrome/browser/accessibility/browser_accessibility_manager.cc

Issue 3582015: Revert 61704 - Make BrowserAccessibilityManager cross platform. Step 2. In Pr... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/browser/accessibility/browser_accessibility_manager.h" 5 #include "chrome/browser/accessibility/browser_accessibility_manager.h"
6 6
7 #include "chrome/browser/accessibility/browser_accessibility.h" 7 #include "chrome/common/render_messages_params.h"
8 8
9 using webkit_glue::WebAccessibility; 9 using webkit_glue::WebAccessibility;
10 10
11 // Start child IDs at -1 and decrement each time, because clients use
12 // child IDs of 1, 2, 3, ... to access the children of an object by
13 // index, so we use negative IDs to clearly distinguish between indices
14 // and unique IDs.
15 // static
16 int32 BrowserAccessibilityManager::next_child_id_ = -1;
17
18 BrowserAccessibility* BrowserAccessibilityFactory::Create() {
19 return BrowserAccessibility::Create();
20 }
21 11
22 BrowserAccessibilityManager::BrowserAccessibilityManager( 12 BrowserAccessibilityManager::BrowserAccessibilityManager(
23 gfx::NativeView parent_view, 13 gfx::NativeWindow parent_window)
24 const WebAccessibility& src, 14 : parent_window_(parent_window) {
25 BrowserAccessibilityDelegate* delegate,
26 BrowserAccessibilityFactory* factory)
27 : parent_view_(parent_view),
28 delegate_(delegate),
29 factory_(factory),
30 focus_(NULL) {
31 root_ = CreateAccessibilityTree(NULL, GetNextChildID(), src, 0);
32 if (!focus_)
33 focus_ = root_;
34 }
35
36 // static
37 int32 BrowserAccessibilityManager::GetNextChildID() {
38 // Get the next child ID, and wrap around when we get near the end
39 // of a 32-bit integer range. It's okay to wrap around; we just want
40 // to avoid it as long as possible because clients may cache the ID of
41 // an object for a while to determine if they've seen it before.
42 next_child_id_--;
43 if (next_child_id_ == -2000000000)
44 next_child_id_ = -1;
45
46 return next_child_id_;
47 } 15 }
48 16
49 BrowserAccessibilityManager::~BrowserAccessibilityManager() { 17 BrowserAccessibilityManager::~BrowserAccessibilityManager() {
50 // Clients could still hold references to some nodes of the tree, so
51 // calling Inactivate will make sure that as many nodes as possible are
52 // released now, and remaining nodes are marked as inactive so that
53 // calls to any methods on them will return E_FAIL;
54 root_->ReleaseTree();
55 root_->ReleaseReference();
56 }
57
58 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
59 return root_;
60 }
61
62 BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID(
63 int32 child_id) {
64 base::hash_map<int32, BrowserAccessibility*>::iterator iter =
65 child_id_map_.find(child_id);
66 if (iter != child_id_map_.end()) {
67 return iter->second;
68 } else {
69 return NULL;
70 }
71 }
72
73 void BrowserAccessibilityManager::Remove(int32 child_id) {
74 child_id_map_.erase(child_id);
75 } 18 }
76 19
77 void BrowserAccessibilityManager::OnAccessibilityNotifications( 20 void BrowserAccessibilityManager::OnAccessibilityNotifications(
78 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) { 21 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) {
79 for (uint32 index = 0; index < params.size(); index++) { 22 for (uint32 index = 0; index < params.size(); index++) {
80 const ViewHostMsg_AccessibilityNotification_Params& param = params[index]; 23 const ViewHostMsg_AccessibilityNotification_Params& param = params[index];
81 24
82 switch (param.notification_type) { 25 switch (param.notification_type) {
83 case ViewHostMsg_AccessibilityNotification_Params:: 26 case ViewHostMsg_AccessibilityNotification_Params::
84 NOTIFICATION_TYPE_CHECK_STATE_CHANGED: 27 NOTIFICATION_TYPE_CHECK_STATE_CHANGED:
(...skipping 19 matching lines...) Expand all
104 NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED: 47 NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED:
105 OnAccessibilityObjectTextChange(param.acc_obj); 48 OnAccessibilityObjectTextChange(param.acc_obj);
106 break; 49 break;
107 default: 50 default:
108 DCHECK(0); 51 DCHECK(0);
109 break; 52 break;
110 } 53 }
111 } 54 }
112 } 55 }
113 56
114 void BrowserAccessibilityManager::OnAccessibilityObjectStateChange( 57 gfx::NativeWindow BrowserAccessibilityManager::GetParentWindow() {
115 const WebAccessibility& acc_obj) { 58 return parent_window_;
116 BrowserAccessibility* new_browser_acc = UpdateTree(acc_obj);
117 if (!new_browser_acc)
118 return;
119
120 NotifyAccessibilityEvent(
121 ViewHostMsg_AccessibilityNotification_Params::
122 NOTIFICATION_TYPE_CHECK_STATE_CHANGED,
123 new_browser_acc);
124 } 59 }
125
126 void BrowserAccessibilityManager::OnAccessibilityObjectChildrenChange(
127 const WebAccessibility& acc_obj) {
128 BrowserAccessibility* new_browser_acc = UpdateTree(acc_obj);
129 if (!new_browser_acc)
130 return;
131
132 NotifyAccessibilityEvent(
133 ViewHostMsg_AccessibilityNotification_Params::
134 NOTIFICATION_TYPE_CHILDREN_CHANGED,
135 new_browser_acc);
136 }
137
138 void BrowserAccessibilityManager::OnAccessibilityObjectFocusChange(
139 const WebAccessibility& acc_obj) {
140 BrowserAccessibility* new_browser_acc = UpdateTree(acc_obj);
141 if (!new_browser_acc)
142 return;
143
144 focus_ = new_browser_acc;
145 if (delegate_ && delegate_->HasFocus())
146 GotFocus();
147 }
148
149 void BrowserAccessibilityManager::OnAccessibilityObjectLoadComplete(
150 const WebAccessibility& acc_obj) {
151 root_->ReleaseTree();
152 root_->ReleaseReference();
153 focus_ = NULL;
154
155 root_ = CreateAccessibilityTree(NULL, GetNextChildID(), acc_obj, 0);
156 if (!focus_)
157 focus_ = root_;
158
159 NotifyAccessibilityEvent(
160 ViewHostMsg_AccessibilityNotification_Params::
161 NOTIFICATION_TYPE_LOAD_COMPLETE,
162 root_);
163 if (delegate_ && delegate_->HasFocus())
164 GotFocus();
165 }
166
167 void BrowserAccessibilityManager::OnAccessibilityObjectValueChange(
168 const WebAccessibility& acc_obj) {
169 BrowserAccessibility* new_browser_acc = UpdateTree(acc_obj);
170 if (!new_browser_acc)
171 return;
172
173 NotifyAccessibilityEvent(
174 ViewHostMsg_AccessibilityNotification_Params::
175 NOTIFICATION_TYPE_VALUE_CHANGED,
176 root_);
177 }
178
179 void BrowserAccessibilityManager::OnAccessibilityObjectTextChange(
180 const WebAccessibility& acc_obj) {
181 BrowserAccessibility* new_browser_acc = UpdateTree(acc_obj);
182 if (!new_browser_acc)
183 return;
184
185 NotifyAccessibilityEvent(
186 ViewHostMsg_AccessibilityNotification_Params::
187 NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED,
188 root_);
189 }
190
191 void BrowserAccessibilityManager::GotFocus() {
192 // TODO(ctguil): Remove when tree update logic handles focus changes.
193 if (!focus_)
194 return;
195
196 NotifyAccessibilityEvent(
197 ViewHostMsg_AccessibilityNotification_Params::
198 NOTIFICATION_TYPE_FOCUS_CHANGED,
199 focus_);
200 }
201
202 gfx::NativeView BrowserAccessibilityManager::GetParentView() {
203 return parent_view_;
204 }
205
206 BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
207 BrowserAccessibility* root) {
208 if (focus_ && (!root || focus_->IsDescendantOf(root)))
209 return focus_;
210
211 return NULL;
212 }
213
214 void BrowserAccessibilityManager::SetFocus(
215 const BrowserAccessibility& node) {
216 if (delegate_)
217 delegate_->SetAccessibilityFocus(node.renderer_id());
218 }
219
220 void BrowserAccessibilityManager::DoDefaultAction(
221 const BrowserAccessibility& node) {
222 if (delegate_)
223 delegate_->AccessibilityDoDefaultAction(node.renderer_id());
224 }
225
226 bool BrowserAccessibilityManager::CanModifyTreeInPlace(
227 BrowserAccessibility* current_root,
228 const WebAccessibility& new_root) {
229 if (current_root->renderer_id() != new_root.id)
230 return false;
231 if (current_root->GetChildCount() != new_root.children.size())
232 return false;
233 for (unsigned int i = 0; i < current_root->GetChildCount(); i++) {
234 if (!CanModifyTreeInPlace(current_root->GetChild(i),
235 new_root.children[i])) {
236 return false;
237 }
238 }
239 return true;
240 }
241
242 void BrowserAccessibilityManager::ModifyTreeInPlace(
243 BrowserAccessibility* current_root,
244 const WebAccessibility& new_root) {
245 DCHECK_EQ(current_root->renderer_id(), new_root.id);
246 DCHECK_EQ(current_root->GetChildCount(), new_root.children.size());
247 for (unsigned int i = 0; i < current_root->GetChildCount(); i++)
248 ModifyTreeInPlace(current_root->GetChild(i), new_root.children[i]);
249 current_root->Initialize(
250 this,
251 current_root->GetParent(),
252 current_root->child_id(),
253 current_root->index_in_parent(),
254 new_root);
255 }
256
257
258 BrowserAccessibility* BrowserAccessibilityManager::UpdateTree(
259 const WebAccessibility& acc_obj) {
260 base::hash_map<int, int32>::iterator iter =
261 renderer_id_to_child_id_map_.find(acc_obj.id);
262 if (iter == renderer_id_to_child_id_map_.end())
263 return NULL;
264
265 int32 child_id = iter->second;
266 BrowserAccessibility* old_browser_acc = GetFromChildID(child_id);
267 if (!old_browser_acc)
268 return NULL;
269
270 if (CanModifyTreeInPlace(old_browser_acc, acc_obj)) {
271 ModifyTreeInPlace(old_browser_acc, acc_obj);
272 return old_browser_acc;
273 }
274
275 BrowserAccessibility* new_browser_acc = CreateAccessibilityTree(
276 old_browser_acc->GetParent(),
277 child_id,
278 acc_obj,
279 old_browser_acc->index_in_parent());
280
281 if (old_browser_acc->GetParent()) {
282 old_browser_acc->GetParent()->ReplaceChild(
283 old_browser_acc,
284 new_browser_acc);
285 } else {
286 DCHECK_EQ(old_browser_acc, root_);
287 root_ = new_browser_acc;
288 }
289 old_browser_acc->ReleaseTree();
290 old_browser_acc->ReleaseReference();
291 child_id_map_[child_id] = new_browser_acc;
292
293 return new_browser_acc;
294 }
295
296 BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree(
297 BrowserAccessibility* parent,
298 int child_id,
299 const WebAccessibility& src,
300 int index_in_parent) {
301 BrowserAccessibility* instance = factory_->Create();
302
303 instance->Initialize(this, parent, child_id, index_in_parent, src);
304 child_id_map_[child_id] = instance;
305 renderer_id_to_child_id_map_[src.id] = child_id;
306 if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1)
307 focus_ = instance;
308 for (int i = 0; i < static_cast<int>(src.children.size()); ++i) {
309 BrowserAccessibility* child = CreateAccessibilityTree(
310 instance, GetNextChildID(), src.children[i], i);
311 instance->AddChild(child);
312 }
313
314 return instance;
315 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698