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

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

Powered by Google App Engine
This is Rietveld 408576698