Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "content/browser/accessibility/browser_accessibility_manager_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
| 6 | 6 |
| 7 #include <atlbase.h> | 7 #include <atlbase.h> |
|
scottmg
2014/01/31 17:28:48
Looks like you can remove all these ATL includes.
ananta
2014/01/31 18:25:29
Done.
| |
| 8 #include <atlapp.h> | 8 #include <atlapp.h> |
| 9 #include <atlcom.h> | 9 #include <atlcom.h> |
| 10 #include <atlcrack.h> | 10 #include <atlcrack.h> |
| 11 #include <oleacc.h> | 11 #include <oleacc.h> |
| 12 | 12 |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/win/scoped_comptr.h" | 14 #include "base/win/scoped_comptr.h" |
| 15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
| 16 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 16 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
| 17 #include "content/browser/accessibility/browser_accessibility_win.h" | 17 #include "content/browser/accessibility/browser_accessibility_win.h" |
| 18 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" | |
| 18 #include "content/common/accessibility_messages.h" | 19 #include "content/common/accessibility_messages.h" |
| 19 | 20 |
| 20 namespace content { | 21 namespace content { |
| 21 | 22 |
| 22 // Some screen readers expect every tab / every unique web content container | |
| 23 // to be in its own HWND, like it was before Aura, but with Aura there's just | |
| 24 // one main HWND for a frame, or even for the whole desktop. So, we need a | |
| 25 // fake HWND as the root of the accessibility tree for each tab. | |
| 26 // We should get rid of this code when the latest two versions of all | |
| 27 // supported screen readers no longer make this assumption. | |
| 28 // | |
| 29 // This class implements a child HWND with zero size, that delegates its | |
| 30 // accessibility implementation to the root of the BrowserAccessibilityManager | |
| 31 // tree. This HWND is hooked up as the parent of the root object in the | |
| 32 // BrowserAccessibilityManager tree, so when any accessibility client | |
| 33 // calls ::WindowFromAccessibleObject, they get this HWND instead of the | |
| 34 // DesktopWindowTreeHostWin. | |
| 35 class AccessibleHWND | |
| 36 : public ATL::CWindowImpl<AccessibleHWND, | |
| 37 ATL::CWindow, | |
| 38 ATL::CWinTraits<WS_CHILD> > { | |
| 39 public: | |
| 40 // Unfortunately, some screen readers look for this exact window class | |
| 41 // to enable certain features. It'd be great to remove this. | |
| 42 DECLARE_WND_CLASS_EX(L"Chrome_RenderWidgetHostHWND", CS_DBLCLKS, 0); | |
| 43 | |
| 44 BEGIN_MSG_MAP_EX(AccessibleHWND) | |
| 45 MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject) | |
| 46 END_MSG_MAP() | |
| 47 | |
| 48 AccessibleHWND(HWND parent, BrowserAccessibilityManagerWin* manager) | |
| 49 : manager_(manager) { | |
| 50 Create(parent); | |
| 51 ShowWindow(true); | |
| 52 MoveWindow(0, 0, 0, 0); | |
| 53 | |
| 54 HRESULT hr = ::CreateStdAccessibleObject( | |
| 55 hwnd(), OBJID_WINDOW, IID_IAccessible, | |
| 56 reinterpret_cast<void **>(window_accessible_.Receive())); | |
| 57 DCHECK(SUCCEEDED(hr)); | |
| 58 } | |
| 59 | |
| 60 HWND hwnd() { | |
| 61 DCHECK(::IsWindow(m_hWnd)); | |
| 62 return m_hWnd; | |
| 63 } | |
| 64 | |
| 65 IAccessible* window_accessible() { return window_accessible_; } | |
| 66 | |
| 67 void OnManagerDeleted() { | |
| 68 manager_ = NULL; | |
| 69 } | |
| 70 | |
| 71 protected: | |
| 72 virtual void OnFinalMessage(HWND hwnd) OVERRIDE { | |
| 73 if (manager_) | |
| 74 manager_->OnAccessibleHwndDeleted(); | |
| 75 delete this; | |
| 76 } | |
| 77 | |
| 78 private: | |
| 79 LRESULT OnGetObject(UINT message, | |
| 80 WPARAM w_param, | |
| 81 LPARAM l_param) { | |
| 82 if (OBJID_CLIENT != l_param || !manager_) | |
| 83 return static_cast<LRESULT>(0L); | |
| 84 | |
| 85 base::win::ScopedComPtr<IAccessible> root( | |
| 86 manager_->GetRoot()->ToBrowserAccessibilityWin()); | |
| 87 return LresultFromObject(IID_IAccessible, w_param, | |
| 88 static_cast<IAccessible*>(root.Detach())); | |
| 89 } | |
| 90 | |
| 91 BrowserAccessibilityManagerWin* manager_; | |
| 92 base::win::ScopedComPtr<IAccessible> window_accessible_; | |
| 93 | |
| 94 DISALLOW_COPY_AND_ASSIGN(AccessibleHWND); | |
| 95 }; | |
| 96 | |
| 97 | |
| 98 // static | 23 // static |
| 99 BrowserAccessibilityManager* BrowserAccessibilityManager::Create( | 24 BrowserAccessibilityManager* BrowserAccessibilityManager::Create( |
| 100 const ui::AXNodeData& src, | 25 const ui::AXNodeData& src, |
| 101 BrowserAccessibilityDelegate* delegate, | 26 BrowserAccessibilityDelegate* delegate, |
| 102 BrowserAccessibilityFactory* factory) { | 27 BrowserAccessibilityFactory* factory) { |
| 103 return new BrowserAccessibilityManagerWin( | 28 return new BrowserAccessibilityManagerWin( |
| 104 GetDesktopWindow(), NULL, src, delegate, factory); | 29 new content::LegacyRenderWidgetHostHWND(GetDesktopWindow()), NULL, src, |
| 30 delegate, factory); | |
| 105 } | 31 } |
| 106 | 32 |
| 107 BrowserAccessibilityManagerWin* | 33 BrowserAccessibilityManagerWin* |
| 108 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { | 34 BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { |
| 109 return static_cast<BrowserAccessibilityManagerWin*>(this); | 35 return static_cast<BrowserAccessibilityManagerWin*>(this); |
| 110 } | 36 } |
| 111 | 37 |
| 112 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( | 38 BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( |
| 113 HWND parent_hwnd, | 39 LegacyRenderWidgetHostHWND* accessible_hwnd, |
| 114 IAccessible* parent_iaccessible, | 40 IAccessible* parent_iaccessible, |
| 115 const ui::AXNodeData& src, | 41 const ui::AXNodeData& src, |
| 116 BrowserAccessibilityDelegate* delegate, | 42 BrowserAccessibilityDelegate* delegate, |
| 117 BrowserAccessibilityFactory* factory) | 43 BrowserAccessibilityFactory* factory) |
| 118 : BrowserAccessibilityManager(src, delegate, factory), | 44 : BrowserAccessibilityManager(src, delegate, factory), |
| 119 parent_hwnd_(parent_hwnd), | 45 parent_hwnd_(accessible_hwnd->parent()), |
| 120 parent_iaccessible_(parent_iaccessible), | 46 parent_iaccessible_(parent_iaccessible), |
| 121 tracked_scroll_object_(NULL), | 47 tracked_scroll_object_(NULL), |
| 122 accessible_hwnd_(NULL) { | 48 accessible_hwnd_(accessible_hwnd) { |
| 123 } | 49 } |
| 124 | 50 |
| 125 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { | 51 BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { |
| 126 if (tracked_scroll_object_) { | 52 if (tracked_scroll_object_) { |
| 127 tracked_scroll_object_->Release(); | 53 tracked_scroll_object_->Release(); |
| 128 tracked_scroll_object_ = NULL; | 54 tracked_scroll_object_ = NULL; |
| 129 } | 55 } |
| 130 if (accessible_hwnd_) | 56 if (accessible_hwnd_) |
| 131 accessible_hwnd_->OnManagerDeleted(); | 57 accessible_hwnd_->OnManagerDeleted(); |
| 132 } | 58 } |
| 133 | 59 |
| 134 // static | 60 // static |
| 135 ui::AXNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() { | 61 ui::AXNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() { |
| 136 ui::AXNodeData empty_document; | 62 ui::AXNodeData empty_document; |
| 137 empty_document.id = 0; | 63 empty_document.id = 0; |
| 138 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; | 64 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; |
| 139 empty_document.state = | 65 empty_document.state = |
| 140 (1 << blink::WebAXStateEnabled) | | 66 (1 << blink::WebAXStateEnabled) | |
| 141 (1 << ui::AX_STATE_READONLY) | | 67 (1 << ui::AX_STATE_READONLY) | |
| 142 (1 << ui::AX_STATE_BUSY); | 68 (1 << ui::AX_STATE_BUSY); |
| 143 return empty_document; | 69 return empty_document; |
| 144 } | 70 } |
| 145 | 71 |
| 146 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, | 72 void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, |
| 147 LONG child_id) { | 73 LONG child_id) { |
| 148 // Don't fire events if this view isn't hooked up to its parent. | 74 // Don't fire events if this view isn't hooked up to its parent. |
| 149 if (!parent_iaccessible()) | 75 if (!parent_iaccessible()) |
| 150 return; | 76 return; |
| 151 | 77 |
| 152 // If on Win 7 and complete accessibility is enabled, create a fake child HWND | 78 // If on Win 7 and complete accessibility is enabled, use the fake child HWND |
| 153 // to use as the root of the accessibility tree. See comments above | 79 // to use as the root of the accessibility tree. See comments above |
| 154 // AccessibleHWND for details. | 80 // LegacyRenderWidgetHostHWND for details. |
| 155 if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser() && | 81 if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser()) { |
| 156 !accessible_hwnd_) { | 82 DCHECK(accessible_hwnd_); |
| 157 accessible_hwnd_ = new AccessibleHWND(parent_hwnd_, this); | 83 accessible_hwnd_->set_browser_accessibility_manager(this); |
| 158 parent_hwnd_ = accessible_hwnd_->hwnd(); | 84 parent_hwnd_ = accessible_hwnd_->hwnd(); |
| 159 parent_iaccessible_ = accessible_hwnd_->window_accessible(); | 85 parent_iaccessible_ = accessible_hwnd_->window_accessible(); |
| 160 } | 86 } |
| 161 | |
| 162 ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id); | 87 ::NotifyWinEvent(event, parent_hwnd(), OBJID_CLIENT, child_id); |
| 163 } | 88 } |
| 164 | 89 |
| 165 void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) { | 90 void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) { |
| 166 BrowserAccessibilityManager::AddNodeToMap(node); | 91 BrowserAccessibilityManager::AddNodeToMap(node); |
| 167 LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win(); | 92 LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win(); |
| 168 unique_id_to_renderer_id_map_[unique_id_win] = node->renderer_id(); | 93 unique_id_to_renderer_id_map_[unique_id_win] = node->renderer_id(); |
| 169 } | 94 } |
| 170 | 95 |
| 171 void BrowserAccessibilityManagerWin::RemoveNode(BrowserAccessibility* node) { | 96 void BrowserAccessibilityManagerWin::RemoveNode(BrowserAccessibility* node) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 // |parent_iaccessible_| are no longer valid either, since they were | 236 // |parent_iaccessible_| are no longer valid either, since they were |
| 312 // derived from AccessibleHWND. We don't have to restore them to | 237 // derived from AccessibleHWND. We don't have to restore them to |
| 313 // previous values, though, because this should only happen | 238 // previous values, though, because this should only happen |
| 314 // during the destruct sequence for this window. | 239 // during the destruct sequence for this window. |
| 315 accessible_hwnd_ = NULL; | 240 accessible_hwnd_ = NULL; |
| 316 parent_hwnd_ = NULL; | 241 parent_hwnd_ = NULL; |
| 317 parent_iaccessible_ = NULL; | 242 parent_iaccessible_ = NULL; |
| 318 } | 243 } |
| 319 | 244 |
| 320 } // namespace content | 245 } // namespace content |
| OLD | NEW |