Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / accessibility / browser_accessibility_manager_win.cc
blob98350450151f27bb4ad6781dea6f829cd2476ecc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
7 #include "base/command_line.h"
8 #include "base/win/scoped_comptr.h"
9 #include "base/win/windows_version.h"
10 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
11 #include "content/browser/accessibility/browser_accessibility_win.h"
12 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
13 #include "content/common/accessibility_messages.h"
15 namespace content {
17 // static
18 BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
19 const ui::AXNodeData& src,
20 BrowserAccessibilityDelegate* delegate,
21 BrowserAccessibilityFactory* factory) {
22 return new BrowserAccessibilityManagerWin(
23 content::LegacyRenderWidgetHostHWND::Create(GetDesktopWindow()).get(),
24 NULL, src, delegate, factory);
27 BrowserAccessibilityManagerWin*
28 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() {
29 return static_cast<BrowserAccessibilityManagerWin*>(this);
32 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
33 LegacyRenderWidgetHostHWND* accessible_hwnd,
34 IAccessible* parent_iaccessible,
35 const ui::AXNodeData& src,
36 BrowserAccessibilityDelegate* delegate,
37 BrowserAccessibilityFactory* factory)
38 : BrowserAccessibilityManager(src, delegate, factory),
39 parent_hwnd_(accessible_hwnd->GetParent()),
40 parent_iaccessible_(parent_iaccessible),
41 tracked_scroll_object_(NULL),
42 accessible_hwnd_(accessible_hwnd) {
43 accessible_hwnd_->set_browser_accessibility_manager(this);
46 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
47 if (tracked_scroll_object_) {
48 tracked_scroll_object_->Release();
49 tracked_scroll_object_ = NULL;
51 if (accessible_hwnd_)
52 accessible_hwnd_->OnManagerDeleted();
55 // static
56 ui::AXNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() {
57 ui::AXNodeData empty_document;
58 empty_document.id = 0;
59 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
60 empty_document.state =
61 (1 << ui::AX_STATE_ENABLED) |
62 (1 << ui::AX_STATE_READ_ONLY) |
63 (1 << ui::AX_STATE_BUSY);
64 return empty_document;
67 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event,
68 LONG child_id) {
69 // Don't fire events if this view isn't hooked up to its parent.
70 if (!parent_iaccessible())
71 return;
73 // If on Win 7 and complete accessibility is enabled, use the fake child HWND
74 // to use as the root of the accessibility tree. See comments above
75 // LegacyRenderWidgetHostHWND for details.
76 if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser()) {
77 DCHECK(accessible_hwnd_);
78 parent_hwnd_ = accessible_hwnd_->hwnd();
79 parent_iaccessible_ = accessible_hwnd_->window_accessible();
81 ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id);
84 void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) {
85 BrowserAccessibilityManager::AddNodeToMap(node);
86 LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win();
87 unique_id_to_renderer_id_map_[unique_id_win] = node->renderer_id();
90 void BrowserAccessibilityManagerWin::RemoveNode(BrowserAccessibility* node) {
91 unique_id_to_renderer_id_map_.erase(
92 node->ToBrowserAccessibilityWin()->unique_id_win());
93 BrowserAccessibilityManager::RemoveNode(node);
94 if (node == tracked_scroll_object_) {
95 tracked_scroll_object_->Release();
96 tracked_scroll_object_ = NULL;
100 void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
101 ui::AXEvent event_type,
102 BrowserAccessibility* node) {
103 if (node->role() == ui::AX_ROLE_INLINE_TEXT_BOX)
104 return;
106 LONG event_id = EVENT_MIN;
107 switch (event_type) {
108 case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
109 event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
110 break;
111 case ui::AX_EVENT_ALERT:
112 event_id = EVENT_SYSTEM_ALERT;
113 break;
114 case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED:
115 event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED;
116 break;
117 case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
118 event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED;
119 break;
120 case ui::AX_EVENT_BLUR:
121 // Equivalent to focus on the root.
122 event_id = EVENT_OBJECT_FOCUS;
123 node = GetRoot();
124 break;
125 case ui::AX_EVENT_CHECKED_STATE_CHANGED:
126 event_id = EVENT_OBJECT_STATECHANGE;
127 break;
128 case ui::AX_EVENT_CHILDREN_CHANGED:
129 event_id = EVENT_OBJECT_REORDER;
130 break;
131 case ui::AX_EVENT_FOCUS:
132 event_id = EVENT_OBJECT_FOCUS;
133 break;
134 case ui::AX_EVENT_INVALID_STATUS_CHANGED:
135 event_id = EVENT_OBJECT_STATECHANGE;
136 break;
137 case ui::AX_EVENT_LIVE_REGION_CHANGED:
138 // TODO: try not firing a native notification at all, since
139 // on Windows, each individual item in a live region that changes
140 // already gets its own notification.
141 event_id = EVENT_OBJECT_REORDER;
142 break;
143 case ui::AX_EVENT_LOAD_COMPLETE:
144 event_id = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
145 break;
146 case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
147 event_id = EVENT_OBJECT_FOCUS;
148 break;
149 case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
150 event_id = EVENT_OBJECT_VALUECHANGE;
151 break;
152 case ui::AX_EVENT_HIDE:
153 event_id = EVENT_OBJECT_HIDE;
154 break;
155 case ui::AX_EVENT_SHOW:
156 event_id = EVENT_OBJECT_SHOW;
157 break;
158 case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
159 event_id = EVENT_SYSTEM_SCROLLINGEND;
160 break;
161 case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
162 event_id = EVENT_SYSTEM_SCROLLINGSTART;
163 break;
164 case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
165 event_id = EVENT_OBJECT_SELECTIONWITHIN;
166 break;
167 case ui::AX_EVENT_SELECTED_TEXT_CHANGED:
168 event_id = IA2_EVENT_TEXT_CARET_MOVED;
169 break;
170 case ui::AX_EVENT_TEXT_CHANGED:
171 event_id = EVENT_OBJECT_NAMECHANGE;
172 break;
173 case ui::AX_EVENT_TEXT_INSERTED:
174 event_id = IA2_EVENT_TEXT_INSERTED;
175 break;
176 case ui::AX_EVENT_TEXT_REMOVED:
177 event_id = IA2_EVENT_TEXT_REMOVED;
178 break;
179 case ui::AX_EVENT_VALUE_CHANGED:
180 event_id = EVENT_OBJECT_VALUECHANGE;
181 break;
182 default:
183 // Not all WebKit accessibility events result in a Windows
184 // accessibility notification.
185 break;
188 if (event_id != EVENT_MIN) {
189 // Pass the node's unique id in the |child_id| argument to NotifyWinEvent;
190 // the AT client will then call get_accChild on the HWND's accessibility
191 // object and pass it that same id, which we can use to retrieve the
192 // IAccessible for this node.
193 LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win();
194 MaybeCallNotifyWinEvent(event_id, child_id);
197 // If this is a layout complete notification (sent when a container scrolls)
198 // and there is a descendant tracked object, send a notification on it.
199 // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
200 if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE &&
201 tracked_scroll_object_ &&
202 tracked_scroll_object_->IsDescendantOf(node)) {
203 MaybeCallNotifyWinEvent(
204 IA2_EVENT_VISIBLE_DATA_CHANGED,
205 tracked_scroll_object_->ToBrowserAccessibilityWin()->unique_id_win());
206 tracked_scroll_object_->Release();
207 tracked_scroll_object_ = NULL;
211 void BrowserAccessibilityManagerWin::TrackScrollingObject(
212 BrowserAccessibilityWin* node) {
213 if (tracked_scroll_object_)
214 tracked_scroll_object_->Release();
215 tracked_scroll_object_ = node;
216 tracked_scroll_object_->AddRef();
219 BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin(
220 LONG unique_id_win) {
221 base::hash_map<LONG, int32>::iterator iter =
222 unique_id_to_renderer_id_map_.find(unique_id_win);
223 if (iter != unique_id_to_renderer_id_map_.end()) {
224 BrowserAccessibility* result = GetFromRendererID(iter->second);
225 if (result)
226 return result->ToBrowserAccessibilityWin();
228 return NULL;
231 void BrowserAccessibilityManagerWin::OnAccessibleHwndDeleted() {
232 // If the AccessibleHWND is deleted, |parent_hwnd_| and
233 // |parent_iaccessible_| are no longer valid either, since they were
234 // derived from AccessibleHWND. We don't have to restore them to
235 // previous values, though, because this should only happen
236 // during the destruct sequence for this window.
237 accessible_hwnd_ = NULL;
238 parent_hwnd_ = NULL;
239 parent_iaccessible_ = NULL;
242 } // namespace content