From 383cfbd691e27ab109f8a3a67abdc1205df3687b Mon Sep 17 00:00:00 2001 From: "dmazzoni@chromium.org" Date: Wed, 16 Jun 2010 15:16:39 +0000 Subject: Rename browser_accessibility to browser_accessibility_win, and same for browser_accessibility_manager, to make it more clear that these are Windows-only source files. BUG=none TEST=none Review URL: http://codereview.chromium.org/2830005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49947 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/browser_accessibility.cc | 1013 -------------------- chrome/browser/browser_accessibility.h | 399 -------- chrome/browser/browser_accessibility_manager.cc | 151 --- chrome/browser/browser_accessibility_manager.h | 120 --- .../browser/browser_accessibility_manager_win.cc | 151 +++ chrome/browser/browser_accessibility_manager_win.h | 120 +++ chrome/browser/browser_accessibility_unittest.cc | 111 --- chrome/browser/browser_accessibility_win.cc | 1013 ++++++++++++++++++++ chrome/browser/browser_accessibility_win.h | 399 ++++++++ .../browser/browser_accessibility_win_unittest.cc | 111 +++ chrome/browser/renderer_host/render_view_host.cc | 2 +- .../renderer_host/render_widget_host_view_win.cc | 4 +- .../renderer_host/render_widget_host_view_win.h | 2 +- chrome/chrome_browser.gypi | 12 +- chrome/chrome_tests.gypi | 4 +- 15 files changed, 1806 insertions(+), 1806 deletions(-) delete mode 100644 chrome/browser/browser_accessibility.cc delete mode 100644 chrome/browser/browser_accessibility.h delete mode 100644 chrome/browser/browser_accessibility_manager.cc delete mode 100644 chrome/browser/browser_accessibility_manager.h create mode 100644 chrome/browser/browser_accessibility_manager_win.cc create mode 100644 chrome/browser/browser_accessibility_manager_win.h delete mode 100644 chrome/browser/browser_accessibility_unittest.cc create mode 100644 chrome/browser/browser_accessibility_win.cc create mode 100644 chrome/browser/browser_accessibility_win.h create mode 100644 chrome/browser/browser_accessibility_win_unittest.cc diff --git a/chrome/browser/browser_accessibility.cc b/chrome/browser/browser_accessibility.cc deleted file mode 100644 index 6471faf..0000000 --- a/chrome/browser/browser_accessibility.cc +++ /dev/null @@ -1,1013 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_accessibility.h" - -#include "base/logging.h" -#include "chrome/browser/browser_accessibility_manager.h" - -using webkit_glue::WebAccessibility; - -BrowserAccessibility::BrowserAccessibility() - : manager_(NULL), - parent_(NULL), - child_id_(-1), - index_in_parent_(-1), - renderer_id_(-1), - instance_active_(false) { -} - -BrowserAccessibility::~BrowserAccessibility() { - InactivateTree(); -} - -void BrowserAccessibility::Initialize( - BrowserAccessibilityManager* manager, - BrowserAccessibility* parent, - LONG child_id, - LONG index_in_parent, - const webkit_glue::WebAccessibility& src) { - manager_ = manager; - parent_ = parent; - child_id_ = child_id; - index_in_parent_ = index_in_parent; - - renderer_id_ = src.id; - name_ = src.name; - value_ = src.value; - attributes_ = src.attributes; - location_ = src.location; - InitRoleAndState(src.role, src.state); - - // If this object doesn't have a name but it does have a description, - // use the description as its name - because some screen readers only - // announce the name. - if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { - GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); - } - - instance_active_ = true; -} - -void BrowserAccessibility::AddChild(BrowserAccessibility* child) { - children_.push_back(child); -} - -void BrowserAccessibility::InactivateTree() { - // Mark this object as inactive, so calls to all COM methods will return - // failure. - instance_active_ = false; - - // Now we can safely call InactivateTree on our children and remove - // references to them, so that as much of the tree as possible will be - // destroyed now - however, nodes that still have references to them - // might stick around a while until all clients have released them. - for (std::vector::iterator iter = - children_.begin(); - iter != children_.end(); ++iter) { - (*iter)->InactivateTree(); - (*iter)->Release(); - } - children_.clear(); -} - -bool BrowserAccessibility::IsDescendantOf(BrowserAccessibility* ancestor) { - if (this == ancestor) { - return true; - } else if (parent_) { - return parent_->IsDescendantOf(ancestor); - } - - return false; -} - -BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { - if (parent_ && index_in_parent_ > 0) - return parent_->children_[index_in_parent_ - 1]; - - return NULL; -} - -BrowserAccessibility* BrowserAccessibility::GetNextSibling() { - if (parent_ && - index_in_parent_ < static_cast(parent_->children_.size() - 1)) { - return parent_->children_[index_in_parent_ + 1]; - } - - return NULL; -} - -BrowserAccessibility* BrowserAccessibility::NewReference() { - AddRef(); - return this; -} - -// -// IAccessible methods. -// -// Conventions: -// * Always test for instance_active_ first and return E_FAIL if it's false. -// * Always check for invalid arguments first, even if they're unused. -// * Return S_FALSE if the only output is a string argument and it's empty. -// - -HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { - if (!instance_active_) - return E_FAIL; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - manager_->DoDefaultAction(*target); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, - VARIANT* child) { - if (!instance_active_) - return E_FAIL; - - if (!child) - return E_INVALIDARG; - - return E_NOTIMPL; -} - -STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, - LONG* width, LONG* height, - VARIANT var_id) { - if (!instance_active_) - return E_FAIL; - - if (!x_left || !y_top || !width || !height) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - // Find the top left corner of the containing window in screen coords, and - // adjust the output position by this amount. - HWND parent_hwnd = manager_->GetParentHWND(); - POINT top_left = {0, 0}; - ::ClientToScreen(parent_hwnd, &top_left); - - *x_left = target->location_.x + top_left.x; - *y_top = target->location_.y + top_left.y; - *width = target->location_.width; - *height = target->location_.height; - - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::accNavigate( - LONG nav_dir, VARIANT start, VARIANT* end) { - BrowserAccessibility* target = GetTargetFromChildID(start); - if (!target) - return E_INVALIDARG; - - if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && - start.lVal != CHILDID_SELF) { - // MSAA states that navigating to first/last child can only be from self. - return E_INVALIDARG; - } - - BrowserAccessibility* result = NULL; - switch (nav_dir) { - case NAVDIR_DOWN: - case NAVDIR_UP: - case NAVDIR_LEFT: - case NAVDIR_RIGHT: - // These directions are not implemented, matching Mozilla and IE. - return E_NOTIMPL; - case NAVDIR_FIRSTCHILD: - if (target->children_.size() > 0) - result = target->children_[0]; - break; - case NAVDIR_LASTCHILD: - if (target->children_.size() > 0) - result = target->children_[target->children_.size() - 1]; - break; - case NAVDIR_NEXT: - result = target->GetNextSibling(); - break; - case NAVDIR_PREVIOUS: - result = target->GetPreviousSibling(); - break; - } - - if (!result) { - end->vt = VT_EMPTY; - return S_FALSE; - } - - end->vt = VT_DISPATCH; - end->pdispVal = result->NewReference(); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, - IDispatch** disp_child) { - if (!instance_active_) - return E_FAIL; - - if (!disp_child) - return E_INVALIDARG; - - *disp_child = NULL; - - BrowserAccessibility* target = GetTargetFromChildID(var_child); - if (!target) - return E_INVALIDARG; - - (*disp_child) = target->NewReference(); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { - if (!instance_active_) - return E_FAIL; - - if (!child_count) - return E_INVALIDARG; - - *child_count = children_.size(); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, - BSTR* def_action) { - if (!instance_active_) - return E_FAIL; - - if (!def_action) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - string16 action; - if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &action)) - return S_FALSE; - - if (action.empty()) - return S_FALSE; - - *def_action = SysAllocString(action.c_str()); - - DCHECK(*def_action); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, - BSTR* desc) { - if (!instance_active_) - return E_FAIL; - - if (!desc) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - string16 description; - if (!target->GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) - return S_FALSE; - - if (description.empty()) - return S_FALSE; - - *desc = SysAllocString(description.c_str()); - - DCHECK(*desc); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { - if (!instance_active_) - return E_FAIL; - - if (!focus_child) - return E_INVALIDARG; - - BrowserAccessibility* focus = manager_->GetFocus(this); - if (focus == this) { - focus_child->vt = VT_I4; - focus_child->lVal = CHILDID_SELF; - } else if (focus == NULL) { - focus_child->vt = VT_EMPTY; - } else { - focus_child->vt = VT_DISPATCH; - focus_child->pdispVal = focus->NewReference(); - } - - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { - if (!instance_active_) - return E_FAIL; - - if (!help) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - string16 help_str; - if (!target->GetAttribute(WebAccessibility::ATTR_HELP, &help_str)) - return S_FALSE; - - if (help_str.empty()) - return S_FALSE; - - *help = SysAllocString(help_str.c_str()); - - DCHECK(*help); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, - BSTR* acc_key) { - if (!instance_active_) - return E_FAIL; - - if (!acc_key) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - string16 shortcut; - if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &shortcut)) - return S_FALSE; - - if (shortcut.empty()) - return S_FALSE; - - *acc_key = SysAllocString(shortcut.c_str()); - - DCHECK(*acc_key); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { - if (!instance_active_) - return E_FAIL; - - if (!name) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - if (target->name_.empty()) - return S_FALSE; - - *name = SysAllocString(target->name_.c_str()); - - DCHECK(*name); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { - if (!instance_active_) - return E_FAIL; - - if (!disp_parent) - return E_INVALIDARG; - - IAccessible* parent = parent_; - if (parent == NULL) { - // This happens if we're the root of the tree; - // return the IAccessible for the window. - parent = manager_->GetParentWindowIAccessible(); - } - - parent->AddRef(); - *disp_parent = parent; - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { - if (!instance_active_) - return E_FAIL; - - if (!role) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - if (!target->role_name_.empty()) { - role->vt = VT_BSTR; - role->bstrVal = SysAllocString(target->role_name_.c_str()); - } else { - role->vt = VT_I4; - role->lVal = target->role_; - } - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, - VARIANT* state) { - if (!instance_active_) - return E_FAIL; - - if (!state) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - state->vt = VT_I4; - state->lVal = target->state_; - if (manager_->GetFocus(NULL) == this) - state->lVal |= STATE_SYSTEM_FOCUSED; - - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { - if (!instance_active_) - return E_FAIL; - - if (!value) - return E_INVALIDARG; - - BrowserAccessibility* target = GetTargetFromChildID(var_id); - if (!target) - return E_INVALIDARG; - - *value = SysAllocString(target->value_.c_str()); - - DCHECK(*value); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, - VARIANT var_id, - LONG* topic_id) { - return E_NOTIMPL; -} - -STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { - if (!instance_active_) - return E_FAIL; - - return E_NOTIMPL; -} - -STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_sel, VARIANT var_id) { - if (!instance_active_) - return E_FAIL; - - if (flags_sel & SELFLAG_TAKEFOCUS) { - manager_->SetFocus(*this); - return S_OK; - } - - return S_FALSE; -} - -// -// IAccessible2 methods. -// - -STDMETHODIMP BrowserAccessibility::role(LONG* role) { - if (!instance_active_) - return E_FAIL; - - if (!role) - return E_INVALIDARG; - - *role = ia2_role_; - - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { - if (!instance_active_) - return E_FAIL; - - if (!attributes) - return E_INVALIDARG; - - return S_FALSE; -} - -STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { - if (!instance_active_) - return E_FAIL; - - if (!states) - return E_INVALIDARG; - - *states = ia2_state_; - - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_uniqueID(LONG* unique_id) { - if (!instance_active_) - return E_FAIL; - - if (!unique_id) - return E_INVALIDARG; - - *unique_id = child_id_; - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_windowHandle(HWND* window_handle) { - if (!instance_active_) - return E_FAIL; - - if (!window_handle) - return E_INVALIDARG; - - *window_handle = manager_->GetParentHWND(); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_indexInParent(LONG* index_in_parent) { - if (!instance_active_) - return E_FAIL; - - if (!index_in_parent) - return E_INVALIDARG; - - *index_in_parent = index_in_parent_; - return S_OK; -} - -// -// IAccessibleImage methods. -// - -STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { - if (!instance_active_) - return E_FAIL; - - if (!desc) - return E_INVALIDARG; - - string16 description; - if (!GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) - return S_FALSE; - - if (description.empty()) - return S_FALSE; - - *desc = SysAllocString(description.c_str()); - - DCHECK(*desc); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_imagePosition( - enum IA2CoordinateType coordinate_type, long* x, long* y) { - if (!instance_active_) - return E_FAIL; - - if (!x || !y) - return E_INVALIDARG; - - if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { - HWND parent_hwnd = manager_->GetParentHWND(); - POINT top_left = {0, 0}; - ::ClientToScreen(parent_hwnd, &top_left); - *x = location_.x + top_left.x; - *y = location_.y + top_left.y; - } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { - *x = location_.x; - *y = location_.y; - if (parent_) { - *x -= parent_->location_.x; - *y -= parent_->location_.y; - } - } else { - return E_INVALIDARG; - } - - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_imageSize(long* height, long* width) { - if (!instance_active_) - return E_FAIL; - - if (!height || !width) - return E_INVALIDARG; - - *height = location_.height; - *width = location_.width; - return S_OK; -} - -// -// IAccessibleText methods. -// - -STDMETHODIMP BrowserAccessibility::get_nCharacters(long* n_characters) { - if (!instance_active_) - return E_FAIL; - - if (!n_characters) - return E_INVALIDARG; - - *n_characters = name_.length(); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_text( - long start_offset, long end_offset, BSTR* text) { - if (!instance_active_) - return E_FAIL; - - if (!text) - return E_INVALIDARG; - - long len = name_.length(); - if (start_offset < 0) - start_offset = 0; - if (end_offset > len) - end_offset = len; - - *text = SysAllocString( - name_.substr(start_offset, end_offset - start_offset).c_str()); - return S_OK; -} - -STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { - *offset = 0; - return S_OK; -} - -// -// IServiceProvider methods. -// - -STDMETHODIMP BrowserAccessibility::QueryService( - REFGUID guidService, REFIID riid, void** object) { - if (!instance_active_) - return E_FAIL; - - if (guidService == IID_IAccessible || guidService == IID_IAccessible2) - return QueryInterface(riid, object); - - *object = NULL; - return E_FAIL; -} - -// -// CComObjectRootEx methods. -// - -HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( - void* this_ptr, - const _ATL_INTMAP_ENTRY* entries, - REFIID iid, - void** object) { - if (iid == IID_IAccessibleText) { - if (role_ != ROLE_SYSTEM_LINK) { - *object = NULL; - return E_NOINTERFACE; - } - } else if (iid == IID_IAccessibleImage) { - if (role_ != ROLE_SYSTEM_GRAPHIC) { - *object = NULL; - return E_NOINTERFACE; - } - } - - return CComObjectRootBase::InternalQueryInterface( - this_ptr, entries, iid, object); -} - -// -// Private methods. -// - -BrowserAccessibility* BrowserAccessibility::GetTargetFromChildID( - const VARIANT& var_id) { - if (var_id.vt != VT_I4) - return NULL; - - LONG child_id = var_id.lVal; - if (child_id == CHILDID_SELF) - return this; - - if (child_id >= 1 && child_id <= static_cast(children_.size())) - return children_[child_id - 1]; - - return manager_->GetFromChildID(child_id); -} - -bool BrowserAccessibility::HasAttribute(WebAccessibility::Attribute attribute) { - return (attributes_.find(attribute) != attributes_.end()); -} - -bool BrowserAccessibility::GetAttribute( - WebAccessibility::Attribute attribute, string16* value) { - std::map::iterator iter = attributes_.find(attribute); - if (iter != attributes_.end()) { - *value = iter->second; - return true; - } - - return false; -} - -void BrowserAccessibility::InitRoleAndState(LONG web_role, - LONG web_state) { - state_ = 0; - ia2_state_ = IA2_STATE_OPAQUE; - - if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) - state_ |= STATE_SYSTEM_CHECKED; - if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) - state_ |= STATE_SYSTEM_FOCUSABLE; - if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) - state_ |= STATE_SYSTEM_HOTTRACKED; - if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) - state_ |= STATE_SYSTEM_INDETERMINATE; - if ((web_state >> WebAccessibility::STATE_LINKED) & 1) - state_ |= STATE_SYSTEM_LINKED; - if ((web_state >> WebAccessibility::STATE_MULTISELECTABLE) & 1) - state_ |= STATE_SYSTEM_MULTISELECTABLE; - if ((web_state >> WebAccessibility::STATE_OFFSCREEN) & 1) - state_ |= STATE_SYSTEM_OFFSCREEN; - if ((web_state >> WebAccessibility::STATE_PRESSED) & 1) - state_ |= STATE_SYSTEM_PRESSED; - if ((web_state >> WebAccessibility::STATE_PROTECTED) & 1) - state_ |= STATE_SYSTEM_PROTECTED; - if ((web_state >> WebAccessibility::STATE_READONLY) & 1) - state_ |= STATE_SYSTEM_READONLY; - if ((web_state >> WebAccessibility::STATE_TRAVERSED) & 1) - state_ |= STATE_SYSTEM_TRAVERSED; - if ((web_state >> WebAccessibility::STATE_UNAVAILABLE) & 1) - state_ |= STATE_SYSTEM_UNAVAILABLE; - - role_ = 0; - ia2_role_ = 0; - switch (web_role) { - case WebAccessibility::ROLE_ALERT: - case WebAccessibility::ROLE_ALERT_DIALOG: - role_ = ROLE_SYSTEM_ALERT; - break; - case WebAccessibility::ROLE_APPLICATION: - role_ = ROLE_SYSTEM_APPLICATION; - break; - case WebAccessibility::ROLE_ARTICLE: - role_ = ROLE_SYSTEM_GROUPING; - ia2_role_ = IA2_ROLE_SECTION; - break; - case WebAccessibility::ROLE_BUTTON: - role_ = ROLE_SYSTEM_PUSHBUTTON; - break; - case WebAccessibility::ROLE_CELL: - role_ = ROLE_SYSTEM_CELL; - break; - case WebAccessibility::ROLE_CHECKBOX: - role_ = ROLE_SYSTEM_CHECKBUTTON; - break; - case WebAccessibility::ROLE_COLOR_WELL: - role_ = ROLE_SYSTEM_CLIENT; - ia2_role_ = IA2_ROLE_COLOR_CHOOSER; - break; - case WebAccessibility::ROLE_COLUMN: - role_ = ROLE_SYSTEM_COLUMN; - break; - case WebAccessibility::ROLE_COLUMN_HEADER: - role_ = ROLE_SYSTEM_COLUMNHEADER; - break; - case WebAccessibility::ROLE_COMBO_BOX: - role_ = ROLE_SYSTEM_COMBOBOX; - break; - case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: - role_name_ = L"dd"; - ia2_role_ = IA2_ROLE_PARAGRAPH; - break; - case WebAccessibility::ROLE_DEFINITION_LIST_TERM: - role_ = ROLE_SYSTEM_LISTITEM; - break; - case WebAccessibility::ROLE_DIALOG: - role_ = ROLE_SYSTEM_DIALOG; - break; - case WebAccessibility::ROLE_DOCUMENT: - case WebAccessibility::ROLE_WEB_AREA: - role_ = ROLE_SYSTEM_DOCUMENT; - state_ |= STATE_SYSTEM_READONLY; - state_ |= STATE_SYSTEM_FOCUSABLE; - break; - case WebAccessibility::ROLE_EDITABLE_TEXT: - role_ = ROLE_SYSTEM_TEXT; - ia2_state_ |= IA2_STATE_SINGLE_LINE; - ia2_state_ |= IA2_STATE_EDITABLE; - break; - case WebAccessibility::ROLE_GRID: - role_ = ROLE_SYSTEM_TABLE; - break; - case WebAccessibility::ROLE_GROUP: - role_name_ = L"div"; - ia2_role_ = IA2_ROLE_SECTION; - break; - case WebAccessibility::ROLE_HEADING: - // TODO(dmazzoni): support all heading levels - role_name_ = L"h1"; - ia2_role_ = IA2_ROLE_HEADING; - break; - case WebAccessibility::ROLE_IMAGE: - role_ = ROLE_SYSTEM_GRAPHIC; - break; - case WebAccessibility::ROLE_IMAGE_MAP: - role_name_ = L"map"; - ia2_role_ = IA2_ROLE_IMAGE_MAP; - break; - case WebAccessibility::ROLE_IMAGE_MAP_LINK: - role_ = ROLE_SYSTEM_LINK; - state_ |= STATE_SYSTEM_LINKED; - break; - case WebAccessibility::ROLE_LANDMARK_APPLICATION: - case WebAccessibility::ROLE_LANDMARK_BANNER: - case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: - case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: - case WebAccessibility::ROLE_LANDMARK_MAIN: - case WebAccessibility::ROLE_LANDMARK_NAVIGATION: - case WebAccessibility::ROLE_LANDMARK_SEARCH: - role_ = ROLE_SYSTEM_GROUPING; - ia2_role_ = IA2_ROLE_SECTION; - break; - case WebAccessibility::ROLE_LINK: - case WebAccessibility::ROLE_WEBCORE_LINK: - role_ = ROLE_SYSTEM_LINK; - state_ |= STATE_SYSTEM_LINKED; - break; - case WebAccessibility::ROLE_LIST: - role_ = ROLE_SYSTEM_LIST; - break; - case WebAccessibility::ROLE_LISTBOX: - role_ = ROLE_SYSTEM_LIST; - break; - case WebAccessibility::ROLE_LISTBOX_OPTION: - case WebAccessibility::ROLE_LIST_ITEM: - case WebAccessibility::ROLE_LIST_MARKER: - role_ = ROLE_SYSTEM_LISTITEM; - break; - case WebAccessibility::ROLE_MENU: - case WebAccessibility::ROLE_MENU_BUTTON: - role_ = ROLE_SYSTEM_MENUPOPUP; - break; - case WebAccessibility::ROLE_MENU_BAR: - role_ = ROLE_SYSTEM_MENUBAR; - break; - case WebAccessibility::ROLE_MENU_ITEM: - case WebAccessibility::ROLE_MENU_LIST_OPTION: - role_ = ROLE_SYSTEM_MENUITEM; - break; - case WebAccessibility::ROLE_MENU_LIST_POPUP: - role_ = ROLE_SYSTEM_MENUPOPUP; - break; - case WebAccessibility::ROLE_NOTE: - role_ = ROLE_SYSTEM_GROUPING; - ia2_role_ = IA2_ROLE_NOTE; - break; - case WebAccessibility::ROLE_OUTLINE: - role_ = ROLE_SYSTEM_OUTLINE; - break; - case WebAccessibility::ROLE_POPUP_BUTTON: - role_ = ROLE_SYSTEM_COMBOBOX; - break; - case WebAccessibility::ROLE_PROGRESS_INDICATOR: - role_ = ROLE_SYSTEM_PROGRESSBAR; - break; - case WebAccessibility::ROLE_RADIO_BUTTON: - role_ = ROLE_SYSTEM_RADIOBUTTON; - break; - case WebAccessibility::ROLE_RADIO_GROUP: - role_ = ROLE_SYSTEM_GROUPING; - ia2_role_ = IA2_ROLE_SECTION; - break; - case WebAccessibility::ROLE_REGION: - role_ = ROLE_SYSTEM_GROUPING; - ia2_role_ = IA2_ROLE_SECTION; - break; - case WebAccessibility::ROLE_ROW: - role_ = ROLE_SYSTEM_ROW; - break; - case WebAccessibility::ROLE_ROW_HEADER: - role_ = ROLE_SYSTEM_ROWHEADER; - break; - case WebAccessibility::ROLE_RULER: - role_ = ROLE_SYSTEM_CLIENT; - ia2_role_ = IA2_ROLE_RULER; - break; - case WebAccessibility::ROLE_SCROLLAREA: - role_ = ROLE_SYSTEM_CLIENT; - ia2_role_ = IA2_ROLE_SCROLL_PANE; - break; - case WebAccessibility::ROLE_SCROLLBAR: - role_ = ROLE_SYSTEM_SCROLLBAR; - break; - case WebAccessibility::ROLE_SLIDER: - role_ = ROLE_SYSTEM_SLIDER; - break; - case WebAccessibility::ROLE_SPLIT_GROUP: - role_ = ROLE_SYSTEM_CLIENT; - ia2_role_ = IA2_ROLE_SPLIT_PANE; - break; - case WebAccessibility::ROLE_ANNOTATION: - case WebAccessibility::ROLE_STATIC_TEXT: - role_ = ROLE_SYSTEM_TEXT; - break; - case WebAccessibility::ROLE_STATUS: - role_ = ROLE_SYSTEM_STATUSBAR; - break; - case WebAccessibility::ROLE_TAB: - role_ = ROLE_SYSTEM_PAGETAB; - break; - case WebAccessibility::ROLE_TABLE: - role_ = ROLE_SYSTEM_TABLE; - break; - case WebAccessibility::ROLE_TABLE_HEADER_CONTAINER: - role_ = ROLE_SYSTEM_GROUPING; - ia2_role_ = IA2_ROLE_SECTION; - break; - case WebAccessibility::ROLE_TAB_GROUP: - case WebAccessibility::ROLE_TAB_LIST: - case WebAccessibility::ROLE_TAB_PANEL: - role_ = ROLE_SYSTEM_PAGETABLIST; - break; - case WebAccessibility::ROLE_TEXTAREA: - role_ = ROLE_SYSTEM_TEXT; - ia2_state_ |= IA2_STATE_MULTI_LINE; - ia2_state_ |= IA2_STATE_EDITABLE; - break; - case WebAccessibility::ROLE_TEXT_FIELD: - role_ = ROLE_SYSTEM_TEXT; - ia2_state_ |= IA2_STATE_SINGLE_LINE; - ia2_state_ |= IA2_STATE_EDITABLE; - break; - case WebAccessibility::ROLE_TOOLBAR: - role_ = ROLE_SYSTEM_TOOLBAR; - break; - case WebAccessibility::ROLE_TOOLTIP: - role_ = ROLE_SYSTEM_TOOLTIP; - break; - case WebAccessibility::ROLE_TREE: - role_ = ROLE_SYSTEM_OUTLINE; - break; - case WebAccessibility::ROLE_TREE_GRID: - role_ = ROLE_SYSTEM_OUTLINE; - break; - case WebAccessibility::ROLE_TREE_ITEM: - role_ = ROLE_SYSTEM_OUTLINEITEM; - break; - case WebAccessibility::ROLE_WINDOW: - role_ = ROLE_SYSTEM_WINDOW; - break; - - // TODO(dmazzoni): figure out the proper MSAA role for all of these. - case WebAccessibility::ROLE_BROWSER: - case WebAccessibility::ROLE_BUSY_INDICATOR: - case WebAccessibility::ROLE_DIRECTORY: - case WebAccessibility::ROLE_DISCLOSURE_TRIANGLE: - case WebAccessibility::ROLE_DRAWER: - case WebAccessibility::ROLE_GROW_AREA: - case WebAccessibility::ROLE_HELP_TAG: - case WebAccessibility::ROLE_IGNORED: - case WebAccessibility::ROLE_INCREMENTOR: - case WebAccessibility::ROLE_LOG: - case WebAccessibility::ROLE_MARQUEE: - case WebAccessibility::ROLE_MATH: - case WebAccessibility::ROLE_MATTE: - case WebAccessibility::ROLE_RULER_MARKER: - case WebAccessibility::ROLE_SHEET: - case WebAccessibility::ROLE_SLIDER_THUMB: - case WebAccessibility::ROLE_SPLITTER: - case WebAccessibility::ROLE_SYSTEM_WIDE: - case WebAccessibility::ROLE_TIMER: - case WebAccessibility::ROLE_VALUE_INDICATOR: - default: - role_ = ROLE_SYSTEM_CLIENT; - break; - } - - // The role should always be set. - DCHECK(!role_name_.empty() || role_); - - // If we didn't explicitly set the IAccessible2 role, make it the same - // as the MSAA role. - if (!ia2_role_) - ia2_role_ = role_; -} diff --git a/chrome/browser/browser_accessibility.h b/chrome/browser/browser_accessibility.h deleted file mode 100644 index 1216d47..0000000 --- a/chrome/browser/browser_accessibility.h +++ /dev/null @@ -1,399 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_BROWSER_ACCESSIBILITY_H_ -#define CHROME_BROWSER_BROWSER_ACCESSIBILITY_H_ - -#include -#include -#include - -#include - -#include "base/scoped_comptr_win.h" -#include "chrome/browser/browser_accessibility_manager.h" -#include "ia2_api_all.h" // Generated -#include "webkit/glue/webaccessibility.h" - -using webkit_glue::WebAccessibility; - -//////////////////////////////////////////////////////////////////////////////// -// -// BrowserAccessibility -// -// Class implementing the MSAA IAccessible COM interface for the -// Browser-Renderer communication of MSAA information, providing accessibility -// to be used by screen readers and other assistive technology (AT). -// -//////////////////////////////////////////////////////////////////////////////// -class ATL_NO_VTABLE BrowserAccessibility - : public CComObjectRootEx, - public IDispatchImpl, - public IAccessibleImage, - public IAccessibleText, - public IServiceProvider { - public: - BEGIN_COM_MAP(BrowserAccessibility) - COM_INTERFACE_ENTRY2(IDispatch, IAccessible2) - COM_INTERFACE_ENTRY2(IAccessible, IAccessible2) - COM_INTERFACE_ENTRY(IAccessible2) - COM_INTERFACE_ENTRY(IAccessibleImage) - COM_INTERFACE_ENTRY(IAccessibleText) - COM_INTERFACE_ENTRY(IServiceProvider) - END_COM_MAP() - - BrowserAccessibility(); - - virtual ~BrowserAccessibility(); - - // Initialize this object and mark it as active. - void Initialize(BrowserAccessibilityManager* manager, - BrowserAccessibility* parent, - LONG child_id, - LONG index_in_parent, - const webkit_glue::WebAccessibility& src); - - // Add a child of this object. - void AddChild(BrowserAccessibility* child); - - // Mark this object as inactive, and remove references to all children. - // When no other clients hold any references to this object it will be - // deleted, and in the meantime, calls to any methods will return E_FAIL. - void InactivateTree(); - - // Return true if this object is equal to or a descendant of |ancestor|. - bool IsDescendantOf(BrowserAccessibility* ancestor); - - // Return the previous sibling of this object, or NULL if it's the first - // child of its parent. - BrowserAccessibility* GetPreviousSibling(); - - // Return the next sibling of this object, or NULL if it's the last child - // of its parent. - BrowserAccessibility* GetNextSibling(); - - // Accessors - LONG child_id() const { return child_id_; } - int32 renderer_id() const { return renderer_id_; } - - // Add one to the reference count and return the same object. Always - // use this method when returning a BrowserAccessibility object as - // an output parameter to a COM interface, never use it otherwise. - BrowserAccessibility* NewReference(); - - // - // IAccessible methods. - // - - // Performs the default action on a given object. - STDMETHODIMP accDoDefaultAction(VARIANT var_id); - - // Retrieves the child element or child object at a given point on the screen. - STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child); - - // Retrieves the specified object's current screen location. - STDMETHODIMP accLocation(LONG* x_left, - LONG* y_top, - LONG* width, - LONG* height, - VARIANT var_id); - - // Traverses to another UI element and retrieves the object. - STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end); - - // Retrieves an IDispatch interface pointer for the specified child. - STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child); - - // Retrieves the number of accessible children. - STDMETHODIMP get_accChildCount(LONG* child_count); - - // Retrieves a string that describes the object's default action. - STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action); - - // Retrieves the object's description. - STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc); - - // Retrieves the object that has the keyboard focus. - STDMETHODIMP get_accFocus(VARIANT* focus_child); - - // Retrieves the help information associated with the object. - STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help); - - // Retrieves the specified object's shortcut. - STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key); - - // Retrieves the name of the specified object. - STDMETHODIMP get_accName(VARIANT var_id, BSTR* name); - - // Retrieves the IDispatch interface of the object's parent. - STDMETHODIMP get_accParent(IDispatch** disp_parent); - - // Retrieves information describing the role of the specified object. - STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role); - - // Retrieves the current state of the specified object. - STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state); - - // Returns the value associated with the object. - STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value); - - // Make an object take focus or extend the selection. - STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id); - - STDMETHODIMP get_accHelpTopic(BSTR* help_file, - VARIANT var_id, - LONG* topic_id); - - STDMETHODIMP get_accSelection(VARIANT* selected); - - // Deprecated methods, not implemented. - STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) { - return E_NOTIMPL; - } - STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val) { - return E_NOTIMPL; - } - - // - // IAccessible2 methods. - // - - // Returns role from a longer list of possible roles. - STDMETHODIMP role(LONG* role); - - // Returns the state bitmask from a larger set of possible states. - STDMETHODIMP get_states(AccessibleStates* states); - - // Returns the attributes specific to this IAccessible2 object, - // such as a cell's formula. - STDMETHODIMP get_attributes(BSTR* attributes); - - // Get the unique ID of this object so that the client knows if it's - // been encountered previously. - STDMETHODIMP get_uniqueID(LONG* unique_id); - - // Get the window handle of the enclosing window. - STDMETHODIMP get_windowHandle(HWND* window_handle); - - // Get this object's index in its parent object. - STDMETHODIMP get_indexInParent(LONG* index_in_parent); - - // IAccessible2 methods not implemented. - STDMETHODIMP get_extendedRole(BSTR* extended_role) { - return E_NOTIMPL; - } - STDMETHODIMP get_nRelations(LONG* n_relations) { - return E_NOTIMPL; - } - STDMETHODIMP get_relation(LONG relation_index, - IAccessibleRelation** relation) { - return E_NOTIMPL; - } - STDMETHODIMP get_relations(LONG max_relations, - IAccessibleRelation** relations, - LONG* n_relations) { - return E_NOTIMPL; - } - STDMETHODIMP scrollTo(enum IA2ScrollType scroll_type) { - return E_NOTIMPL; - } - STDMETHODIMP scrollToPoint(enum IA2CoordinateType coordinate_type, - LONG x, - LONG y) { - return E_NOTIMPL; - } - STDMETHODIMP get_groupPosition(LONG* group_level, - LONG* similar_items_in_group, - LONG* position_in_group) { - return E_NOTIMPL; - } - STDMETHODIMP get_localizedExtendedRole(BSTR* localized_extended_role) { - return E_NOTIMPL; - } - STDMETHODIMP get_nExtendedStates(LONG* n_extended_states) { - return E_NOTIMPL; - } - STDMETHODIMP get_extendedStates(LONG max_extended_states, - BSTR** extended_states, - LONG* n_extended_states) { - return E_NOTIMPL; - } - STDMETHODIMP get_localizedExtendedStates(LONG max_localized_extended_states, - BSTR** localized_extended_states, - LONG* n_localized_extended_states) { - return E_NOTIMPL; - } - STDMETHODIMP get_locale(IA2Locale* locale) { - return E_NOTIMPL; - } - - // - // IAccessibleImage methods. - // - - STDMETHODIMP get_description(BSTR* description); - - STDMETHODIMP get_imagePosition(enum IA2CoordinateType coordinate_type, - long* x, long* y); - - STDMETHODIMP get_imageSize(long* height, long* width); - - // - // IAccessibleText methods. - // - - STDMETHODIMP get_nCharacters(long* n_characters); - - STDMETHODIMP get_text(long start_offset, long end_offset, BSTR* text); - - STDMETHODIMP get_caretOffset(long* offset); - - // IAccessibleText methods not implemented. - STDMETHODIMP addSelection(long start_offset, long end_offset) { - return E_NOTIMPL; - } - STDMETHODIMP get_attributes(long offset, long* start_offset, long* end_offset, - BSTR* text_attributes) { - return E_NOTIMPL; - } - STDMETHODIMP get_characterExtents(long offset, - enum IA2CoordinateType coord_type, - long* x, long* y, - long* width, long* height) { - return E_NOTIMPL; - } - STDMETHODIMP get_nSelections(long* n_selections) { - return E_NOTIMPL; - } - STDMETHODIMP get_offsetAtPoint(long x, long y, - enum IA2CoordinateType coord_type, - long* offset) { - return E_NOTIMPL; - } - STDMETHODIMP get_selection(long selection_index, - long* start_offset, - long* end_offset) { - return E_NOTIMPL; - } - STDMETHODIMP get_textBeforeOffset(long offset, - enum IA2TextBoundaryType boundary_type, - long* start_offset, long* end_offset, - BSTR* text) { - return E_NOTIMPL; - } - STDMETHODIMP get_textAfterOffset(long offset, - enum IA2TextBoundaryType boundary_type, - long* start_offset, long* end_offset, - BSTR* text) { - return E_NOTIMPL; - } - STDMETHODIMP get_textAtOffset(long offset, - enum IA2TextBoundaryType boundary_type, - long* start_offset, long* end_offset, - BSTR* text) { - return E_NOTIMPL; - } - STDMETHODIMP removeSelection(long selection_index) { - return E_NOTIMPL; - } - STDMETHODIMP setCaretOffset(long offset) { - return E_NOTIMPL; - } - STDMETHODIMP setSelection(long selection_index, - long start_offset, - long end_offset) { - return E_NOTIMPL; - } - STDMETHODIMP scrollSubstringTo(long start_index, - long end_index, - enum IA2ScrollType scroll_type) { - return E_NOTIMPL; - } - STDMETHODIMP scrollSubstringToPoint(long start_index, long end_index, - enum IA2CoordinateType coordinate_type, - long x, long y) { - return E_NOTIMPL; - } - STDMETHODIMP get_newText(IA2TextSegment* new_text) { - return E_NOTIMPL; - } - STDMETHODIMP get_oldText(IA2TextSegment* old_text) { - return E_NOTIMPL; - } - - // - // IServiceProvider methods. - // - - STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** object); - - // - // CComObjectRootEx methods. - // - - HRESULT WINAPI InternalQueryInterface(void* this_ptr, - const _ATL_INTMAP_ENTRY* entries, - REFIID iid, - void** object); - - private: - // Many MSAA methods take a var_id parameter indicating that the operation - // should be performed on a particular child ID, rather than this object. - // This method tries to figure out the target object from |var_id| and - // returns a pointer to the target object if it exists, otherwise NULL. - // Does not return a new reference. - BrowserAccessibility* GetTargetFromChildID(const VARIANT& var_id); - - // Initialize the role and state metadata from the role enum and state - // bitmasks defined in webkit/glue/webaccessibility.h. - void InitRoleAndState(LONG web_accessibility_role, - LONG web_accessibility_state); - - // Return true if this attribute is in the attributes map. - bool HasAttribute(WebAccessibility::Attribute attribute); - - // Retrieve the string value of an attribute from the attribute map and - // returns true if found. - bool GetAttribute(WebAccessibility::Attribute attribute, string16* value); - - // The manager of this tree of accessibility objects; needed for - // global operations like focus tracking. - BrowserAccessibilityManager* manager_; - // The parent of this object, may be NULL if we're the root object. - BrowserAccessibility* parent_; - // The ID of this object; globally unique within the browser process. - LONG child_id_; - // The index of this within its parent object. - LONG index_in_parent_; - // The ID of this object in the renderer process. - int32 renderer_id_; - - // The children of this object. - std::vector children_; - - // Accessibility metadata from the renderer, used to respond to MSAA - // events. - string16 name_; - string16 value_; - std::map attributes_; - - LONG role_; - LONG state_; - string16 role_name_; - LONG ia2_role_; - LONG ia2_state_; - WebKit::WebRect location_; - - // COM objects are reference-counted. When we're done with this object - // and it's removed from our accessibility tree, a client may still be - // holding onto a pointer to this object, so we mark it as inactive - // so that calls to any of this object's methods immediately return - // failure. - bool instance_active_; - - DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility); -}; - -#endif // CHROME_BROWSER_BROWSER_ACCESSIBILITY_H_ diff --git a/chrome/browser/browser_accessibility_manager.cc b/chrome/browser/browser_accessibility_manager.cc deleted file mode 100644 index d82c89b..0000000 --- a/chrome/browser/browser_accessibility_manager.cc +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_accessibility_manager.h" - -#include "base/scoped_comptr_win.h" -#include "chrome/browser/browser_accessibility.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/common/render_messages.h" - -using webkit_glue::WebAccessibility; - -// Factory method to create an instance of BrowserAccessibility -BrowserAccessibility* BrowserAccessibilityFactory::Create() { - CComObject* instance; - HRESULT hr = CComObject::CreateInstance(&instance); - DCHECK(SUCCEEDED(hr)); - return instance->NewReference(); -} - -// static -// Start child IDs at -1 and decrement each time, because clients use -// child IDs of 1, 2, 3, ... to access the children of an object by -// index, so we use negative IDs to clearly distinguish between indices -// and unique IDs. -LONG BrowserAccessibilityManager::next_child_id_ = -1; - -BrowserAccessibilityManager::BrowserAccessibilityManager( - HWND parent_hwnd, - const webkit_glue::WebAccessibility& src, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory) - : parent_hwnd_(parent_hwnd), - delegate_(delegate), - factory_(factory), - focus_(NULL) { - HRESULT hr = ::CreateStdAccessibleObject( - parent_hwnd_, OBJID_WINDOW, IID_IAccessible, - reinterpret_cast(&window_iaccessible_)); - DCHECK(SUCCEEDED(hr)); - root_ = CreateAccessibilityTree(NULL, src, 0); - if (!focus_) - focus_ = root_; -} - -BrowserAccessibilityManager::~BrowserAccessibilityManager() { - // Clients could still hold references to some nodes of the tree, so - // calling Inactivate will make sure that as many nodes as possible are - // released now, and remaining nodes are marked as inactive so that - // calls to any methods on them will return E_FAIL; - root_->InactivateTree(); - root_->Release(); -} - -BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { - return root_; -} - -BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID( - LONG child_id) { - base::hash_map::iterator iter = - child_id_map_.find(child_id); - if (iter != child_id_map_.end()) { - return iter->second; - } else { - return NULL; - } -} - -IAccessible* BrowserAccessibilityManager::GetParentWindowIAccessible() { - return window_iaccessible_; -} - -HWND BrowserAccessibilityManager::GetParentHWND() { - return parent_hwnd_; -} - -BrowserAccessibility* BrowserAccessibilityManager::GetFocus( - BrowserAccessibility* root) { - if (focus_ && (!root || focus_->IsDescendantOf(root))) - return focus_; - - return NULL; -} - -void BrowserAccessibilityManager::SetFocus(const BrowserAccessibility& node) { - if (delegate_) - delegate_->SetAccessibilityFocus(node.renderer_id()); -} - -void BrowserAccessibilityManager::DoDefaultAction( - const BrowserAccessibility& node) { - if (delegate_) - delegate_->AccessibilityDoDefaultAction(node.renderer_id()); -} - -void BrowserAccessibilityManager::OnAccessibilityFocusChange(int renderer_id) { - base::hash_map::iterator iter = - renderer_id_to_child_id_map_.find(renderer_id); - if (iter == renderer_id_to_child_id_map_.end()) - return; - - LONG child_id = iter->second; - base::hash_map::iterator uniq_iter = - child_id_map_.find(child_id); - if (uniq_iter != child_id_map_.end()) - focus_ = uniq_iter->second; - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); -} - -void BrowserAccessibilityManager::OnAccessibilityObjectStateChange( - int renderer_id) { - base::hash_map::iterator iter = - renderer_id_to_child_id_map_.find(renderer_id); - if (iter == renderer_id_to_child_id_map_.end()) - return; - - LONG child_id = iter->second; - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); -} - -BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( - BrowserAccessibility* parent, - const webkit_glue::WebAccessibility& src, - int index_in_parent) { - BrowserAccessibility* instance = factory_->Create(); - - // Get the next child ID, and wrap around when we get near the end - // of a 32-bit integer range. It's okay to wrap around; we just want - // to avoid it as long as possible because clients may cache the ID of - // an object for a while to determine if they've seen it before. - LONG child_id = next_child_id_; - next_child_id_--; - if (next_child_id_ == -2000000000) - next_child_id_ = -1; - - instance->Initialize(this, parent, child_id, index_in_parent, src); - child_id_map_[child_id] = instance; - renderer_id_to_child_id_map_[src.id] = child_id; - if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) - focus_ = instance; - for (int i = 0; i < static_cast(src.children.size()); ++i) { - BrowserAccessibility* child = CreateAccessibilityTree( - instance, src.children[i], i); - instance->AddChild(child); - } - - return instance; -} diff --git a/chrome/browser/browser_accessibility_manager.h b/chrome/browser/browser_accessibility_manager.h deleted file mode 100644 index f9e0491..0000000 --- a/chrome/browser/browser_accessibility_manager.h +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_ -#define CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_ - -#include -#include -#include - -#include - -#include "base/hash_tables.h" -#include "base/scoped_comptr_win.h" -#include "base/scoped_ptr.h" -#include "webkit/glue/webaccessibility.h" - -class BrowserAccessibility; -class RenderProcessHost; -class RenderWidgetHost; - -class BrowserAccessibilityFactory { - public: - virtual ~BrowserAccessibilityFactory() {} - - // Create an instance of BrowserAccessibility and return a new - // reference to it. - virtual BrowserAccessibility* Create(); -}; - -// Class that can perform actions on behalf of the BrowserAccessibilityManager. -class BrowserAccessibilityDelegate { - public: - virtual ~BrowserAccessibilityDelegate() {} - virtual void SetAccessibilityFocus(int acc_obj_id) = 0; - virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0; -}; - -// Manages a tree of BrowserAccessibility objects. -class BrowserAccessibilityManager { - public: - BrowserAccessibilityManager( - HWND parent_hwnd, - const webkit_glue::WebAccessibility& src, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); - - virtual ~BrowserAccessibilityManager(); - - // Return a pointer to the root of the tree, does not make a new reference. - BrowserAccessibility* GetRoot(); - - // Return a pointer to the object corresponding to the given child_id, - // does not make a new reference. - BrowserAccessibility* GetFromChildID(LONG child_id); - - // Get a the default IAccessible for the parent window, does not make a - // new reference. - IAccessible* GetParentWindowIAccessible(); - - // Get the parent window. - HWND GetParentHWND(); - - // Return the object that has focus, if it's a descandant of the - // given root (inclusive). Does not make a new reference. - BrowserAccessibility* GetFocus(BrowserAccessibility* root); - - // Tell the renderer to set focus to this node. - void SetFocus(const BrowserAccessibility& node); - - // Tell the renderer to do the default action for this node. - void DoDefaultAction(const BrowserAccessibility& node); - - // Called when the renderer process has notified us of a focus or state - // change. Send a notification to MSAA clients of the change. - void OnAccessibilityFocusChange(int acc_obj_id); - void OnAccessibilityObjectStateChange(int acc_obj_id); - - private: - // Recursively build a tree of BrowserAccessibility objects from - // the WebAccessibility tree received from the renderer process. - BrowserAccessibility* CreateAccessibilityTree( - BrowserAccessibility* parent, - const webkit_glue::WebAccessibility& src, - int index_in_parent); - - // The parent window. - HWND parent_hwnd_; - - // The object that can perform actions on our behalf. - BrowserAccessibilityDelegate* delegate_; - - // Factory to create BrowserAccessibility objects (for dependency injection). - scoped_ptr factory_; - - // A default IAccessible instance for the parent window. - ScopedComPtr window_iaccessible_; - - // The root of the tree of IAccessible objects and the element that - // currently has focus, if any. - BrowserAccessibility* root_; - BrowserAccessibility* focus_; - - // A mapping from the IDs of objects in the renderer, to the child IDs - // we use internally here. - base::hash_map renderer_id_to_child_id_map_; - - // A mapping from child IDs to BrowserAccessibility objects. - base::hash_map child_id_map_; - - // The next child ID to use; static so that they're global to the process. - // Screen readers cache these IDs to see if they've seen the same object - // before so we should avoid reusing them within the same project. - static LONG next_child_id_; - - DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); -}; - -#endif // CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_ diff --git a/chrome/browser/browser_accessibility_manager_win.cc b/chrome/browser/browser_accessibility_manager_win.cc new file mode 100644 index 0000000..eddb1c3 --- /dev/null +++ b/chrome/browser/browser_accessibility_manager_win.cc @@ -0,0 +1,151 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/browser_accessibility_manager_win.h" + +#include "base/scoped_comptr_win.h" +#include "chrome/browser/browser_accessibility_win.h" +#include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/common/render_messages.h" + +using webkit_glue::WebAccessibility; + +// Factory method to create an instance of BrowserAccessibility +BrowserAccessibility* BrowserAccessibilityFactory::Create() { + CComObject* instance; + HRESULT hr = CComObject::CreateInstance(&instance); + DCHECK(SUCCEEDED(hr)); + return instance->NewReference(); +} + +// static +// Start child IDs at -1 and decrement each time, because clients use +// child IDs of 1, 2, 3, ... to access the children of an object by +// index, so we use negative IDs to clearly distinguish between indices +// and unique IDs. +LONG BrowserAccessibilityManager::next_child_id_ = -1; + +BrowserAccessibilityManager::BrowserAccessibilityManager( + HWND parent_hwnd, + const webkit_glue::WebAccessibility& src, + BrowserAccessibilityDelegate* delegate, + BrowserAccessibilityFactory* factory) + : parent_hwnd_(parent_hwnd), + delegate_(delegate), + factory_(factory), + focus_(NULL) { + HRESULT hr = ::CreateStdAccessibleObject( + parent_hwnd_, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast(&window_iaccessible_)); + DCHECK(SUCCEEDED(hr)); + root_ = CreateAccessibilityTree(NULL, src, 0); + if (!focus_) + focus_ = root_; +} + +BrowserAccessibilityManager::~BrowserAccessibilityManager() { + // Clients could still hold references to some nodes of the tree, so + // calling Inactivate will make sure that as many nodes as possible are + // released now, and remaining nodes are marked as inactive so that + // calls to any methods on them will return E_FAIL; + root_->InactivateTree(); + root_->Release(); +} + +BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { + return root_; +} + +BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID( + LONG child_id) { + base::hash_map::iterator iter = + child_id_map_.find(child_id); + if (iter != child_id_map_.end()) { + return iter->second; + } else { + return NULL; + } +} + +IAccessible* BrowserAccessibilityManager::GetParentWindowIAccessible() { + return window_iaccessible_; +} + +HWND BrowserAccessibilityManager::GetParentHWND() { + return parent_hwnd_; +} + +BrowserAccessibility* BrowserAccessibilityManager::GetFocus( + BrowserAccessibility* root) { + if (focus_ && (!root || focus_->IsDescendantOf(root))) + return focus_; + + return NULL; +} + +void BrowserAccessibilityManager::SetFocus(const BrowserAccessibility& node) { + if (delegate_) + delegate_->SetAccessibilityFocus(node.renderer_id()); +} + +void BrowserAccessibilityManager::DoDefaultAction( + const BrowserAccessibility& node) { + if (delegate_) + delegate_->AccessibilityDoDefaultAction(node.renderer_id()); +} + +void BrowserAccessibilityManager::OnAccessibilityFocusChange(int renderer_id) { + base::hash_map::iterator iter = + renderer_id_to_child_id_map_.find(renderer_id); + if (iter == renderer_id_to_child_id_map_.end()) + return; + + LONG child_id = iter->second; + base::hash_map::iterator uniq_iter = + child_id_map_.find(child_id); + if (uniq_iter != child_id_map_.end()) + focus_ = uniq_iter->second; + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); +} + +void BrowserAccessibilityManager::OnAccessibilityObjectStateChange( + int renderer_id) { + base::hash_map::iterator iter = + renderer_id_to_child_id_map_.find(renderer_id); + if (iter == renderer_id_to_child_id_map_.end()) + return; + + LONG child_id = iter->second; + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); +} + +BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( + BrowserAccessibility* parent, + const webkit_glue::WebAccessibility& src, + int index_in_parent) { + BrowserAccessibility* instance = factory_->Create(); + + // Get the next child ID, and wrap around when we get near the end + // of a 32-bit integer range. It's okay to wrap around; we just want + // to avoid it as long as possible because clients may cache the ID of + // an object for a while to determine if they've seen it before. + LONG child_id = next_child_id_; + next_child_id_--; + if (next_child_id_ == -2000000000) + next_child_id_ = -1; + + instance->Initialize(this, parent, child_id, index_in_parent, src); + child_id_map_[child_id] = instance; + renderer_id_to_child_id_map_[src.id] = child_id; + if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) + focus_ = instance; + for (int i = 0; i < static_cast(src.children.size()); ++i) { + BrowserAccessibility* child = CreateAccessibilityTree( + instance, src.children[i], i); + instance->AddChild(child); + } + + return instance; +} diff --git a/chrome/browser/browser_accessibility_manager_win.h b/chrome/browser/browser_accessibility_manager_win.h new file mode 100644 index 0000000..afae99c --- /dev/null +++ b/chrome/browser/browser_accessibility_manager_win.h @@ -0,0 +1,120 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_WIN_H_ +#define CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_WIN_H_ + +#include +#include +#include + +#include + +#include "base/hash_tables.h" +#include "base/scoped_comptr_win.h" +#include "base/scoped_ptr.h" +#include "webkit/glue/webaccessibility.h" + +class BrowserAccessibility; +class RenderProcessHost; +class RenderWidgetHost; + +class BrowserAccessibilityFactory { + public: + virtual ~BrowserAccessibilityFactory() {} + + // Create an instance of BrowserAccessibility and return a new + // reference to it. + virtual BrowserAccessibility* Create(); +}; + +// Class that can perform actions on behalf of the BrowserAccessibilityManager. +class BrowserAccessibilityDelegate { + public: + virtual ~BrowserAccessibilityDelegate() {} + virtual void SetAccessibilityFocus(int acc_obj_id) = 0; + virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0; +}; + +// Manages a tree of BrowserAccessibility objects. +class BrowserAccessibilityManager { + public: + BrowserAccessibilityManager( + HWND parent_hwnd, + const webkit_glue::WebAccessibility& src, + BrowserAccessibilityDelegate* delegate, + BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); + + virtual ~BrowserAccessibilityManager(); + + // Return a pointer to the root of the tree, does not make a new reference. + BrowserAccessibility* GetRoot(); + + // Return a pointer to the object corresponding to the given child_id, + // does not make a new reference. + BrowserAccessibility* GetFromChildID(LONG child_id); + + // Get a the default IAccessible for the parent window, does not make a + // new reference. + IAccessible* GetParentWindowIAccessible(); + + // Get the parent window. + HWND GetParentHWND(); + + // Return the object that has focus, if it's a descandant of the + // given root (inclusive). Does not make a new reference. + BrowserAccessibility* GetFocus(BrowserAccessibility* root); + + // Tell the renderer to set focus to this node. + void SetFocus(const BrowserAccessibility& node); + + // Tell the renderer to do the default action for this node. + void DoDefaultAction(const BrowserAccessibility& node); + + // Called when the renderer process has notified us of a focus or state + // change. Send a notification to MSAA clients of the change. + void OnAccessibilityFocusChange(int acc_obj_id); + void OnAccessibilityObjectStateChange(int acc_obj_id); + + private: + // Recursively build a tree of BrowserAccessibility objects from + // the WebAccessibility tree received from the renderer process. + BrowserAccessibility* CreateAccessibilityTree( + BrowserAccessibility* parent, + const webkit_glue::WebAccessibility& src, + int index_in_parent); + + // The parent window. + HWND parent_hwnd_; + + // The object that can perform actions on our behalf. + BrowserAccessibilityDelegate* delegate_; + + // Factory to create BrowserAccessibility objects (for dependency injection). + scoped_ptr factory_; + + // A default IAccessible instance for the parent window. + ScopedComPtr window_iaccessible_; + + // The root of the tree of IAccessible objects and the element that + // currently has focus, if any. + BrowserAccessibility* root_; + BrowserAccessibility* focus_; + + // A mapping from the IDs of objects in the renderer, to the child IDs + // we use internally here. + base::hash_map renderer_id_to_child_id_map_; + + // A mapping from child IDs to BrowserAccessibility objects. + base::hash_map child_id_map_; + + // The next child ID to use; static so that they're global to the process. + // Screen readers cache these IDs to see if they've seen the same object + // before so we should avoid reusing them within the same project. + static LONG next_child_id_; + + DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); +}; + +#endif // CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_WIN_H_ diff --git a/chrome/browser/browser_accessibility_unittest.cc b/chrome/browser/browser_accessibility_unittest.cc deleted file mode 100644 index 217cb10..0000000 --- a/chrome/browser/browser_accessibility_unittest.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/scoped_ptr.h" -#include "chrome/browser/browser_accessibility_manager.h" -#include "chrome/browser/browser_accessibility.h" -#include "testing/gtest/include/gtest/gtest.h" - -using webkit_glue::WebAccessibility; - -// Subclass of BrowserAccessibility that counts the number of instances. -class CountedBrowserAccessibility : public BrowserAccessibility { - public: - CountedBrowserAccessibility() { global_obj_count_++; } - virtual ~CountedBrowserAccessibility() { global_obj_count_--; } - static int global_obj_count_; -}; - -int CountedBrowserAccessibility::global_obj_count_ = 0; - -// Factory that creates a CountedBrowserAccessibility. -class CountedBrowserAccessibilityFactory : public BrowserAccessibilityFactory { - public: - virtual ~CountedBrowserAccessibilityFactory() {} - virtual BrowserAccessibility* Create() { - CComObject* instance; - HRESULT hr = CComObject::CreateInstance( - &instance); - DCHECK(SUCCEEDED(hr)); - return instance->NewReference(); - } -}; - -// Test that BrowserAccessibilityManager correctly releases the tree of -// BrowserAccessibility instances upon delete. -TEST(BrowserAccessibilityTest, TestNoLeaks) { - // ATL needs a pointer to a COM module. - CComModule module; - _pAtlModule = &module; - // Make sure COM is initialized for this thread; it's safe to call twice. - ::CoInitialize(NULL); - - // Create WebAccessibility objects for a simple document tree, - // representing the accessibility information used to initialize - // BrowserAccessibilityManager. - WebAccessibility button; - button.id = 2; - button.name = L"Button"; - button.role = WebAccessibility::ROLE_BUTTON; - button.state = 0; - - WebAccessibility checkbox; - checkbox.id = 3; - checkbox.name = L"Checkbox"; - checkbox.role = WebAccessibility::ROLE_CHECKBOX; - checkbox.state = 0; - - WebAccessibility root; - root.id = 1; - root.name = L"Document"; - root.role = WebAccessibility::ROLE_DOCUMENT; - root.state = 0; - root.children.push_back(button); - root.children.push_back(checkbox); - - // Construct a BrowserAccessibilityManager with this WebAccessibility tree - // and a factory for an instance-counting BrowserAccessibility, and ensure - // that exactly 3 instances were created. Note that the manager takes - // ownership of the factory. - CountedBrowserAccessibility::global_obj_count_ = 0; - BrowserAccessibilityManager* manager = - new BrowserAccessibilityManager( - GetDesktopWindow(), root, NULL, - new CountedBrowserAccessibilityFactory()); - ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); - - // Delete the manager and test that all 3 instances are deleted. - delete manager; - ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); - - // Construct a manager again, and this time use the IAccessible interface - // to get new references to two of the three nodes in the tree. - manager = new BrowserAccessibilityManager( - GetDesktopWindow(), root, NULL, - new CountedBrowserAccessibilityFactory()); - ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); - BrowserAccessibility* root_accessible = manager->GetRoot(); - IDispatch* root_iaccessible = NULL; - IDispatch* child1_iaccessible = NULL; - VARIANT var_child; - var_child.vt = VT_I4; - var_child.lVal = CHILDID_SELF; - HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible); - ASSERT_EQ(S_OK, hr); - var_child.lVal = 1; - hr = root_accessible->get_accChild(var_child, &child1_iaccessible); - ASSERT_EQ(S_OK, hr); - - // Now delete the manager, and only one of the three nodes in the tree - // should be released. - delete manager; - ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_); - - // Release each of our references and make sure that each one results in - // the instance being deleted as its reference count hits zero. - root_iaccessible->Release(); - ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_); - child1_iaccessible->Release(); - ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); -} diff --git a/chrome/browser/browser_accessibility_win.cc b/chrome/browser/browser_accessibility_win.cc new file mode 100644 index 0000000..aed9bbc --- /dev/null +++ b/chrome/browser/browser_accessibility_win.cc @@ -0,0 +1,1013 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/browser_accessibility_win.h" + +#include "base/logging.h" +#include "chrome/browser/browser_accessibility_manager_win.h" + +using webkit_glue::WebAccessibility; + +BrowserAccessibility::BrowserAccessibility() + : manager_(NULL), + parent_(NULL), + child_id_(-1), + index_in_parent_(-1), + renderer_id_(-1), + instance_active_(false) { +} + +BrowserAccessibility::~BrowserAccessibility() { + InactivateTree(); +} + +void BrowserAccessibility::Initialize( + BrowserAccessibilityManager* manager, + BrowserAccessibility* parent, + LONG child_id, + LONG index_in_parent, + const webkit_glue::WebAccessibility& src) { + manager_ = manager; + parent_ = parent; + child_id_ = child_id; + index_in_parent_ = index_in_parent; + + renderer_id_ = src.id; + name_ = src.name; + value_ = src.value; + attributes_ = src.attributes; + location_ = src.location; + InitRoleAndState(src.role, src.state); + + // If this object doesn't have a name but it does have a description, + // use the description as its name - because some screen readers only + // announce the name. + if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { + GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); + } + + instance_active_ = true; +} + +void BrowserAccessibility::AddChild(BrowserAccessibility* child) { + children_.push_back(child); +} + +void BrowserAccessibility::InactivateTree() { + // Mark this object as inactive, so calls to all COM methods will return + // failure. + instance_active_ = false; + + // Now we can safely call InactivateTree on our children and remove + // references to them, so that as much of the tree as possible will be + // destroyed now - however, nodes that still have references to them + // might stick around a while until all clients have released them. + for (std::vector::iterator iter = + children_.begin(); + iter != children_.end(); ++iter) { + (*iter)->InactivateTree(); + (*iter)->Release(); + } + children_.clear(); +} + +bool BrowserAccessibility::IsDescendantOf(BrowserAccessibility* ancestor) { + if (this == ancestor) { + return true; + } else if (parent_) { + return parent_->IsDescendantOf(ancestor); + } + + return false; +} + +BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { + if (parent_ && index_in_parent_ > 0) + return parent_->children_[index_in_parent_ - 1]; + + return NULL; +} + +BrowserAccessibility* BrowserAccessibility::GetNextSibling() { + if (parent_ && + index_in_parent_ < static_cast(parent_->children_.size() - 1)) { + return parent_->children_[index_in_parent_ + 1]; + } + + return NULL; +} + +BrowserAccessibility* BrowserAccessibility::NewReference() { + AddRef(); + return this; +} + +// +// IAccessible methods. +// +// Conventions: +// * Always test for instance_active_ first and return E_FAIL if it's false. +// * Always check for invalid arguments first, even if they're unused. +// * Return S_FALSE if the only output is a string argument and it's empty. +// + +HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { + if (!instance_active_) + return E_FAIL; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + manager_->DoDefaultAction(*target); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, + VARIANT* child) { + if (!instance_active_) + return E_FAIL; + + if (!child) + return E_INVALIDARG; + + return E_NOTIMPL; +} + +STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, + LONG* width, LONG* height, + VARIANT var_id) { + if (!instance_active_) + return E_FAIL; + + if (!x_left || !y_top || !width || !height) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + // Find the top left corner of the containing window in screen coords, and + // adjust the output position by this amount. + HWND parent_hwnd = manager_->GetParentHWND(); + POINT top_left = {0, 0}; + ::ClientToScreen(parent_hwnd, &top_left); + + *x_left = target->location_.x + top_left.x; + *y_top = target->location_.y + top_left.y; + *width = target->location_.width; + *height = target->location_.height; + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::accNavigate( + LONG nav_dir, VARIANT start, VARIANT* end) { + BrowserAccessibility* target = GetTargetFromChildID(start); + if (!target) + return E_INVALIDARG; + + if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && + start.lVal != CHILDID_SELF) { + // MSAA states that navigating to first/last child can only be from self. + return E_INVALIDARG; + } + + BrowserAccessibility* result = NULL; + switch (nav_dir) { + case NAVDIR_DOWN: + case NAVDIR_UP: + case NAVDIR_LEFT: + case NAVDIR_RIGHT: + // These directions are not implemented, matching Mozilla and IE. + return E_NOTIMPL; + case NAVDIR_FIRSTCHILD: + if (target->children_.size() > 0) + result = target->children_[0]; + break; + case NAVDIR_LASTCHILD: + if (target->children_.size() > 0) + result = target->children_[target->children_.size() - 1]; + break; + case NAVDIR_NEXT: + result = target->GetNextSibling(); + break; + case NAVDIR_PREVIOUS: + result = target->GetPreviousSibling(); + break; + } + + if (!result) { + end->vt = VT_EMPTY; + return S_FALSE; + } + + end->vt = VT_DISPATCH; + end->pdispVal = result->NewReference(); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, + IDispatch** disp_child) { + if (!instance_active_) + return E_FAIL; + + if (!disp_child) + return E_INVALIDARG; + + *disp_child = NULL; + + BrowserAccessibility* target = GetTargetFromChildID(var_child); + if (!target) + return E_INVALIDARG; + + (*disp_child) = target->NewReference(); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { + if (!instance_active_) + return E_FAIL; + + if (!child_count) + return E_INVALIDARG; + + *child_count = children_.size(); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, + BSTR* def_action) { + if (!instance_active_) + return E_FAIL; + + if (!def_action) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + string16 action; + if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &action)) + return S_FALSE; + + if (action.empty()) + return S_FALSE; + + *def_action = SysAllocString(action.c_str()); + + DCHECK(*def_action); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, + BSTR* desc) { + if (!instance_active_) + return E_FAIL; + + if (!desc) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + string16 description; + if (!target->GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) + return S_FALSE; + + if (description.empty()) + return S_FALSE; + + *desc = SysAllocString(description.c_str()); + + DCHECK(*desc); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { + if (!instance_active_) + return E_FAIL; + + if (!focus_child) + return E_INVALIDARG; + + BrowserAccessibility* focus = manager_->GetFocus(this); + if (focus == this) { + focus_child->vt = VT_I4; + focus_child->lVal = CHILDID_SELF; + } else if (focus == NULL) { + focus_child->vt = VT_EMPTY; + } else { + focus_child->vt = VT_DISPATCH; + focus_child->pdispVal = focus->NewReference(); + } + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { + if (!instance_active_) + return E_FAIL; + + if (!help) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + string16 help_str; + if (!target->GetAttribute(WebAccessibility::ATTR_HELP, &help_str)) + return S_FALSE; + + if (help_str.empty()) + return S_FALSE; + + *help = SysAllocString(help_str.c_str()); + + DCHECK(*help); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, + BSTR* acc_key) { + if (!instance_active_) + return E_FAIL; + + if (!acc_key) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + string16 shortcut; + if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &shortcut)) + return S_FALSE; + + if (shortcut.empty()) + return S_FALSE; + + *acc_key = SysAllocString(shortcut.c_str()); + + DCHECK(*acc_key); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { + if (!instance_active_) + return E_FAIL; + + if (!name) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + if (target->name_.empty()) + return S_FALSE; + + *name = SysAllocString(target->name_.c_str()); + + DCHECK(*name); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { + if (!instance_active_) + return E_FAIL; + + if (!disp_parent) + return E_INVALIDARG; + + IAccessible* parent = parent_; + if (parent == NULL) { + // This happens if we're the root of the tree; + // return the IAccessible for the window. + parent = manager_->GetParentWindowIAccessible(); + } + + parent->AddRef(); + *disp_parent = parent; + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { + if (!instance_active_) + return E_FAIL; + + if (!role) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + if (!target->role_name_.empty()) { + role->vt = VT_BSTR; + role->bstrVal = SysAllocString(target->role_name_.c_str()); + } else { + role->vt = VT_I4; + role->lVal = target->role_; + } + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, + VARIANT* state) { + if (!instance_active_) + return E_FAIL; + + if (!state) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + state->vt = VT_I4; + state->lVal = target->state_; + if (manager_->GetFocus(NULL) == this) + state->lVal |= STATE_SYSTEM_FOCUSED; + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { + if (!instance_active_) + return E_FAIL; + + if (!value) + return E_INVALIDARG; + + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; + + *value = SysAllocString(target->value_.c_str()); + + DCHECK(*value); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, + VARIANT var_id, + LONG* topic_id) { + return E_NOTIMPL; +} + +STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { + if (!instance_active_) + return E_FAIL; + + return E_NOTIMPL; +} + +STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_sel, VARIANT var_id) { + if (!instance_active_) + return E_FAIL; + + if (flags_sel & SELFLAG_TAKEFOCUS) { + manager_->SetFocus(*this); + return S_OK; + } + + return S_FALSE; +} + +// +// IAccessible2 methods. +// + +STDMETHODIMP BrowserAccessibility::role(LONG* role) { + if (!instance_active_) + return E_FAIL; + + if (!role) + return E_INVALIDARG; + + *role = ia2_role_; + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { + if (!instance_active_) + return E_FAIL; + + if (!attributes) + return E_INVALIDARG; + + return S_FALSE; +} + +STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { + if (!instance_active_) + return E_FAIL; + + if (!states) + return E_INVALIDARG; + + *states = ia2_state_; + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_uniqueID(LONG* unique_id) { + if (!instance_active_) + return E_FAIL; + + if (!unique_id) + return E_INVALIDARG; + + *unique_id = child_id_; + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_windowHandle(HWND* window_handle) { + if (!instance_active_) + return E_FAIL; + + if (!window_handle) + return E_INVALIDARG; + + *window_handle = manager_->GetParentHWND(); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_indexInParent(LONG* index_in_parent) { + if (!instance_active_) + return E_FAIL; + + if (!index_in_parent) + return E_INVALIDARG; + + *index_in_parent = index_in_parent_; + return S_OK; +} + +// +// IAccessibleImage methods. +// + +STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { + if (!instance_active_) + return E_FAIL; + + if (!desc) + return E_INVALIDARG; + + string16 description; + if (!GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) + return S_FALSE; + + if (description.empty()) + return S_FALSE; + + *desc = SysAllocString(description.c_str()); + + DCHECK(*desc); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_imagePosition( + enum IA2CoordinateType coordinate_type, long* x, long* y) { + if (!instance_active_) + return E_FAIL; + + if (!x || !y) + return E_INVALIDARG; + + if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { + HWND parent_hwnd = manager_->GetParentHWND(); + POINT top_left = {0, 0}; + ::ClientToScreen(parent_hwnd, &top_left); + *x = location_.x + top_left.x; + *y = location_.y + top_left.y; + } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { + *x = location_.x; + *y = location_.y; + if (parent_) { + *x -= parent_->location_.x; + *y -= parent_->location_.y; + } + } else { + return E_INVALIDARG; + } + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_imageSize(long* height, long* width) { + if (!instance_active_) + return E_FAIL; + + if (!height || !width) + return E_INVALIDARG; + + *height = location_.height; + *width = location_.width; + return S_OK; +} + +// +// IAccessibleText methods. +// + +STDMETHODIMP BrowserAccessibility::get_nCharacters(long* n_characters) { + if (!instance_active_) + return E_FAIL; + + if (!n_characters) + return E_INVALIDARG; + + *n_characters = name_.length(); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_text( + long start_offset, long end_offset, BSTR* text) { + if (!instance_active_) + return E_FAIL; + + if (!text) + return E_INVALIDARG; + + long len = name_.length(); + if (start_offset < 0) + start_offset = 0; + if (end_offset > len) + end_offset = len; + + *text = SysAllocString( + name_.substr(start_offset, end_offset - start_offset).c_str()); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { + *offset = 0; + return S_OK; +} + +// +// IServiceProvider methods. +// + +STDMETHODIMP BrowserAccessibility::QueryService( + REFGUID guidService, REFIID riid, void** object) { + if (!instance_active_) + return E_FAIL; + + if (guidService == IID_IAccessible || guidService == IID_IAccessible2) + return QueryInterface(riid, object); + + *object = NULL; + return E_FAIL; +} + +// +// CComObjectRootEx methods. +// + +HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( + void* this_ptr, + const _ATL_INTMAP_ENTRY* entries, + REFIID iid, + void** object) { + if (iid == IID_IAccessibleText) { + if (role_ != ROLE_SYSTEM_LINK) { + *object = NULL; + return E_NOINTERFACE; + } + } else if (iid == IID_IAccessibleImage) { + if (role_ != ROLE_SYSTEM_GRAPHIC) { + *object = NULL; + return E_NOINTERFACE; + } + } + + return CComObjectRootBase::InternalQueryInterface( + this_ptr, entries, iid, object); +} + +// +// Private methods. +// + +BrowserAccessibility* BrowserAccessibility::GetTargetFromChildID( + const VARIANT& var_id) { + if (var_id.vt != VT_I4) + return NULL; + + LONG child_id = var_id.lVal; + if (child_id == CHILDID_SELF) + return this; + + if (child_id >= 1 && child_id <= static_cast(children_.size())) + return children_[child_id - 1]; + + return manager_->GetFromChildID(child_id); +} + +bool BrowserAccessibility::HasAttribute(WebAccessibility::Attribute attribute) { + return (attributes_.find(attribute) != attributes_.end()); +} + +bool BrowserAccessibility::GetAttribute( + WebAccessibility::Attribute attribute, string16* value) { + std::map::iterator iter = attributes_.find(attribute); + if (iter != attributes_.end()) { + *value = iter->second; + return true; + } + + return false; +} + +void BrowserAccessibility::InitRoleAndState(LONG web_role, + LONG web_state) { + state_ = 0; + ia2_state_ = IA2_STATE_OPAQUE; + + if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) + state_ |= STATE_SYSTEM_CHECKED; + if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) + state_ |= STATE_SYSTEM_FOCUSABLE; + if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) + state_ |= STATE_SYSTEM_HOTTRACKED; + if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) + state_ |= STATE_SYSTEM_INDETERMINATE; + if ((web_state >> WebAccessibility::STATE_LINKED) & 1) + state_ |= STATE_SYSTEM_LINKED; + if ((web_state >> WebAccessibility::STATE_MULTISELECTABLE) & 1) + state_ |= STATE_SYSTEM_MULTISELECTABLE; + if ((web_state >> WebAccessibility::STATE_OFFSCREEN) & 1) + state_ |= STATE_SYSTEM_OFFSCREEN; + if ((web_state >> WebAccessibility::STATE_PRESSED) & 1) + state_ |= STATE_SYSTEM_PRESSED; + if ((web_state >> WebAccessibility::STATE_PROTECTED) & 1) + state_ |= STATE_SYSTEM_PROTECTED; + if ((web_state >> WebAccessibility::STATE_READONLY) & 1) + state_ |= STATE_SYSTEM_READONLY; + if ((web_state >> WebAccessibility::STATE_TRAVERSED) & 1) + state_ |= STATE_SYSTEM_TRAVERSED; + if ((web_state >> WebAccessibility::STATE_UNAVAILABLE) & 1) + state_ |= STATE_SYSTEM_UNAVAILABLE; + + role_ = 0; + ia2_role_ = 0; + switch (web_role) { + case WebAccessibility::ROLE_ALERT: + case WebAccessibility::ROLE_ALERT_DIALOG: + role_ = ROLE_SYSTEM_ALERT; + break; + case WebAccessibility::ROLE_APPLICATION: + role_ = ROLE_SYSTEM_APPLICATION; + break; + case WebAccessibility::ROLE_ARTICLE: + role_ = ROLE_SYSTEM_GROUPING; + ia2_role_ = IA2_ROLE_SECTION; + break; + case WebAccessibility::ROLE_BUTTON: + role_ = ROLE_SYSTEM_PUSHBUTTON; + break; + case WebAccessibility::ROLE_CELL: + role_ = ROLE_SYSTEM_CELL; + break; + case WebAccessibility::ROLE_CHECKBOX: + role_ = ROLE_SYSTEM_CHECKBUTTON; + break; + case WebAccessibility::ROLE_COLOR_WELL: + role_ = ROLE_SYSTEM_CLIENT; + ia2_role_ = IA2_ROLE_COLOR_CHOOSER; + break; + case WebAccessibility::ROLE_COLUMN: + role_ = ROLE_SYSTEM_COLUMN; + break; + case WebAccessibility::ROLE_COLUMN_HEADER: + role_ = ROLE_SYSTEM_COLUMNHEADER; + break; + case WebAccessibility::ROLE_COMBO_BOX: + role_ = ROLE_SYSTEM_COMBOBOX; + break; + case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: + role_name_ = L"dd"; + ia2_role_ = IA2_ROLE_PARAGRAPH; + break; + case WebAccessibility::ROLE_DEFINITION_LIST_TERM: + role_ = ROLE_SYSTEM_LISTITEM; + break; + case WebAccessibility::ROLE_DIALOG: + role_ = ROLE_SYSTEM_DIALOG; + break; + case WebAccessibility::ROLE_DOCUMENT: + case WebAccessibility::ROLE_WEB_AREA: + role_ = ROLE_SYSTEM_DOCUMENT; + state_ |= STATE_SYSTEM_READONLY; + state_ |= STATE_SYSTEM_FOCUSABLE; + break; + case WebAccessibility::ROLE_EDITABLE_TEXT: + role_ = ROLE_SYSTEM_TEXT; + ia2_state_ |= IA2_STATE_SINGLE_LINE; + ia2_state_ |= IA2_STATE_EDITABLE; + break; + case WebAccessibility::ROLE_GRID: + role_ = ROLE_SYSTEM_TABLE; + break; + case WebAccessibility::ROLE_GROUP: + role_name_ = L"div"; + ia2_role_ = IA2_ROLE_SECTION; + break; + case WebAccessibility::ROLE_HEADING: + // TODO(dmazzoni): support all heading levels + role_name_ = L"h1"; + ia2_role_ = IA2_ROLE_HEADING; + break; + case WebAccessibility::ROLE_IMAGE: + role_ = ROLE_SYSTEM_GRAPHIC; + break; + case WebAccessibility::ROLE_IMAGE_MAP: + role_name_ = L"map"; + ia2_role_ = IA2_ROLE_IMAGE_MAP; + break; + case WebAccessibility::ROLE_IMAGE_MAP_LINK: + role_ = ROLE_SYSTEM_LINK; + state_ |= STATE_SYSTEM_LINKED; + break; + case WebAccessibility::ROLE_LANDMARK_APPLICATION: + case WebAccessibility::ROLE_LANDMARK_BANNER: + case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: + case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: + case WebAccessibility::ROLE_LANDMARK_MAIN: + case WebAccessibility::ROLE_LANDMARK_NAVIGATION: + case WebAccessibility::ROLE_LANDMARK_SEARCH: + role_ = ROLE_SYSTEM_GROUPING; + ia2_role_ = IA2_ROLE_SECTION; + break; + case WebAccessibility::ROLE_LINK: + case WebAccessibility::ROLE_WEBCORE_LINK: + role_ = ROLE_SYSTEM_LINK; + state_ |= STATE_SYSTEM_LINKED; + break; + case WebAccessibility::ROLE_LIST: + role_ = ROLE_SYSTEM_LIST; + break; + case WebAccessibility::ROLE_LISTBOX: + role_ = ROLE_SYSTEM_LIST; + break; + case WebAccessibility::ROLE_LISTBOX_OPTION: + case WebAccessibility::ROLE_LIST_ITEM: + case WebAccessibility::ROLE_LIST_MARKER: + role_ = ROLE_SYSTEM_LISTITEM; + break; + case WebAccessibility::ROLE_MENU: + case WebAccessibility::ROLE_MENU_BUTTON: + role_ = ROLE_SYSTEM_MENUPOPUP; + break; + case WebAccessibility::ROLE_MENU_BAR: + role_ = ROLE_SYSTEM_MENUBAR; + break; + case WebAccessibility::ROLE_MENU_ITEM: + case WebAccessibility::ROLE_MENU_LIST_OPTION: + role_ = ROLE_SYSTEM_MENUITEM; + break; + case WebAccessibility::ROLE_MENU_LIST_POPUP: + role_ = ROLE_SYSTEM_MENUPOPUP; + break; + case WebAccessibility::ROLE_NOTE: + role_ = ROLE_SYSTEM_GROUPING; + ia2_role_ = IA2_ROLE_NOTE; + break; + case WebAccessibility::ROLE_OUTLINE: + role_ = ROLE_SYSTEM_OUTLINE; + break; + case WebAccessibility::ROLE_POPUP_BUTTON: + role_ = ROLE_SYSTEM_COMBOBOX; + break; + case WebAccessibility::ROLE_PROGRESS_INDICATOR: + role_ = ROLE_SYSTEM_PROGRESSBAR; + break; + case WebAccessibility::ROLE_RADIO_BUTTON: + role_ = ROLE_SYSTEM_RADIOBUTTON; + break; + case WebAccessibility::ROLE_RADIO_GROUP: + role_ = ROLE_SYSTEM_GROUPING; + ia2_role_ = IA2_ROLE_SECTION; + break; + case WebAccessibility::ROLE_REGION: + role_ = ROLE_SYSTEM_GROUPING; + ia2_role_ = IA2_ROLE_SECTION; + break; + case WebAccessibility::ROLE_ROW: + role_ = ROLE_SYSTEM_ROW; + break; + case WebAccessibility::ROLE_ROW_HEADER: + role_ = ROLE_SYSTEM_ROWHEADER; + break; + case WebAccessibility::ROLE_RULER: + role_ = ROLE_SYSTEM_CLIENT; + ia2_role_ = IA2_ROLE_RULER; + break; + case WebAccessibility::ROLE_SCROLLAREA: + role_ = ROLE_SYSTEM_CLIENT; + ia2_role_ = IA2_ROLE_SCROLL_PANE; + break; + case WebAccessibility::ROLE_SCROLLBAR: + role_ = ROLE_SYSTEM_SCROLLBAR; + break; + case WebAccessibility::ROLE_SLIDER: + role_ = ROLE_SYSTEM_SLIDER; + break; + case WebAccessibility::ROLE_SPLIT_GROUP: + role_ = ROLE_SYSTEM_CLIENT; + ia2_role_ = IA2_ROLE_SPLIT_PANE; + break; + case WebAccessibility::ROLE_ANNOTATION: + case WebAccessibility::ROLE_STATIC_TEXT: + role_ = ROLE_SYSTEM_TEXT; + break; + case WebAccessibility::ROLE_STATUS: + role_ = ROLE_SYSTEM_STATUSBAR; + break; + case WebAccessibility::ROLE_TAB: + role_ = ROLE_SYSTEM_PAGETAB; + break; + case WebAccessibility::ROLE_TABLE: + role_ = ROLE_SYSTEM_TABLE; + break; + case WebAccessibility::ROLE_TABLE_HEADER_CONTAINER: + role_ = ROLE_SYSTEM_GROUPING; + ia2_role_ = IA2_ROLE_SECTION; + break; + case WebAccessibility::ROLE_TAB_GROUP: + case WebAccessibility::ROLE_TAB_LIST: + case WebAccessibility::ROLE_TAB_PANEL: + role_ = ROLE_SYSTEM_PAGETABLIST; + break; + case WebAccessibility::ROLE_TEXTAREA: + role_ = ROLE_SYSTEM_TEXT; + ia2_state_ |= IA2_STATE_MULTI_LINE; + ia2_state_ |= IA2_STATE_EDITABLE; + break; + case WebAccessibility::ROLE_TEXT_FIELD: + role_ = ROLE_SYSTEM_TEXT; + ia2_state_ |= IA2_STATE_SINGLE_LINE; + ia2_state_ |= IA2_STATE_EDITABLE; + break; + case WebAccessibility::ROLE_TOOLBAR: + role_ = ROLE_SYSTEM_TOOLBAR; + break; + case WebAccessibility::ROLE_TOOLTIP: + role_ = ROLE_SYSTEM_TOOLTIP; + break; + case WebAccessibility::ROLE_TREE: + role_ = ROLE_SYSTEM_OUTLINE; + break; + case WebAccessibility::ROLE_TREE_GRID: + role_ = ROLE_SYSTEM_OUTLINE; + break; + case WebAccessibility::ROLE_TREE_ITEM: + role_ = ROLE_SYSTEM_OUTLINEITEM; + break; + case WebAccessibility::ROLE_WINDOW: + role_ = ROLE_SYSTEM_WINDOW; + break; + + // TODO(dmazzoni): figure out the proper MSAA role for all of these. + case WebAccessibility::ROLE_BROWSER: + case WebAccessibility::ROLE_BUSY_INDICATOR: + case WebAccessibility::ROLE_DIRECTORY: + case WebAccessibility::ROLE_DISCLOSURE_TRIANGLE: + case WebAccessibility::ROLE_DRAWER: + case WebAccessibility::ROLE_GROW_AREA: + case WebAccessibility::ROLE_HELP_TAG: + case WebAccessibility::ROLE_IGNORED: + case WebAccessibility::ROLE_INCREMENTOR: + case WebAccessibility::ROLE_LOG: + case WebAccessibility::ROLE_MARQUEE: + case WebAccessibility::ROLE_MATH: + case WebAccessibility::ROLE_MATTE: + case WebAccessibility::ROLE_RULER_MARKER: + case WebAccessibility::ROLE_SHEET: + case WebAccessibility::ROLE_SLIDER_THUMB: + case WebAccessibility::ROLE_SPLITTER: + case WebAccessibility::ROLE_SYSTEM_WIDE: + case WebAccessibility::ROLE_TIMER: + case WebAccessibility::ROLE_VALUE_INDICATOR: + default: + role_ = ROLE_SYSTEM_CLIENT; + break; + } + + // The role should always be set. + DCHECK(!role_name_.empty() || role_); + + // If we didn't explicitly set the IAccessible2 role, make it the same + // as the MSAA role. + if (!ia2_role_) + ia2_role_ = role_; +} diff --git a/chrome/browser/browser_accessibility_win.h b/chrome/browser/browser_accessibility_win.h new file mode 100644 index 0000000..08edb2b --- /dev/null +++ b/chrome/browser/browser_accessibility_win.h @@ -0,0 +1,399 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BROWSER_ACCESSIBILITY_WIN_H_ +#define CHROME_BROWSER_BROWSER_ACCESSIBILITY_WIN_H_ + +#include +#include +#include + +#include + +#include "base/scoped_comptr_win.h" +#include "chrome/browser/browser_accessibility_manager_win.h" +#include "ia2_api_all.h" // Generated +#include "webkit/glue/webaccessibility.h" + +using webkit_glue::WebAccessibility; + +//////////////////////////////////////////////////////////////////////////////// +// +// BrowserAccessibility +// +// Class implementing the MSAA IAccessible COM interface for the +// Browser-Renderer communication of MSAA information, providing accessibility +// to be used by screen readers and other assistive technology (AT). +// +//////////////////////////////////////////////////////////////////////////////// +class ATL_NO_VTABLE BrowserAccessibility + : public CComObjectRootEx, + public IDispatchImpl, + public IAccessibleImage, + public IAccessibleText, + public IServiceProvider { + public: + BEGIN_COM_MAP(BrowserAccessibility) + COM_INTERFACE_ENTRY2(IDispatch, IAccessible2) + COM_INTERFACE_ENTRY2(IAccessible, IAccessible2) + COM_INTERFACE_ENTRY(IAccessible2) + COM_INTERFACE_ENTRY(IAccessibleImage) + COM_INTERFACE_ENTRY(IAccessibleText) + COM_INTERFACE_ENTRY(IServiceProvider) + END_COM_MAP() + + BrowserAccessibility(); + + virtual ~BrowserAccessibility(); + + // Initialize this object and mark it as active. + void Initialize(BrowserAccessibilityManager* manager, + BrowserAccessibility* parent, + LONG child_id, + LONG index_in_parent, + const webkit_glue::WebAccessibility& src); + + // Add a child of this object. + void AddChild(BrowserAccessibility* child); + + // Mark this object as inactive, and remove references to all children. + // When no other clients hold any references to this object it will be + // deleted, and in the meantime, calls to any methods will return E_FAIL. + void InactivateTree(); + + // Return true if this object is equal to or a descendant of |ancestor|. + bool IsDescendantOf(BrowserAccessibility* ancestor); + + // Return the previous sibling of this object, or NULL if it's the first + // child of its parent. + BrowserAccessibility* GetPreviousSibling(); + + // Return the next sibling of this object, or NULL if it's the last child + // of its parent. + BrowserAccessibility* GetNextSibling(); + + // Accessors + LONG child_id() const { return child_id_; } + int32 renderer_id() const { return renderer_id_; } + + // Add one to the reference count and return the same object. Always + // use this method when returning a BrowserAccessibility object as + // an output parameter to a COM interface, never use it otherwise. + BrowserAccessibility* NewReference(); + + // + // IAccessible methods. + // + + // Performs the default action on a given object. + STDMETHODIMP accDoDefaultAction(VARIANT var_id); + + // Retrieves the child element or child object at a given point on the screen. + STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child); + + // Retrieves the specified object's current screen location. + STDMETHODIMP accLocation(LONG* x_left, + LONG* y_top, + LONG* width, + LONG* height, + VARIANT var_id); + + // Traverses to another UI element and retrieves the object. + STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end); + + // Retrieves an IDispatch interface pointer for the specified child. + STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child); + + // Retrieves the number of accessible children. + STDMETHODIMP get_accChildCount(LONG* child_count); + + // Retrieves a string that describes the object's default action. + STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action); + + // Retrieves the object's description. + STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc); + + // Retrieves the object that has the keyboard focus. + STDMETHODIMP get_accFocus(VARIANT* focus_child); + + // Retrieves the help information associated with the object. + STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help); + + // Retrieves the specified object's shortcut. + STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key); + + // Retrieves the name of the specified object. + STDMETHODIMP get_accName(VARIANT var_id, BSTR* name); + + // Retrieves the IDispatch interface of the object's parent. + STDMETHODIMP get_accParent(IDispatch** disp_parent); + + // Retrieves information describing the role of the specified object. + STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role); + + // Retrieves the current state of the specified object. + STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state); + + // Returns the value associated with the object. + STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value); + + // Make an object take focus or extend the selection. + STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id); + + STDMETHODIMP get_accHelpTopic(BSTR* help_file, + VARIANT var_id, + LONG* topic_id); + + STDMETHODIMP get_accSelection(VARIANT* selected); + + // Deprecated methods, not implemented. + STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) { + return E_NOTIMPL; + } + STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val) { + return E_NOTIMPL; + } + + // + // IAccessible2 methods. + // + + // Returns role from a longer list of possible roles. + STDMETHODIMP role(LONG* role); + + // Returns the state bitmask from a larger set of possible states. + STDMETHODIMP get_states(AccessibleStates* states); + + // Returns the attributes specific to this IAccessible2 object, + // such as a cell's formula. + STDMETHODIMP get_attributes(BSTR* attributes); + + // Get the unique ID of this object so that the client knows if it's + // been encountered previously. + STDMETHODIMP get_uniqueID(LONG* unique_id); + + // Get the window handle of the enclosing window. + STDMETHODIMP get_windowHandle(HWND* window_handle); + + // Get this object's index in its parent object. + STDMETHODIMP get_indexInParent(LONG* index_in_parent); + + // IAccessible2 methods not implemented. + STDMETHODIMP get_extendedRole(BSTR* extended_role) { + return E_NOTIMPL; + } + STDMETHODIMP get_nRelations(LONG* n_relations) { + return E_NOTIMPL; + } + STDMETHODIMP get_relation(LONG relation_index, + IAccessibleRelation** relation) { + return E_NOTIMPL; + } + STDMETHODIMP get_relations(LONG max_relations, + IAccessibleRelation** relations, + LONG* n_relations) { + return E_NOTIMPL; + } + STDMETHODIMP scrollTo(enum IA2ScrollType scroll_type) { + return E_NOTIMPL; + } + STDMETHODIMP scrollToPoint(enum IA2CoordinateType coordinate_type, + LONG x, + LONG y) { + return E_NOTIMPL; + } + STDMETHODIMP get_groupPosition(LONG* group_level, + LONG* similar_items_in_group, + LONG* position_in_group) { + return E_NOTIMPL; + } + STDMETHODIMP get_localizedExtendedRole(BSTR* localized_extended_role) { + return E_NOTIMPL; + } + STDMETHODIMP get_nExtendedStates(LONG* n_extended_states) { + return E_NOTIMPL; + } + STDMETHODIMP get_extendedStates(LONG max_extended_states, + BSTR** extended_states, + LONG* n_extended_states) { + return E_NOTIMPL; + } + STDMETHODIMP get_localizedExtendedStates(LONG max_localized_extended_states, + BSTR** localized_extended_states, + LONG* n_localized_extended_states) { + return E_NOTIMPL; + } + STDMETHODIMP get_locale(IA2Locale* locale) { + return E_NOTIMPL; + } + + // + // IAccessibleImage methods. + // + + STDMETHODIMP get_description(BSTR* description); + + STDMETHODIMP get_imagePosition(enum IA2CoordinateType coordinate_type, + long* x, long* y); + + STDMETHODIMP get_imageSize(long* height, long* width); + + // + // IAccessibleText methods. + // + + STDMETHODIMP get_nCharacters(long* n_characters); + + STDMETHODIMP get_text(long start_offset, long end_offset, BSTR* text); + + STDMETHODIMP get_caretOffset(long* offset); + + // IAccessibleText methods not implemented. + STDMETHODIMP addSelection(long start_offset, long end_offset) { + return E_NOTIMPL; + } + STDMETHODIMP get_attributes(long offset, long* start_offset, long* end_offset, + BSTR* text_attributes) { + return E_NOTIMPL; + } + STDMETHODIMP get_characterExtents(long offset, + enum IA2CoordinateType coord_type, + long* x, long* y, + long* width, long* height) { + return E_NOTIMPL; + } + STDMETHODIMP get_nSelections(long* n_selections) { + return E_NOTIMPL; + } + STDMETHODIMP get_offsetAtPoint(long x, long y, + enum IA2CoordinateType coord_type, + long* offset) { + return E_NOTIMPL; + } + STDMETHODIMP get_selection(long selection_index, + long* start_offset, + long* end_offset) { + return E_NOTIMPL; + } + STDMETHODIMP get_textBeforeOffset(long offset, + enum IA2TextBoundaryType boundary_type, + long* start_offset, long* end_offset, + BSTR* text) { + return E_NOTIMPL; + } + STDMETHODIMP get_textAfterOffset(long offset, + enum IA2TextBoundaryType boundary_type, + long* start_offset, long* end_offset, + BSTR* text) { + return E_NOTIMPL; + } + STDMETHODIMP get_textAtOffset(long offset, + enum IA2TextBoundaryType boundary_type, + long* start_offset, long* end_offset, + BSTR* text) { + return E_NOTIMPL; + } + STDMETHODIMP removeSelection(long selection_index) { + return E_NOTIMPL; + } + STDMETHODIMP setCaretOffset(long offset) { + return E_NOTIMPL; + } + STDMETHODIMP setSelection(long selection_index, + long start_offset, + long end_offset) { + return E_NOTIMPL; + } + STDMETHODIMP scrollSubstringTo(long start_index, + long end_index, + enum IA2ScrollType scroll_type) { + return E_NOTIMPL; + } + STDMETHODIMP scrollSubstringToPoint(long start_index, long end_index, + enum IA2CoordinateType coordinate_type, + long x, long y) { + return E_NOTIMPL; + } + STDMETHODIMP get_newText(IA2TextSegment* new_text) { + return E_NOTIMPL; + } + STDMETHODIMP get_oldText(IA2TextSegment* old_text) { + return E_NOTIMPL; + } + + // + // IServiceProvider methods. + // + + STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** object); + + // + // CComObjectRootEx methods. + // + + HRESULT WINAPI InternalQueryInterface(void* this_ptr, + const _ATL_INTMAP_ENTRY* entries, + REFIID iid, + void** object); + + private: + // Many MSAA methods take a var_id parameter indicating that the operation + // should be performed on a particular child ID, rather than this object. + // This method tries to figure out the target object from |var_id| and + // returns a pointer to the target object if it exists, otherwise NULL. + // Does not return a new reference. + BrowserAccessibility* GetTargetFromChildID(const VARIANT& var_id); + + // Initialize the role and state metadata from the role enum and state + // bitmasks defined in webkit/glue/webaccessibility.h. + void InitRoleAndState(LONG web_accessibility_role, + LONG web_accessibility_state); + + // Return true if this attribute is in the attributes map. + bool HasAttribute(WebAccessibility::Attribute attribute); + + // Retrieve the string value of an attribute from the attribute map and + // returns true if found. + bool GetAttribute(WebAccessibility::Attribute attribute, string16* value); + + // The manager of this tree of accessibility objects; needed for + // global operations like focus tracking. + BrowserAccessibilityManager* manager_; + // The parent of this object, may be NULL if we're the root object. + BrowserAccessibility* parent_; + // The ID of this object; globally unique within the browser process. + LONG child_id_; + // The index of this within its parent object. + LONG index_in_parent_; + // The ID of this object in the renderer process. + int32 renderer_id_; + + // The children of this object. + std::vector children_; + + // Accessibility metadata from the renderer, used to respond to MSAA + // events. + string16 name_; + string16 value_; + std::map attributes_; + + LONG role_; + LONG state_; + string16 role_name_; + LONG ia2_role_; + LONG ia2_state_; + WebKit::WebRect location_; + + // COM objects are reference-counted. When we're done with this object + // and it's removed from our accessibility tree, a client may still be + // holding onto a pointer to this object, so we mark it as inactive + // so that calls to any of this object's methods immediately return + // failure. + bool instance_active_; + + DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility); +}; + +#endif // CHROME_BROWSER_BROWSER_ACCESSIBILITY_WIN_H_ diff --git a/chrome/browser/browser_accessibility_win_unittest.cc b/chrome/browser/browser_accessibility_win_unittest.cc new file mode 100644 index 0000000..6d85671 --- /dev/null +++ b/chrome/browser/browser_accessibility_win_unittest.cc @@ -0,0 +1,111 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_ptr.h" +#include "chrome/browser/browser_accessibility_manager_win.h" +#include "chrome/browser/browser_accessibility_win.h" +#include "testing/gtest/include/gtest/gtest.h" + +using webkit_glue::WebAccessibility; + +// Subclass of BrowserAccessibility that counts the number of instances. +class CountedBrowserAccessibility : public BrowserAccessibility { + public: + CountedBrowserAccessibility() { global_obj_count_++; } + virtual ~CountedBrowserAccessibility() { global_obj_count_--; } + static int global_obj_count_; +}; + +int CountedBrowserAccessibility::global_obj_count_ = 0; + +// Factory that creates a CountedBrowserAccessibility. +class CountedBrowserAccessibilityFactory : public BrowserAccessibilityFactory { + public: + virtual ~CountedBrowserAccessibilityFactory() {} + virtual BrowserAccessibility* Create() { + CComObject* instance; + HRESULT hr = CComObject::CreateInstance( + &instance); + DCHECK(SUCCEEDED(hr)); + return instance->NewReference(); + } +}; + +// Test that BrowserAccessibilityManager correctly releases the tree of +// BrowserAccessibility instances upon delete. +TEST(BrowserAccessibilityTest, TestNoLeaks) { + // ATL needs a pointer to a COM module. + CComModule module; + _pAtlModule = &module; + // Make sure COM is initialized for this thread; it's safe to call twice. + ::CoInitialize(NULL); + + // Create WebAccessibility objects for a simple document tree, + // representing the accessibility information used to initialize + // BrowserAccessibilityManager. + WebAccessibility button; + button.id = 2; + button.name = L"Button"; + button.role = WebAccessibility::ROLE_BUTTON; + button.state = 0; + + WebAccessibility checkbox; + checkbox.id = 3; + checkbox.name = L"Checkbox"; + checkbox.role = WebAccessibility::ROLE_CHECKBOX; + checkbox.state = 0; + + WebAccessibility root; + root.id = 1; + root.name = L"Document"; + root.role = WebAccessibility::ROLE_DOCUMENT; + root.state = 0; + root.children.push_back(button); + root.children.push_back(checkbox); + + // Construct a BrowserAccessibilityManager with this WebAccessibility tree + // and a factory for an instance-counting BrowserAccessibility, and ensure + // that exactly 3 instances were created. Note that the manager takes + // ownership of the factory. + CountedBrowserAccessibility::global_obj_count_ = 0; + BrowserAccessibilityManager* manager = + new BrowserAccessibilityManager( + GetDesktopWindow(), root, NULL, + new CountedBrowserAccessibilityFactory()); + ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); + + // Delete the manager and test that all 3 instances are deleted. + delete manager; + ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); + + // Construct a manager again, and this time use the IAccessible interface + // to get new references to two of the three nodes in the tree. + manager = new BrowserAccessibilityManager( + GetDesktopWindow(), root, NULL, + new CountedBrowserAccessibilityFactory()); + ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); + BrowserAccessibility* root_accessible = manager->GetRoot(); + IDispatch* root_iaccessible = NULL; + IDispatch* child1_iaccessible = NULL; + VARIANT var_child; + var_child.vt = VT_I4; + var_child.lVal = CHILDID_SELF; + HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible); + ASSERT_EQ(S_OK, hr); + var_child.lVal = 1; + hr = root_accessible->get_accChild(var_child, &child1_iaccessible); + ASSERT_EQ(S_OK, hr); + + // Now delete the manager, and only one of the three nodes in the tree + // should be released. + delete manager; + ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_); + + // Release each of our references and make sure that each one results in + // the instance being deleted as its reference count hits zero. + root_iaccessible->Release(); + ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_); + child1_iaccessible->Release(); + ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); +} diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index a5414b6..03a179e 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -49,7 +49,7 @@ #if defined(OS_WIN) // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. -#include "chrome/browser/browser_accessibility_manager.h" +#include "chrome/browser/browser_accessibility_manager_win.h" #endif using base::TimeDelta; diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index 7932e00..a616e06 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -13,8 +13,8 @@ #include "base/process_util.h" #include "base/thread.h" #include "base/win_util.h" -#include "chrome/browser/browser_accessibility.h" -#include "chrome/browser/browser_accessibility_manager.h" +#include "chrome/browser/browser_accessibility_win.h" +#include "chrome/browser/browser_accessibility_manager_win.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_trial.h" #include "chrome/browser/chrome_thread.h" diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h index 134ea76..fe524cd7 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.h +++ b/chrome/browser/renderer_host/render_widget_host_view_win.h @@ -15,7 +15,7 @@ #include "base/scoped_comptr_win.h" #include "base/scoped_ptr.h" #include "base/task.h" -#include "chrome/browser/browser_accessibility_manager.h" +#include "chrome/browser/browser_accessibility_manager_win.h" #include "chrome/browser/ime_input.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/common/notification_registrar.h" diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index e6d57e8..f94df80 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -254,10 +254,10 @@ 'browser/browser.h', 'browser/browser_about_handler.cc', 'browser/browser_about_handler.h', - 'browser/browser_accessibility.cc', - 'browser/browser_accessibility.h', - 'browser/browser_accessibility_manager.cc', - 'browser/browser_accessibility_manager.h', + 'browser/browser_accessibility_win.cc', + 'browser/browser_accessibility_win.h', + 'browser/browser_accessibility_manager_win.cc', + 'browser/browser_accessibility_manager_win.h', 'browser/browser_init.cc', 'browser/browser_init.h', 'browser/browser_list_gtk.cc', @@ -3348,8 +3348,8 @@ 'browser/autocomplete/autocomplete_accessibility.cc', 'browser/bookmarks/bookmark_menu_controller.cc', 'browser/bookmarks/bookmark_menu_controller.h', - 'browser/browser_accessibility.cc', - 'browser/browser_accessibility_manager.cc', + 'browser/browser_accessibility_win.cc', + 'browser/browser_accessibility_manager_win.cc', 'browser/google_update.cc', 'browser/history/history_indexer.idl', 'browser/history_tab_ui.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 0366c10..e4dfbb9 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -589,7 +589,7 @@ 'browser/bookmarks/bookmark_model_unittest.cc', 'browser/bookmarks/bookmark_utils_unittest.cc', 'browser/browser_about_handler_unittest.cc', - 'browser/browser_accessibility_unittest.cc', + 'browser/browser_accessibility_win_unittest.cc', 'browser/browser_commands_unittest.cc', 'browser/browser_theme_pack_unittest.cc', 'browser/browser_theme_provider_unittest.cc', @@ -1246,7 +1246,7 @@ 'sources!': [ 'browser/bookmarks/bookmark_codec_unittest.cc', 'browser/bookmarks/bookmark_drag_data_unittest.cc', - 'browser/browser_accessibility_unittest.cc', + 'browser/browser_accessibility_win_unittest.cc', 'browser/chrome_plugin_unittest.cc', 'browser/extensions/extension_process_manager_unittest.cc', 'browser/importer/importer_unittest.cc', -- cgit v1.1