diff options
author | ctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-22 00:03:22 +0000 |
---|---|---|
committer | ctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-22 00:03:22 +0000 |
commit | 5fe1572eaaec0f18f8126b9d6d48e7f575e9bcb2 (patch) | |
tree | 185fc94efbf78529bd3cbfdf9fb04f04f8e64fe3 /views/accessibility | |
parent | 3b12395d378c0740947438ddeb770de52ad3162a (diff) | |
download | chromium_src-5fe1572eaaec0f18f8126b9d6d48e7f575e9bcb2.zip chromium_src-5fe1572eaaec0f18f8126b9d6d48e7f575e9bcb2.tar.gz chromium_src-5fe1572eaaec0f18f8126b9d6d48e7f575e9bcb2.tar.bz2 |
Some cleanup of view accessibility and view accessibility wrapper.
1. Remove the ViewAccessibilityWrapper class. The view can directly manage it's ViewAccessibility.
2. Always use GetAccessibleForView to retrieve a view's associated accessibility object. This ensures that the correct accessibility object is returned for native view host objects.
3. Update get_accFocus to use FocusManager.
4. Move oleacc guid definitions to view_win.cc.
BUG=none
TEST=interactive_ui_tests:BrowserViewsAccessibilityTest.TestBrowserRootViewAccObj
TEST=Manual: I can select the accessibility object of a native view host within AccExplorer32.exe.
Review URL: http://codereview.chromium.org/4047001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63451 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/accessibility')
-rw-r--r-- | views/accessibility/view_accessibility.cc | 245 | ||||
-rw-r--r-- | views/accessibility/view_accessibility.h | 31 | ||||
-rw-r--r-- | views/accessibility/view_accessibility_wrapper.cc | 93 | ||||
-rw-r--r-- | views/accessibility/view_accessibility_wrapper.h | 61 |
4 files changed, 109 insertions, 321 deletions
diff --git a/views/accessibility/view_accessibility.cc b/views/accessibility/view_accessibility.cc index 72042c4..c092895 100644 --- a/views/accessibility/view_accessibility.cc +++ b/views/accessibility/view_accessibility.cc @@ -4,24 +4,51 @@ #include "views/accessibility/view_accessibility.h" -#include "views/accessibility/view_accessibility_wrapper.h" #include "views/widget/widget.h" #include "views/widget/widget_win.h" -const wchar_t kViewsUninitializeAccessibilityInstance[] = - L"Views_Uninitialize_AccessibilityInstance"; - const wchar_t kViewsNativeHostPropForAccessibility[] = L"Views_NativeViewHostHWNDForAccessibility"; +// static +scoped_refptr<ViewAccessibility> ViewAccessibility::Create(views::View* view) { + CComObject<ViewAccessibility>* instance = NULL; + HRESULT hr = CComObject<ViewAccessibility>::CreateInstance(&instance); + DCHECK(SUCCEEDED(hr)); + instance->set_view(view); + return scoped_refptr<ViewAccessibility>(instance); +} -HRESULT ViewAccessibility::Initialize(views::View* view) { - if (!view) { - return E_INVALIDARG; +// static +IAccessible* ViewAccessibility::GetAccessibleForView(views::View* view) { + IAccessible* accessible = NULL; + + // First, check to see if the view is a native view. + if (view->GetClassName() == views::NativeViewHost::kViewClassName) { + views::NativeViewHost* native_host = + static_cast<views::NativeViewHost*>(view); + if (GetNativeIAccessibleInterface(native_host, &accessible) == S_OK) + return accessible; } - view_ = view; - return S_OK; + // Next, see if the view is a widget container. + if (view->child_widget()) { + views::WidgetWin* native_widget = + reinterpret_cast<views::WidgetWin*>(view->child_widget()); + if (GetNativeIAccessibleInterface( + native_widget->GetNativeView(), &accessible) == S_OK) { + return accessible; + } + } + + // Finally, use our ViewAccessibility implementation. + return view->GetViewAccessibility(); +} + +ViewAccessibility::ViewAccessibility() : view_(NULL) { +} + +ViewAccessibility::~ViewAccessibility() { } // TODO(ctguil): Handle case where child View is not contained by parent. @@ -49,25 +76,16 @@ STDMETHODIMP ViewAccessibility::accHitTest( child->lVal = CHILDID_SELF; } else { child->vt = VT_DISPATCH; - if ((GetViewAccessibilityWrapper(view))-> - GetInstance(IID_IAccessible, - reinterpret_cast<void**>(&child->pdispVal)) == S_OK) { - // Increment the reference count for the retrieved interface. - child->pdispVal->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } + child->pdispVal = GetAccessibleForView(view); + child->pdispVal->AddRef(); } - return S_OK; } STDMETHODIMP ViewAccessibility::accLocation( LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { - if (!IsValidId(var_id) || !x_left || !y_top || !width || !height) { + if (!IsValidId(var_id) || !x_left || !y_top || !width || !height) return E_INVALIDARG; - } if (!view_) return E_FAIL; @@ -101,9 +119,8 @@ STDMETHODIMP ViewAccessibility::accLocation( STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start, VARIANT* end) { - if (start.vt != VT_I4 || !end) { + if (start.vt != VT_I4 || !end) return E_INVALIDARG; - } if (!view_) return E_FAIL; @@ -126,25 +143,10 @@ STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start, } views::View* child = view_->GetChildViewAt(child_id); - - if (child->GetChildViewCount() != 0) { - end->vt = VT_DISPATCH; - if ((GetViewAccessibilityWrapper(child))-> - GetInstance(IID_IAccessible, - reinterpret_cast<void**>(&end->pdispVal)) == S_OK) { - // Increment the reference count for the retrieved interface. - end->pdispVal->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } - } else { - end->vt = VT_I4; - // Set return child lVal, adjusted for MSAA indexing. (MSAA - // child indexing starts with 1, whereas View indexing starts with 0). - end->lVal = child_id + 1; - } - break; + end->vt = VT_DISPATCH; + end->pdispVal = GetAccessibleForView(child); + end->pdispVal->AddRef(); + return S_OK; } case NAVDIR_LEFT: case NAVDIR_UP: @@ -176,24 +178,10 @@ STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start, } views::View* child = parent->GetChildViewAt(view_index); - if (child->GetChildViewCount() != 0) { - end->vt = VT_DISPATCH; - // Retrieve IDispatch for non-leaf child. - if ((GetViewAccessibilityWrapper(child))-> - GetInstance(IID_IAccessible, - reinterpret_cast<void**>(&end->pdispVal)) == S_OK) { - // Increment the reference count for the retrieved interface. - end->pdispVal->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } - } else { - end->vt = VT_I4; - // Modifying view_index to give lVal correct MSAA-based value. (MSAA - // child indexing starts with 1, whereas View indexing starts with 0). - end->lVal = view_index + 1; - } + end->pdispVal = GetAccessibleForView(child); + end->vt = VT_DISPATCH; + end->pdispVal->AddRef(); + return S_OK; } else { // Check navigation bounds, adjusting for MSAA child indexing (MSAA // child indexing starts with 1, whereas View indexing starts with 0). @@ -269,42 +257,14 @@ STDMETHODIMP ViewAccessibility::get_accChild(VARIANT var_child, return E_FAIL; } - // First, check to see if the child is a native view. - if (child_view->GetClassName() == views::NativeViewHost::kViewClassName) { - views::NativeViewHost* native_host = - static_cast<views::NativeViewHost*>(child_view); - if (GetNativeIAccessibleInterface(native_host, disp_child) == S_OK) - return S_OK; - } - - // Next, see if the child view is a widget container. - if (child_view->child_widget()) { - views::WidgetWin* native_widget = - reinterpret_cast<views::WidgetWin*>(child_view->child_widget()); - if (GetNativeIAccessibleInterface( - native_widget->GetNativeView(), disp_child) == S_OK) { - return S_OK; - } - } - - // Finally, try our ViewAccessibility implementation. - // Retrieve the IUnknown interface for the requested child view, and - // assign the IDispatch returned. - HRESULT hr = GetViewAccessibilityWrapper(child_view)-> - GetInstance(IID_IAccessible, reinterpret_cast<void**>(disp_child)); - if (hr == S_OK) { - // Increment the reference count for the retrieved interface. - (*disp_child)->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } + *disp_child = GetAccessibleForView(child_view); + (*disp_child)->AddRef(); + return S_OK; } STDMETHODIMP ViewAccessibility::get_accChildCount(LONG* child_count) { - if (!child_count || !view_) { + if (!child_count || !view_) return E_INVALIDARG; - } if (!view_) return E_FAIL; @@ -315,9 +275,8 @@ STDMETHODIMP ViewAccessibility::get_accChildCount(LONG* child_count) { STDMETHODIMP ViewAccessibility::get_accDefaultAction( VARIANT var_id, BSTR* def_action) { - if (!IsValidId(var_id) || !def_action) { + if (!IsValidId(var_id) || !def_action) return E_INVALIDARG; - } if (!view_) return E_FAIL; @@ -334,9 +293,11 @@ STDMETHODIMP ViewAccessibility::get_accDefaultAction( } STDMETHODIMP ViewAccessibility::get_accDescription(VARIANT var_id, BSTR* desc) { - if (!IsValidId(var_id) || !desc) { + if (!IsValidId(var_id) || !desc) return E_INVALIDARG; - } + + if (!view_) + return E_FAIL; std::wstring temp_desc; @@ -351,42 +312,29 @@ STDMETHODIMP ViewAccessibility::get_accDescription(VARIANT var_id, BSTR* desc) { } STDMETHODIMP ViewAccessibility::get_accFocus(VARIANT* focus_child) { - if (!focus_child) { + if (!focus_child) return E_INVALIDARG; - } if (!view_) return E_FAIL; - if (view_->GetChildViewCount() == 0 && view_->HasFocus()) { - // Parent view has focus. + views::View* focus = NULL; + views::FocusManager* focus_manager = view_->GetFocusManager(); + if (focus_manager) + focus = focus_manager->GetFocusedView(); + if (focus == view_) { + // This view has focus. focus_child->vt = VT_I4; focus_child->lVal = CHILDID_SELF; + } else if (focus && view_->IsParentOf(focus)) { + // Return the child object that has the keyboard focus. + focus_child->pdispVal = GetAccessibleForView(focus); + focus_child->pdispVal->AddRef(); + return S_OK; } else { - bool has_focus = false; - int child_count = view_->GetChildViewCount(); - // Search for child view with focus. - for (int child_id = 0; child_id < child_count; ++child_id) { - if (view_->GetChildViewAt(child_id)->HasFocus()) { - focus_child->vt = VT_I4; - focus_child->lVal = child_id + 1; - - // If child view is no leaf, retrieve IDispatch. - if (view_->GetChildViewAt(child_id)->GetChildViewCount() != 0) { - focus_child->vt = VT_DISPATCH; - this->get_accChild(*focus_child, &focus_child->pdispVal); - } - has_focus = true; - break; - } - } - // No current focus on any of the children. - if (!has_focus) { - focus_child->vt = VT_EMPTY; - return S_FALSE; - } + // Neither this object nor any of its children has the keyboard focus. + focus_child->vt = VT_EMPTY; } - return S_OK; } @@ -410,9 +358,8 @@ STDMETHODIMP ViewAccessibility::get_accKeyboardShortcut( } STDMETHODIMP ViewAccessibility::get_accName(VARIANT var_id, BSTR* name) { - if (!IsValidId(var_id) || !name) { + if (!IsValidId(var_id) || !name) return E_INVALIDARG; - } if (!view_) return E_FAIL; @@ -433,9 +380,8 @@ STDMETHODIMP ViewAccessibility::get_accName(VARIANT var_id, BSTR* name) { } STDMETHODIMP ViewAccessibility::get_accParent(IDispatch** disp_parent) { - if (!disp_parent) { + if (!disp_parent) return E_INVALIDARG; - } if (!view_) return E_FAIL; @@ -466,37 +412,34 @@ STDMETHODIMP ViewAccessibility::get_accParent(IDispatch** disp_parent) { return S_OK; } - // Retrieve the IUnknown interface for the parent view, and assign the - // IDispatch returned. - if ((GetViewAccessibilityWrapper(parent_view))-> - GetInstance(IID_IAccessible, - reinterpret_cast<void**>(disp_parent)) == S_OK) { - // Increment the reference count for the retrieved interface. - (*disp_parent)->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } + *disp_parent = GetAccessibleForView(parent_view); + (*disp_parent)->AddRef(); + return S_OK; } STDMETHODIMP ViewAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { if (!IsValidId(var_id) || !role) return E_INVALIDARG; + if (!view_) + return E_FAIL; + role->vt = VT_I4; role->lVal = MSAARole(view_->GetAccessibleRole()); return S_OK; } STDMETHODIMP ViewAccessibility::get_accState(VARIANT var_id, VARIANT* state) { - if (!IsValidId(var_id) || !state) { + if (!IsValidId(var_id) || !state) return E_INVALIDARG; - } + + if (!view_) + return E_FAIL; state->vt = VT_I4; // Retrieve all currently applicable states of the parent. - this->SetState(state, view_); + SetState(state, view_); // Make sure that state is not empty, and has the proper type. if (state->vt == VT_EMPTY) @@ -628,13 +571,6 @@ STDMETHODIMP ViewAccessibility::put_accName(VARIANT var_id, BSTR put_name) { } STDMETHODIMP ViewAccessibility::put_accValue(VARIANT var_id, BSTR put_val) { - // TODO(ctguil): This use looks incorrect. var_id should be of type VT_I4. - if (V_VT(&var_id) == VT_BSTR) { - if (!lstrcmpi(var_id.bstrVal, kViewsUninitializeAccessibilityInstance)) { - view_ = NULL; - return S_OK; - } - } // Deprecated. return E_NOTIMPL; } @@ -768,11 +704,11 @@ int32 ViewAccessibility::MSAAState(AccessibilityTypes::State state) { return msaa_state; } +// static HRESULT ViewAccessibility::GetNativeIAccessibleInterface( - views::NativeViewHost* native_host, IDispatch** disp_child) { - if (!native_host || !disp_child) { + views::NativeViewHost* native_host, IAccessible** accessible) { + if (!native_host || !accessible) return E_INVALIDARG; - } HWND native_view_window = static_cast<HWND>(GetProp(native_host->native_view(), @@ -781,16 +717,17 @@ HRESULT ViewAccessibility::GetNativeIAccessibleInterface( native_view_window = native_host->native_view(); } - return GetNativeIAccessibleInterface(native_view_window, disp_child); + return GetNativeIAccessibleInterface(native_view_window, accessible); } +// static HRESULT ViewAccessibility::GetNativeIAccessibleInterface( - HWND native_view_window , IDispatch** disp_child) { + HWND native_view_window , IAccessible** accessible) { if (IsWindow(native_view_window)) { LRESULT ret = SendMessage(native_view_window, WM_GETOBJECT, 0, OBJID_CLIENT); return ObjectFromLresult(ret, IID_IDispatch, 0, - reinterpret_cast<void**>(disp_child)); + reinterpret_cast<void**>(accessible)); } return E_FAIL; diff --git a/views/accessibility/view_accessibility.h b/views/accessibility/view_accessibility.h index 010eeb4..9803cba 100644 --- a/views/accessibility/view_accessibility.h +++ b/views/accessibility/view_accessibility.h @@ -11,6 +11,7 @@ #include <oleacc.h> +#include "base/scoped_ptr.h" #include "views/controls/native/native_view_host.h" #include "views/view.h" @@ -32,10 +33,15 @@ class ATL_NO_VTABLE ViewAccessibility COM_INTERFACE_ENTRY(IAccessible) END_COM_MAP() - ViewAccessibility() {} - ~ViewAccessibility() {} + // Create method for view accessibility. + static scoped_refptr<ViewAccessibility> Create(views::View* view); - HRESULT Initialize(views::View* view); + // Returns the IAccessible interface for a view. + static IAccessible* GetAccessibleForView(views::View* view); + + virtual ~ViewAccessibility(); + + void set_view(views::View* view) { view_ = view; } // Supported IAccessible methods. @@ -117,6 +123,8 @@ class ATL_NO_VTABLE ViewAccessibility static int32 MSAAState(AccessibilityTypes::State state); private: + ViewAccessibility(); + // Determines navigation direction for accNavigate, based on left, up and // previous being mapped all to previous and right, down, next being mapped // to next. Returns true if navigation direction is next, false otherwise. @@ -132,21 +140,19 @@ class ATL_NO_VTABLE ViewAccessibility // Determines if the child id variant is valid. bool IsValidId(const VARIANT& child) const; - // Wrapper to retrieve the view's instance of IAccessible. - ViewAccessibilityWrapper* GetViewAccessibilityWrapper(views::View* v) const { - return v->GetViewAccessibilityWrapper(); - } - // Helper function which sets applicable states of view. void SetState(VARIANT* msaa_state, views::View* view); // Returns the IAccessible interface for a native view if applicable. // Returns S_OK on success. - HRESULT GetNativeIAccessibleInterface(views::NativeViewHost* native_host, - IDispatch** disp_child); + static HRESULT GetNativeIAccessibleInterface( + views::NativeViewHost* native_host, IAccessible** accessible); + + static HRESULT GetNativeIAccessibleInterface( + HWND native_view_window, IAccessible** accessible); - HRESULT GetNativeIAccessibleInterface(HWND native_view_window, - IDispatch** disp_child); + // Give CComObject access to the class constructor. + template <class Base> friend class CComObject; // Member View needed for view-specific calls. views::View* view_; @@ -154,7 +160,6 @@ class ATL_NO_VTABLE ViewAccessibility DISALLOW_COPY_AND_ASSIGN(ViewAccessibility); }; -extern const wchar_t kViewsUninitializeAccessibilityInstance[]; extern const wchar_t kViewsNativeHostPropForAccessibility[]; #endif // VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_ diff --git a/views/accessibility/view_accessibility_wrapper.cc b/views/accessibility/view_accessibility_wrapper.cc deleted file mode 100644 index 989c90a..0000000 --- a/views/accessibility/view_accessibility_wrapper.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2006-2008 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 "views/accessibility/view_accessibility_wrapper.h" - -#include "base/scoped_variant_win.h" - -#include "views/accessibility/view_accessibility.h" - -//////////////////////////////////////////////////////////////////////////////// -// -// ViewAccessibilityWrapper - constructors, destructors -// -//////////////////////////////////////////////////////////////////////////////// - -ViewAccessibilityWrapper::ViewAccessibilityWrapper(views::View* view) - : accessibility_info_(NULL), - view_(view) { -} - -STDMETHODIMP ViewAccessibilityWrapper::CreateDefaultInstance(REFIID iid) { - if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) { - // If there is no instance of ViewAccessibility created, create it - // now. Otherwise reuse previous instance. - if (!accessibility_info_) { - CComObject<ViewAccessibility>* instance = NULL; - - HRESULT hr = CComObject<ViewAccessibility>::CreateInstance(&instance); - - if (!SUCCEEDED(hr) || !instance) - return E_FAIL; - - ScopedComPtr<IAccessible> accessibility_instance(instance); - - if (!SUCCEEDED(instance->Initialize(view_))) - return E_FAIL; - - // All is well, assign the temp instance to the class smart pointer. - accessibility_info_.Attach(accessibility_instance.Detach()); - } - return S_OK; - } - // Interface not supported. - return E_NOINTERFACE; -} - -HRESULT ViewAccessibilityWrapper::Uninitialize() { - view_ = NULL; - if (accessibility_info_.get()) { - accessibility_info_->put_accValue( - ScopedVariant(kViewsUninitializeAccessibilityInstance), NULL); - ::CoDisconnectObject(accessibility_info_.get(), 0); - accessibility_info_ = NULL; - } - - return S_OK; -} - -STDMETHODIMP ViewAccessibilityWrapper::GetInstance(REFIID iid, - void** interface_ptr) { - if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) { - // If there is no accessibility instance created, create a default now. - // Otherwise reuse previous instance. - if (!accessibility_info_) { - HRESULT hr = CreateDefaultInstance(iid); - - if (hr != S_OK) { - // Interface creation failed. - *interface_ptr = NULL; - return E_NOINTERFACE; - } - } - *interface_ptr = static_cast<IAccessible*>(accessibility_info_); - return S_OK; - } - // No supported interface found, return error. - *interface_ptr = NULL; - return E_NOINTERFACE; -} - -STDMETHODIMP ViewAccessibilityWrapper::SetInstance(IAccessible* interface_ptr) { - if (!interface_ptr) - return E_NOINTERFACE; - - accessibility_info_.Attach(interface_ptr); - - // Paranoia check, to make sure we do have a valid IAccessible pointer stored. - if (!accessibility_info_) - return E_FAIL; - - return S_OK; -} diff --git a/views/accessibility/view_accessibility_wrapper.h b/views/accessibility/view_accessibility_wrapper.h deleted file mode 100644 index ae4b563..0000000 --- a/views/accessibility/view_accessibility_wrapper.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2006-2008 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 VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_WRAPPER_H_ -#define VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_WRAPPER_H_ -#pragma once - -#include <atlcomcli.h> -// Necessary to define OleAcc GUID's used in window_win.cc. -#include <initguid.h> -#include <oleacc.h> - -#include "base/basictypes.h" -#include "base/scoped_comptr_win.h" - -namespace views { -class View; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// ViewAccessibilityWrapper -// -// Wrapper class for returning a pointer to the appropriate (platform-specific) -// accessibility interface for a given View. Needed to keep platform-specific -// code out of the View class, when answering calls for child/parent IAccessible -// implementations, for instance. -// -//////////////////////////////////////////////////////////////////////////////// -class ViewAccessibilityWrapper { - public: - explicit ViewAccessibilityWrapper(views::View* view); - ~ViewAccessibilityWrapper() {} - - STDMETHODIMP CreateDefaultInstance(REFIID iid); - - HRESULT Uninitialize(); - - // Returns a pointer to a specified interface on an object to which a client - // currently holds an interface pointer. If pointer exists, it is reused, - // otherwise a new pointer is created. Used by accessibility implementation to - // retrieve MSAA implementation for child or parent, when navigating MSAA - // hierarchy. - STDMETHODIMP GetInstance(REFIID iid, void** interface_ptr); - - // Sets the accessibility interface implementation of this wrapper to be - // anything the user specifies. - STDMETHODIMP SetInstance(IAccessible* interface_ptr); - - private: - // Instance of accessibility information and handling for a View. - ScopedComPtr<IAccessible> accessibility_info_; - - // View needed to initialize IAccessible. - views::View* view_; - - DISALLOW_COPY_AND_ASSIGN(ViewAccessibilityWrapper); -}; - -#endif // VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_WRAPPER_H_ |