diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-05-09 14:22:11 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-05-09 15:11:45 +0000 |
commit | 2ddb2d3e14eef3de7dbd0cef553d669b9ac2361c (patch) | |
tree | e75f511546c5fd1a173e87c1f9fb11d7ac8d1af3 /chromium/ui/accessibility/platform | |
parent | a4f3d46271c57e8155ba912df46a05559d14726e (diff) | |
download | qtwebengine-chromium-2ddb2d3e14eef3de7dbd0cef553d669b9ac2361c.tar.gz |
BASELINE: Update Chromium to 51.0.2704.41
Also adds in all smaller components by reversing logic for exclusion.
Change-Id: Ibf90b506e7da088ea2f65dcf23f2b0992c504422
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'chromium/ui/accessibility/platform')
11 files changed, 264 insertions, 92 deletions
diff --git a/chromium/ui/accessibility/platform/atk_util_auralinux.cc b/chromium/ui/accessibility/platform/atk_util_auralinux.cc index 02563199409..46ad3be53be 100644 --- a/chromium/ui/accessibility/platform/atk_util_auralinux.cc +++ b/chromium/ui/accessibility/platform/atk_util_auralinux.cc @@ -8,7 +8,9 @@ #endif #include <glib-2.0/gmodule.h> +#include "base/bind.h" #include "base/files/file_path.h" +#include "base/location.h" #include "base/logging.h" #include "base/memory/singleton.h" #include "ui/accessibility/platform/atk_util_auralinux.h" @@ -16,41 +18,42 @@ namespace { -#if defined(USE_GCONF) +typedef void (*gnome_accessibility_module_init)(); -const char kGnomeAccessibilityEnabledKey[] = - "/desktop/gnome/interface/accessibility"; +const char kAtkBridgePath[] = "gtk-2.0/modules/libatk-bridge.so"; +const char kAtkBridgeSymbolName[] = "gnome_accessibility_module_init"; -bool ShouldEnableAccessibility() { - GConfClient* client = gconf_client_get_default(); - if (!client) { - LOG(ERROR) << "gconf_client_get_default failed"; +gnome_accessibility_module_init g_accessibility_module_init = nullptr; + +bool AccessibilityModuleInitOnFileThread() { + // Try to load libatk-bridge.so. + base::FilePath atk_bridge_path(ATK_LIB_DIR); + atk_bridge_path = atk_bridge_path.Append(kAtkBridgePath); + GModule* bridge = g_module_open(atk_bridge_path.value().c_str(), + static_cast<GModuleFlags>(0)); + if (!bridge) { + VLOG(1) << "Unable to open module " << atk_bridge_path.value(); return false; } - GError* error = nullptr; - gboolean value = gconf_client_get_bool(client, - kGnomeAccessibilityEnabledKey, - &error); - if (error) { - VLOG(1) << "gconf_client_get_bool failed"; - g_error_free(error); - g_object_unref(client); + if (!g_module_symbol(bridge, kAtkBridgeSymbolName, + (gpointer *)&g_accessibility_module_init)) { + VLOG(1) << "Unable to get symbol pointer from " << atk_bridge_path.value(); + // Just to make sure it's null; + g_accessibility_module_init = nullptr; return false; } - g_object_unref(client); - return value; + return true; } -#else // !defined(USE_GCONF) +#if defined(USE_GCONF) -bool ShouldEnableAccessibility() { - // TODO(k.czech): implement this for non-GNOME desktops. - return false; -} +const char kAccessibilityEnabled[] = "ACCESSIBILITY_ENABLED"; +const char kGnomeAccessibilityEnabledKey[] = + "/desktop/gnome/interface/accessibility"; -#endif // defined(USE_GCONF) +#endif } // namespace @@ -139,44 +142,88 @@ AtkUtilAuraLinux* AtkUtilAuraLinux::GetInstance() { return base::Singleton<AtkUtilAuraLinux>::get(); } +#if defined(USE_GCONF) + +AtkUtilAuraLinux::AtkUtilAuraLinux() + : is_enabled_(false) { +} + +#else + AtkUtilAuraLinux::AtkUtilAuraLinux() { } +#endif // defined(USE_GCONF) + void AtkUtilAuraLinux::Initialize( - scoped_refptr<base::TaskRunner> /* init_task_runner */) { - // TODO(k.czech): use |init_task_runner| to post a task to do the - // initialization rather than doing it on this thread. - // http://crbug.com/468112 + scoped_refptr<base::TaskRunner> init_task_runner) { // Register our util class. g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE)); - if (!ShouldEnableAccessibility()) { - VLOG(1) << "Will not enable ATK accessibility support."; - return; + init_task_runner->PostTaskAndReply( + FROM_HERE, + base::Bind( + &AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread, + base::Unretained(this)), + base::Bind( + &AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread, + base::Unretained(this))); +} + +AtkUtilAuraLinux::~AtkUtilAuraLinux() { +} + +#if defined(USE_GCONF) + +void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread() { + char* enable_accessibility = getenv(kAccessibilityEnabled); + if ((enable_accessibility && atoi(enable_accessibility) == 1) || + CheckPlatformAccessibilitySupportOnFileThread()) + is_enabled_ = AccessibilityModuleInitOnFileThread(); +} + +bool AtkUtilAuraLinux::CheckPlatformAccessibilitySupportOnFileThread() { + GConfClient* client = gconf_client_get_default(); + if (!client) { + LOG(ERROR) << "gconf_client_get_default failed"; + return false; } - VLOG(1) << "Enabling ATK accessibility support."; + GError* error = nullptr; + bool is_enabled = gconf_client_get_bool(client, + kGnomeAccessibilityEnabledKey, + &error); - // Try to load libatk-bridge.so. - base::FilePath atk_bridge_path(ATK_LIB_DIR); - atk_bridge_path = atk_bridge_path.Append("gtk-2.0/modules/libatk-bridge.so"); - GModule* bridge = g_module_open(atk_bridge_path.value().c_str(), - static_cast<GModuleFlags>(0)); - if (!bridge) { - VLOG(1) << "Unable to open module " << atk_bridge_path.value(); - return; + g_object_unref(client); + + if (error) { + VLOG(1) << "gconf_client_get_bool failed"; + g_error_free(error); + return false; } - // Try to call gnome_accessibility_module_init from libatk-bridge.so. - void (*gnome_accessibility_module_init)(); - if (g_module_symbol(bridge, "gnome_accessibility_module_init", - (gpointer *)&gnome_accessibility_module_init)) { - (*gnome_accessibility_module_init)(); + return is_enabled; +} + +void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() { + if (!is_enabled_) { + VLOG(1) << "Will not enable ATK accessibility support."; + return; } + + DCHECK(g_accessibility_module_init); + g_accessibility_module_init(); } -AtkUtilAuraLinux::~AtkUtilAuraLinux() { +#else + +void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread() { +} + +void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() { } +#endif // defined(USE_GCONF) + } // namespace ui diff --git a/chromium/ui/accessibility/platform/atk_util_auralinux.h b/chromium/ui/accessibility/platform/atk_util_auralinux.h index a5bc75d9311..8342a1299c7 100644 --- a/chromium/ui/accessibility/platform/atk_util_auralinux.h +++ b/chromium/ui/accessibility/platform/atk_util_auralinux.h @@ -29,6 +29,14 @@ class AtkUtilAuraLinux { private: friend struct base::DefaultSingletonTraits<AtkUtilAuraLinux>; + + void CheckIfAccessibilityIsEnabledOnFileThread(); + bool CheckPlatformAccessibilitySupportOnFileThread(); + void FinishAccessibilityInitOnUIThread(); + +#if defined(USE_GCONF) + bool is_enabled_; +#endif }; } // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node.cc b/chromium/ui/accessibility/platform/ax_platform_node.cc index 8f889458ddb..adfcc1e2ad2 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node.cc @@ -4,12 +4,23 @@ #include "ui/accessibility/platform/ax_platform_node.h" +#include "base/containers/hash_tables.h" +#include "base/lazy_instance.h" #include "build/build_config.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" namespace ui { +namespace { + +using UniqueIdMap = base::hash_map<int32_t, AXPlatformNode*>; +// Map from each AXPlatformNode's unique id to its instance. +base::LazyInstance<UniqueIdMap> g_unique_id_map = + LAZY_INSTANCE_INITIALIZER; + +} + #if !defined(PLATFORM_HAS_AX_PLATFORM_NODE_IMPL) // static AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { @@ -28,10 +39,39 @@ AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( } #endif -AXPlatformNode::AXPlatformNode() { +// static +int32_t AXPlatformNode::GetNextUniqueId() { + static int32_t next_unique_id = 1; + int32_t unique_id = next_unique_id; + if (next_unique_id == INT32_MAX) + next_unique_id = 1; + else + next_unique_id++; + + return unique_id; +} + +AXPlatformNode::AXPlatformNode() : unique_id_(GetNextUniqueId()) { + g_unique_id_map.Get()[unique_id_] = this; } AXPlatformNode::~AXPlatformNode() { + if (unique_id_) + g_unique_id_map.Get().erase(unique_id_); +} + +void AXPlatformNode::Destroy() { + g_unique_id_map.Get().erase(unique_id_); + unique_id_ = 0; +} + +AXPlatformNode* AXPlatformNode::GetFromUniqueId(int32_t unique_id) { + UniqueIdMap* unique_ids = g_unique_id_map.Pointer(); + auto iter = unique_ids->find(unique_id); + if (iter != unique_ids->end()) + return iter->second; + + return nullptr; } } // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node.h b/chromium/ui/accessibility/platform/ax_platform_node.h index 1d0ed510b38..c9df25947dd 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node.h +++ b/chromium/ui/accessibility/platform/ax_platform_node.h @@ -46,9 +46,17 @@ class AX_EXPORT AXPlatformNode { static AXPlatformNode* FromNativeViewAccessible( gfx::NativeViewAccessible accessible); + // Each platform accessibility object has a unique id that's guaranteed + // to be a positive number. (It's stored in an int32_t as opposed to + // uint32_t because some platforms want to negate it, so we want to ensure + // the range is below the signed int max.) This can be used when the + // id has to be unique across multiple frames, since node ids are + // only unique within one tree. + static int32_t GetNextUniqueId(); + // Call Destroy rather than deleting this, because the subclass may // use reference counting. - virtual void Destroy() = 0; + virtual void Destroy(); // Get the platform-specific accessible object type for this instance. // On some platforms this is just a type cast, on others it may be a @@ -65,6 +73,10 @@ class AX_EXPORT AXPlatformNode { protected: AXPlatformNode(); virtual ~AXPlatformNode(); + + AXPlatformNode* GetFromUniqueId(int32_t unique_id); + + int32_t unique_id_; }; } // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc index 801c3473e66..04e96c02ba5 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc @@ -448,14 +448,15 @@ void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) { atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDED); if (state & (1 << ui::AX_STATE_FOCUSABLE)) atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSABLE); - if (state & (1 << ui::AX_STATE_FOCUSED)) - atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSED); if (state & (1 << ui::AX_STATE_PRESSED)) atk_state_set_add_state(atk_state_set, ATK_STATE_PRESSED); if (state & (1 << ui::AX_STATE_SELECTABLE)) atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE); if (state & (1 << ui::AX_STATE_SELECTED)) atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTED); + + if (delegate_->GetFocus() == GetNativeViewAccessible()) + atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSED); } void AXPlatformNodeAuraLinux::GetAtkRelations(AtkRelationSet* atk_relation_set) diff --git a/chromium/ui/accessibility/platform/ax_platform_node_base.cc b/chromium/ui/accessibility/platform/ax_platform_node_base.cc index 2c1bf90507d..4937e4d3178 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_base.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_base.cc @@ -44,6 +44,7 @@ gfx::NativeViewAccessible AXPlatformNodeBase::ChildAtIndex(int index) { // AXPlatformNode overrides. void AXPlatformNodeBase::Destroy() { + AXPlatformNode::Destroy(); delegate_ = nullptr; delete this; } @@ -92,7 +93,10 @@ bool AXPlatformNodeBase::IsDescendant(AXPlatformNodeBase* node) { return false; if (node == this) return true; - AXPlatformNodeBase* parent = FromNativeViewAccessible(node->GetParent()); + gfx::NativeViewAccessible native_parent = node->GetParent(); + if (!native_parent) + return false; + AXPlatformNodeBase* parent = FromNativeViewAccessible(native_parent); return IsDescendant(parent); } diff --git a/chromium/ui/accessibility/platform/ax_platform_node_mac.mm b/chromium/ui/accessibility/platform/ax_platform_node_mac.mm index a4384f9ac77..c4b54d421bd 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/chromium/ui/accessibility/platform/ax_platform_node_mac.mm @@ -24,6 +24,7 @@ typedef std::map<ui::AXRole, NSString*> RoleMap; RoleMap BuildRoleMap() { const MapEntry roles[] = { + {ui::AX_ROLE_ABBR, NSAccessibilityGroupRole}, {ui::AX_ROLE_ALERT, NSAccessibilityGroupRole}, {ui::AX_ROLE_ALERT_DIALOG, NSAccessibilityGroupRole}, {ui::AX_ROLE_ANNOTATION, NSAccessibilityUnknownRole}, @@ -55,6 +56,7 @@ RoleMap BuildRoleMap() { {ui::AX_ROLE_DISCLOSURE_TRIANGLE, NSAccessibilityDisclosureTriangleRole}, {ui::AX_ROLE_DIV, NSAccessibilityGroupRole}, {ui::AX_ROLE_DOCUMENT, NSAccessibilityGroupRole}, + {ui::AX_ROLE_EMBEDDED_OBJECT, NSAccessibilityGroupRole}, {ui::AX_ROLE_FIGCAPTION, NSAccessibilityGroupRole}, {ui::AX_ROLE_FIGURE, NSAccessibilityGroupRole}, {ui::AX_ROLE_FOOTER, NSAccessibilityGroupRole}, diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win.cc b/chromium/ui/accessibility/platform/ax_platform_node_win.cc index ee7a4f9f8c6..c8f7d5445c3 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_win.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_win.cc @@ -78,35 +78,36 @@ namespace ui { namespace { -typedef base::hash_map<LONG, AXPlatformNodeWin*> UniqueIdWinMap; -// Map from each AXPlatformNodeWin's unique id to its instance. -base::LazyInstance<UniqueIdWinMap> g_unique_id_win_map = - LAZY_INSTANCE_INITIALIZER; - typedef base::hash_set<AXPlatformNodeWin*> AXPlatformNodeWinSet; // Set of all AXPlatformNodeWin objects that were the target of an // alert event. base::LazyInstance<AXPlatformNodeWinSet> g_alert_targets = LAZY_INSTANCE_INITIALIZER; -LONG GetNextNegativeUniqueIdForWinAccessibility(AXPlatformNodeWin* obj) { - static LONG next_unique_id = -1; - LONG unique_id = next_unique_id; - if (next_unique_id == LONG_MIN) - next_unique_id = -1; - else - next_unique_id--; +base::LazyInstance<base::ObserverList<IAccessible2UsageObserver>> + g_iaccessible2_usage_observer_list = LAZY_INSTANCE_INITIALIZER; + +} // namespace - g_unique_id_win_map.Get().insert(std::make_pair(unique_id, obj)); +// +// IAccessible2UsageObserver +// - return unique_id; +IAccessible2UsageObserver::IAccessible2UsageObserver() { } -void UnregisterNegativeUniqueId(LONG unique_id) { - g_unique_id_win_map.Get().erase(unique_id); +IAccessible2UsageObserver::~IAccessible2UsageObserver() { } -} // namespace +// static +base::ObserverList<IAccessible2UsageObserver>& + GetIAccessible2UsageObserverList() { + return g_iaccessible2_usage_observer_list.Get(); +} + +// +// AXPlatformNode::Create +// // static AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { @@ -129,8 +130,11 @@ AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( return ax_platform_node.get(); } -AXPlatformNodeWin::AXPlatformNodeWin() - : unique_id_win_(GetNextNegativeUniqueIdForWinAccessibility(this)) { +// +// AXPlatformNodeWin +// + +AXPlatformNodeWin::AXPlatformNodeWin() { } AXPlatformNodeWin::~AXPlatformNodeWin() { @@ -143,7 +147,6 @@ AXPlatformNodeWin::~AXPlatformNodeWin() { void AXPlatformNodeWin::Destroy() { delegate_ = nullptr; - UnregisterNegativeUniqueId(unique_id_win_); RemoveAlertTarget(); Release(); } @@ -157,11 +160,17 @@ void AXPlatformNodeWin::NotifyAccessibilityEvent(ui::AXEvent event_type) { if (!hwnd) return; + // Menu items fire selection events but Windows screen readers work reliably + // with focus events. Remap here. + if (event_type == ui::AX_EVENT_SELECTION && + GetData().role == ui::AX_ROLE_MENU_ITEM) + event_type = ui::AX_EVENT_FOCUS; + int native_event = MSAAEvent(event_type); if (native_event < EVENT_MIN) return; - ::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, unique_id_win_); + ::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, -unique_id_); // Keep track of objects that are a target of an alert event. if (event_type == ui::AX_EVENT_ALERT) @@ -324,25 +333,28 @@ STDMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child, // that want to enumerate all immediate children. *disp_child = delegate_->ChildAtIndex(child_id - 1); if (!(*disp_child)) - return E_FAIL; + return E_INVALIDARG; (*disp_child)->AddRef(); return S_OK; } if (child_id >= 0) - return E_FAIL; + return E_INVALIDARG; // Negative child ids can be used to map to any descendant. - UniqueIdWinMap* unique_ids = g_unique_id_win_map.Pointer(); - auto iter = unique_ids->find(child_id); - if (iter != unique_ids->end()) { - *disp_child = iter->second; + AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>( + GetFromUniqueId(-child_id)); + if (child && !IsDescendant(child)) + child = nullptr; + + if (child) { + *disp_child = child; (*disp_child)->AddRef(); return S_OK; } *disp_child = nullptr; - return E_FAIL; + return E_INVALIDARG; } STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { @@ -498,7 +510,7 @@ STDMETHODIMP AXPlatformNodeWin::get_states(AccessibleStates* states) { STDMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* unique_id) { COM_OBJECT_VALIDATE_1_ARG(unique_id); - *unique_id = unique_id_win_; + *unique_id = -unique_id_; return S_OK; } @@ -876,6 +888,13 @@ STDMETHODIMP AXPlatformNodeWin::scrollSubstringToPoint( STDMETHODIMP AXPlatformNodeWin::QueryService( REFGUID guidService, REFIID riid, void** object) { COM_OBJECT_VALIDATE_1_ARG(object); + + if (riid == IID_IAccessible2) { + FOR_EACH_OBSERVER(IAccessible2UsageObserver, + GetIAccessible2UsageObserverList(), + OnIAccessible2Used()); + } + if (guidService == IID_IAccessible || guidService == IID_IAccessible2 || guidService == IID_IAccessible2_2 || @@ -982,8 +1001,6 @@ int AXPlatformNodeWin::MSAAState() { msaa_state |= STATE_SYSTEM_EXPANDED; if (state & (1 << ui::AX_STATE_FOCUSABLE)) msaa_state |= STATE_SYSTEM_FOCUSABLE; - if (state & (1 << ui::AX_STATE_FOCUSED)) - msaa_state |= STATE_SYSTEM_FOCUSED; if (state & (1 << ui::AX_STATE_HASPOPUP)) msaa_state |= STATE_SYSTEM_HASPOPUP; if (state & (1 << ui::AX_STATE_HOVERED)) @@ -1007,6 +1024,21 @@ int AXPlatformNodeWin::MSAAState() { if (state & (1 << ui::AX_STATE_DISABLED)) msaa_state |= STATE_SYSTEM_UNAVAILABLE; + gfx::NativeViewAccessible focus = delegate_->GetFocus(); + if (focus == GetNativeViewAccessible()) + msaa_state |= STATE_SYSTEM_FOCUSED; + + // On Windows, the "focus" bit should be set on certain containers, like + // menu bars, when visible. + // + // TODO(dmazzoni): this should probably check if focus is actually inside + // the menu bar, but we don't currently track focus inside menu pop-ups, + // and Chrome only has one menu visible at a time so this works for now. + if (GetData().role == ui::AX_ROLE_MENU_BAR && + !(state & (1 << ui::AX_STATE_INVISIBLE))) { + msaa_state |= STATE_SYSTEM_FOCUSED; + } + return msaa_state; } diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win.h b/chromium/ui/accessibility/platform/ax_platform_node_win.h index 5d264211b34..eb747ed4d0b 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_win.h +++ b/chromium/ui/accessibility/platform/ax_platform_node_win.h @@ -9,11 +9,29 @@ #include <atlcom.h> #include <oleacc.h> +#include "base/observer_list.h" #include "third_party/iaccessible2/ia2_api_all.h" +#include "ui/accessibility/ax_export.h" +#include "ui/accessibility/ax_text_utils.h" #include "ui/accessibility/platform/ax_platform_node_base.h" namespace ui { +// A simple interface for a class that wants to be notified when IAccessible2 +// is used by a client, a strong indication that full accessibility support +// should be enabled. +class AX_EXPORT IAccessible2UsageObserver { + public: + IAccessible2UsageObserver(); + virtual ~IAccessible2UsageObserver(); + virtual void OnIAccessible2Used() = 0; +}; + +// Get an observer list that allows modules across the codebase to +// listen to when usage of IAccessible2 is detected. +extern AX_EXPORT base::ObserverList<IAccessible2UsageObserver>& + GetIAccessible2UsageObserverList(); + class __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2")) AXPlatformNodeWin : public CComObjectRootEx<CComMultiThreadModel>, @@ -279,16 +297,6 @@ AXPlatformNodeWin IA2TextBoundaryType ia2_boundary, LONG start_offset, ui::TextBoundaryDirection direction); - - // A windows-specific unique ID for this object. It's returned in - // IAccessible2::get_uniqueID, but more importantly it's used for - // firing events. On Windows, we fire events on the nearest parent HWND - // and pass the unique ID as the child id parameter. When the client - // wants to retrieve the object the event was fired on, it calls - // get_accChild and passes the child ID. We use negative IDs for the unique - // ID so we can distinguish a request for an arbitrary child from a request - // for an immediate child of an object by its 0-based index. - LONG unique_id_win_; }; } // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc index 08be59b21f1..d5a4f81e501 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc @@ -315,7 +315,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { // Asking for child id 3 should fail. ScopedComPtr<IDispatch> result; ScopedVariant child3(3); - ASSERT_EQ(E_FAIL, root_iaccessible->get_accChild(child3, result.Receive())); + ASSERT_EQ(E_INVALIDARG, + root_iaccessible->get_accChild(child3, result.Receive())); } // We should be able to ask for the button by its unique id too. @@ -332,6 +333,20 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { ASSERT_EQ(result.get(), button_iaccessible); } + // We shouldn't be able to ask for the root node by its unique ID + // from one of its children, though. + LONG root_unique_id; + ScopedComPtr<IAccessible2> root_iaccessible2 = + ToIAccessible2(root_iaccessible); + root_iaccessible2->get_uniqueID(&root_unique_id); + ASSERT_LT(root_unique_id, 0); + { + ScopedComPtr<IDispatch> result; + ScopedVariant root_id_variant(root_unique_id); + ASSERT_EQ(E_INVALIDARG, button_iaccessible->get_accChild(root_id_variant, + result.Receive())); + } + // Now check parents. { ScopedComPtr<IDispatch> result; diff --git a/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc b/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc index fbb76ca13be..f2b91731aa4 100644 --- a/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc @@ -18,6 +18,9 @@ gfx::Vector2d g_offset; // A simple implementation of AXTreeDelegate to catch when AXNodes are // deleted so we can delete their wrappers. class TestAXTreeDelegate : public AXTreeDelegate { + void OnNodeDataWillChange(AXTree* tree, + const AXNodeData& old_node_data, + const AXNodeData& new_node_data) override {} void OnTreeDataChanged(AXTree* tree) override {} void OnNodeWillBeDeleted(AXTree* tree, AXNode* node) override { auto iter = g_node_to_wrapper_map.find(node); |