OLD | NEW |
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/browser_accessibility_manager_win.h" | 5 #include "chrome/browser/browser_accessibility_manager_win.h" |
6 | 6 |
7 #include "chrome/browser/browser_accessibility_win.h" | 7 #include "chrome/browser/browser_accessibility_win.h" |
8 #include "chrome/browser/renderer_host/render_process_host.h" | 8 #include "chrome/browser/renderer_host/render_process_host.h" |
9 #include "chrome/browser/renderer_host/render_view_host.h" | 9 #include "chrome/browser/renderer_host/render_view_host.h" |
10 #include "chrome/common/render_messages.h" | 10 #include "chrome/common/render_messages.h" |
(...skipping 21 matching lines...) Loading... |
32 BrowserAccessibilityDelegate* delegate, | 32 BrowserAccessibilityDelegate* delegate, |
33 BrowserAccessibilityFactory* factory) | 33 BrowserAccessibilityFactory* factory) |
34 : parent_hwnd_(parent_hwnd), | 34 : parent_hwnd_(parent_hwnd), |
35 delegate_(delegate), | 35 delegate_(delegate), |
36 factory_(factory), | 36 factory_(factory), |
37 focus_(NULL) { | 37 focus_(NULL) { |
38 HRESULT hr = ::CreateStdAccessibleObject( | 38 HRESULT hr = ::CreateStdAccessibleObject( |
39 parent_hwnd_, OBJID_WINDOW, IID_IAccessible, | 39 parent_hwnd_, OBJID_WINDOW, IID_IAccessible, |
40 reinterpret_cast<void **>(&window_iaccessible_)); | 40 reinterpret_cast<void **>(&window_iaccessible_)); |
41 DCHECK(SUCCEEDED(hr)); | 41 DCHECK(SUCCEEDED(hr)); |
42 root_ = CreateAccessibilityTree(NULL, src, 0); | 42 root_ = CreateAccessibilityTree(NULL, GetNextChildID(), src, 0); |
43 if (!focus_) | 43 if (!focus_) |
44 focus_ = root_; | 44 focus_ = root_; |
45 } | 45 } |
46 | 46 |
47 BrowserAccessibilityManager::~BrowserAccessibilityManager() { | 47 BrowserAccessibilityManager::~BrowserAccessibilityManager() { |
48 // Clients could still hold references to some nodes of the tree, so | 48 // Clients could still hold references to some nodes of the tree, so |
49 // calling Inactivate will make sure that as many nodes as possible are | 49 // calling Inactivate will make sure that as many nodes as possible are |
50 // released now, and remaining nodes are marked as inactive so that | 50 // released now, and remaining nodes are marked as inactive so that |
51 // calls to any methods on them will return E_FAIL; | 51 // calls to any methods on them will return E_FAIL; |
52 root_->InactivateTree(); | 52 root_->InactivateTree(); |
53 root_->Release(); | 53 root_->Release(); |
54 } | 54 } |
55 | 55 |
56 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { | 56 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { |
57 return root_; | 57 return root_; |
58 } | 58 } |
59 | 59 |
| 60 void BrowserAccessibilityManager::Remove(LONG child_id) { |
| 61 child_id_map_.erase(child_id); |
| 62 } |
| 63 |
60 BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID( | 64 BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID( |
61 LONG child_id) { | 65 LONG child_id) { |
62 base::hash_map<LONG, BrowserAccessibility*>::iterator iter = | 66 base::hash_map<LONG, BrowserAccessibility*>::iterator iter = |
63 child_id_map_.find(child_id); | 67 child_id_map_.find(child_id); |
64 if (iter != child_id_map_.end()) { | 68 if (iter != child_id_map_.end()) { |
65 return iter->second; | 69 return iter->second; |
66 } else { | 70 } else { |
67 return NULL; | 71 return NULL; |
68 } | 72 } |
69 } | 73 } |
(...skipping 40 matching lines...) Loading... |
110 } | 114 } |
111 | 115 |
112 void BrowserAccessibilityManager::OnAccessibilityObjectStateChange( | 116 void BrowserAccessibilityManager::OnAccessibilityObjectStateChange( |
113 int renderer_id) { | 117 int renderer_id) { |
114 base::hash_map<int, LONG>::iterator iter = | 118 base::hash_map<int, LONG>::iterator iter = |
115 renderer_id_to_child_id_map_.find(renderer_id); | 119 renderer_id_to_child_id_map_.find(renderer_id); |
116 if (iter == renderer_id_to_child_id_map_.end()) | 120 if (iter == renderer_id_to_child_id_map_.end()) |
117 return; | 121 return; |
118 | 122 |
119 LONG child_id = iter->second; | 123 LONG child_id = iter->second; |
120 ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); | 124 ::NotifyWinEvent( |
| 125 EVENT_OBJECT_STATECHANGE, |
| 126 parent_hwnd_, |
| 127 OBJID_CLIENT, |
| 128 child_id); |
| 129 } |
| 130 |
| 131 void BrowserAccessibilityManager::OnAccessibilityObjectChildrenChange( |
| 132 const std::vector<webkit_glue::WebAccessibility>& acc_changes) { |
| 133 if (delegate_) |
| 134 delegate_->AccessibilityObjectChildrenChangeAck(); |
| 135 |
| 136 // For each accessibility object child change. |
| 137 for (unsigned int index = 0; index < acc_changes.size(); index++) { |
| 138 const webkit_glue::WebAccessibility& acc_obj = acc_changes[index]; |
| 139 base::hash_map<int, LONG>::iterator iter = |
| 140 renderer_id_to_child_id_map_.find(acc_obj.id); |
| 141 if (iter == renderer_id_to_child_id_map_.end()) |
| 142 continue; |
| 143 |
| 144 LONG child_id = iter->second; |
| 145 BrowserAccessibility* old_browser_acc = GetFromChildID(child_id); |
| 146 |
| 147 BrowserAccessibility* new_browser_acc = CreateAccessibilityTree( |
| 148 old_browser_acc->GetParent(), |
| 149 child_id, |
| 150 acc_obj, |
| 151 old_browser_acc->index_in_parent()); |
| 152 |
| 153 if (focus_->IsDescendantOf(old_browser_acc)) |
| 154 focus_ = new_browser_acc; |
| 155 |
| 156 if (old_browser_acc->GetParent()) { |
| 157 old_browser_acc->GetParent()->ReplaceChild( |
| 158 old_browser_acc, |
| 159 new_browser_acc); |
| 160 } else { |
| 161 DCHECK_EQ(old_browser_acc, root_); |
| 162 root_ = new_browser_acc; |
| 163 } |
| 164 old_browser_acc->InactivateTree(); |
| 165 old_browser_acc->Release(); |
| 166 child_id_map_[child_id] = new_browser_acc; |
| 167 |
| 168 if (root_ != new_browser_acc) { |
| 169 NotifyWinEvent( |
| 170 EVENT_OBJECT_REORDER, parent_hwnd_, OBJID_CLIENT, child_id); |
| 171 } else { |
| 172 NotifyWinEvent( |
| 173 EVENT_OBJECT_REORDER, parent_hwnd_, OBJID_CLIENT, CHILDID_SELF); |
| 174 } |
| 175 } |
| 176 } |
| 177 |
| 178 LONG BrowserAccessibilityManager::GetNextChildID() { |
| 179 // Get the next child ID, and wrap around when we get near the end |
| 180 // of a 32-bit integer range. It's okay to wrap around; we just want |
| 181 // to avoid it as long as possible because clients may cache the ID of |
| 182 // an object for a while to determine if they've seen it before. |
| 183 next_child_id_--; |
| 184 if (next_child_id_ == -2000000000) |
| 185 next_child_id_ = -1; |
| 186 |
| 187 return next_child_id_; |
121 } | 188 } |
122 | 189 |
123 BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( | 190 BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( |
124 BrowserAccessibility* parent, | 191 BrowserAccessibility* parent, |
| 192 int child_id, |
125 const webkit_glue::WebAccessibility& src, | 193 const webkit_glue::WebAccessibility& src, |
126 int index_in_parent) { | 194 int index_in_parent) { |
127 BrowserAccessibility* instance = factory_->Create(); | 195 BrowserAccessibility* instance = factory_->Create(); |
128 | 196 |
129 // Get the next child ID, and wrap around when we get near the end | |
130 // of a 32-bit integer range. It's okay to wrap around; we just want | |
131 // to avoid it as long as possible because clients may cache the ID of | |
132 // an object for a while to determine if they've seen it before. | |
133 LONG child_id = next_child_id_; | |
134 next_child_id_--; | |
135 if (next_child_id_ == -2000000000) | |
136 next_child_id_ = -1; | |
137 | |
138 instance->Initialize(this, parent, child_id, index_in_parent, src); | 197 instance->Initialize(this, parent, child_id, index_in_parent, src); |
139 child_id_map_[child_id] = instance; | 198 child_id_map_[child_id] = instance; |
140 renderer_id_to_child_id_map_[src.id] = child_id; | 199 renderer_id_to_child_id_map_[src.id] = child_id; |
141 if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) | 200 if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) |
142 focus_ = instance; | 201 focus_ = instance; |
143 for (int i = 0; i < static_cast<int>(src.children.size()); ++i) { | 202 for (int i = 0; i < static_cast<int>(src.children.size()); ++i) { |
144 BrowserAccessibility* child = CreateAccessibilityTree( | 203 BrowserAccessibility* child = CreateAccessibilityTree( |
145 instance, src.children[i], i); | 204 instance, GetNextChildID(), src.children[i], i); |
146 instance->AddChild(child); | 205 instance->AddChild(child); |
147 } | 206 } |
148 | 207 |
149 return instance; | 208 return instance; |
150 } | 209 } |
OLD | NEW |