diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-01-29 16:35:13 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-02-01 15:33:35 +0000 |
commit | c8c2d1901aec01e934adf561a9fdf0cc776cdef8 (patch) | |
tree | 9157c3d9815e5870799e070b113813bec53e0535 /chromium/ui/accessibility/platform | |
parent | abefd5095b41dac94ca451d784ab6e27372e981a (diff) | |
download | qtwebengine-chromium-c8c2d1901aec01e934adf561a9fdf0cc776cdef8.tar.gz |
BASELINE: Update Chromium to 64.0.3282.139
Change-Id: I1cae68fe9c94ff7608b26b8382fc19862cdb293a
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ui/accessibility/platform')
24 files changed, 2408 insertions, 773 deletions
diff --git a/chromium/ui/accessibility/platform/atk_util_auralinux.cc b/chromium/ui/accessibility/platform/atk_util_auralinux.cc index 207260ef57d..eab53e188d3 100644 --- a/chromium/ui/accessibility/platform/atk_util_auralinux.cc +++ b/chromium/ui/accessibility/platform/atk_util_auralinux.cc @@ -3,89 +3,15 @@ // found in the LICENSE file. #include <atk/atk.h> -#include <glib-2.0/gmodule.h> -#include "base/bind.h" #include "base/environment.h" -#include "base/files/file_path.h" -#include "base/location.h" -#include "base/logging.h" #include "base/memory/singleton.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/task_scheduler/post_task.h" -#include "base/threading/thread_restrictions.h" #include "ui/accessibility/platform/atk_util_auralinux.h" #include "ui/accessibility/platform/ax_platform_node_auralinux.h" namespace { -typedef void (*GnomeAccessibilityModuleInitFunc)(); - const char kAccessibilityEnabled[] = "ACCESSIBILITY_ENABLED"; -const char kAtkBridgeModule[] = "atk-bridge"; -const char kAtkBridgePath[] = "gtk-2.0/modules/libatk-bridge.so"; -const char kAtkBridgeSymbolName[] = "gnome_accessibility_module_init"; -const char kGtkModules[] = "GTK_MODULES"; - -// Returns a function pointer to be invoked on the main thread to init -// the gnome accessibility module if it's enabled (nullptr otherwise). -GnomeAccessibilityModuleInitFunc GetAccessibilityModuleInitFunc() { - base::ThreadRestrictions::AssertIOAllowed(); - - // 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 nullptr; - } - - GnomeAccessibilityModuleInitFunc init_func = nullptr; - - if (!g_module_symbol(bridge, kAtkBridgeSymbolName, (gpointer*)&init_func)) { - VLOG(1) << "Unable to get symbol pointer from " << atk_bridge_path.value(); - return nullptr; - } - - DCHECK(init_func); - return init_func; -} - -void FinishAccessibilityInitOnMainThread( - GnomeAccessibilityModuleInitFunc init_func) { - if (!init_func) { - VLOG(1) << "Will not enable ATK accessibility support."; - return; - } - - init_func(); -} - -bool PlatformShouldEnableAccessibility() { - std::unique_ptr<base::Environment> env(base::Environment::Create()); - std::string gtk_modules; - if (!env->GetVar(kGtkModules, >k_modules)) - return false; - - for (const std::string& module : - base::SplitString(gtk_modules, ":", base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY)) { - if (module == kAtkBridgeModule) - return true; - } - return false; -} - -bool ShouldEnableAccessibility() { - char* enable_accessibility = getenv(kAccessibilityEnabled); - if ((enable_accessibility && atoi(enable_accessibility) == 1) || - PlatformShouldEnableAccessibility()) - return true; - return false; -} } // namespace @@ -174,18 +100,34 @@ AtkUtilAuraLinux* AtkUtilAuraLinux::GetInstance() { return base::Singleton<AtkUtilAuraLinux>::get(); } +bool AtkUtilAuraLinux::ShouldEnableAccessibility() { + std::unique_ptr<base::Environment> env(base::Environment::Create()); + std::string enable_accessibility; + env->GetVar(kAccessibilityEnabled, &enable_accessibility); + if (enable_accessibility == "1" || PlatformShouldEnableAccessibility()) + return true; + return false; +} + void AtkUtilAuraLinux::InitializeAsync() { + static bool initialized = false; + + if (initialized || !ShouldEnableAccessibility()) + return; + + initialized = true; + // Register our util class. g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE)); - if (!ShouldEnableAccessibility()) - return; + PlatformInitializeAsync(); +} + +void AtkUtilAuraLinux::InitializeForTesting() { + std::unique_ptr<base::Environment> env(base::Environment::Create()); + env->SetVar(kAccessibilityEnabled, "1"); - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::Bind(&GetAccessibilityModuleInitFunc), - base::Bind(&FinishAccessibilityInitOnMainThread)); + InitializeAsync(); } } // namespace ui diff --git a/chromium/ui/accessibility/platform/atk_util_auralinux.h b/chromium/ui/accessibility/platform/atk_util_auralinux.h index 8119fb781c1..286d49a7203 100644 --- a/chromium/ui/accessibility/platform/atk_util_auralinux.h +++ b/chromium/ui/accessibility/platform/atk_util_auralinux.h @@ -14,7 +14,7 @@ namespace ui { // This singleton class initializes ATK (accessibility toolkit) and // registers an implementation of the AtkUtil class, a global class that // every accessible application needs to register once. -class AtkUtilAuraLinux { +class AX_EXPORT AtkUtilAuraLinux { public: // Get the single instance of this class. static AtkUtilAuraLinux* GetInstance(); @@ -22,10 +22,16 @@ class AtkUtilAuraLinux { AtkUtilAuraLinux() = default; void InitializeAsync(); + void InitializeForTesting(); private: friend struct base::DefaultSingletonTraits<AtkUtilAuraLinux>; + bool ShouldEnableAccessibility(); + + bool PlatformShouldEnableAccessibility(); + void PlatformInitializeAsync(); + DISALLOW_COPY_AND_ASSIGN(AtkUtilAuraLinux); }; diff --git a/chromium/ui/accessibility/platform/atk_util_auralinux_gtk2.cc b/chromium/ui/accessibility/platform/atk_util_auralinux_gtk2.cc new file mode 100644 index 00000000000..9c50ead8560 --- /dev/null +++ b/chromium/ui/accessibility/platform/atk_util_auralinux_gtk2.cc @@ -0,0 +1,80 @@ +// Copyright 2017 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 <glib-2.0/gmodule.h> + +#include "base/bind.h" +#include "base/environment.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/task_scheduler/post_task.h" +#include "ui/accessibility/platform/atk_util_auralinux.h" + +typedef void (*GnomeAccessibilityModuleInitFunc)(); + +const char kAtkBridgeModule[] = "atk-bridge"; +const char kAtkBridgePath[] = "gtk-2.0/modules/libatk-bridge.so"; +const char kAtkBridgeSymbolName[] = "gnome_accessibility_module_init"; +const char kGtkModules[] = "GTK_MODULES"; + +// Returns a function pointer to be invoked on the main thread to init +// the gnome accessibility module if it's enabled (nullptr otherwise). +GnomeAccessibilityModuleInitFunc GetAccessibilityModuleInitFunc() { + base::AssertBlockingAllowed(); + + // 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 nullptr; + } + + GnomeAccessibilityModuleInitFunc init_func = nullptr; + + if (!g_module_symbol(bridge, kAtkBridgeSymbolName, (gpointer*)&init_func)) { + VLOG(1) << "Unable to get symbol pointer from " << atk_bridge_path.value(); + return nullptr; + } + + DCHECK(init_func); + return init_func; +} + +void FinishAccessibilityInitOnMainThread( + GnomeAccessibilityModuleInitFunc init_func) { + if (!init_func) { + VLOG(1) << "Will not enable ATK accessibility support."; + return; + } + + init_func(); +} + +bool AtkUtilAuraLinux::PlatformShouldEnableAccessibility() { + std::unique_ptr<base::Environment> env(base::Environment::Create()); + std::string gtk_modules; + if (!env->GetVar(kGtkModules, >k_modules)) + return false; + + for (const std::string& module : + base::SplitString(gtk_modules, ":", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY)) { + if (module == kAtkBridgeModule) + return true; + } + return false; +} + +void AtkUtilAuraLinux::PlatformInitializeAsync() { + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::Bind(&GetAccessibilityModuleInitFunc), + base::Bind(&FinishAccessibilityInitOnMainThread)); +} diff --git a/chromium/ui/accessibility/platform/atk_util_auralinux_gtk3.cc b/chromium/ui/accessibility/platform/atk_util_auralinux_gtk3.cc new file mode 100644 index 00000000000..196cf6a558f --- /dev/null +++ b/chromium/ui/accessibility/platform/atk_util_auralinux_gtk3.cc @@ -0,0 +1,24 @@ +// Copyright 2017 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 <atk-bridge.h> + +#include "base/environment.h" +#include "ui/accessibility/platform/atk_util_auralinux.h" + +namespace ui { + +bool AtkUtilAuraLinux::PlatformShouldEnableAccessibility() { + return false; +} + +void AtkUtilAuraLinux::PlatformInitializeAsync() { + // AT bridge enabling was disabled before loading GTK to avoid + // getting GTK implementation ATK root. + std::unique_ptr<base::Environment> env(base::Environment::Create()); + env->UnSetVar("NO_AT_BRIDGE"); + atk_bridge_adaptor_init(nullptr, nullptr); +} + +} // namespace ui diff --git a/chromium/ui/accessibility/platform/aura_window_properties.cc b/chromium/ui/accessibility/platform/aura_window_properties.cc index 146ad75b77e..9b3fe21cc48 100644 --- a/chromium/ui/accessibility/platform/aura_window_properties.cc +++ b/chromium/ui/accessibility/platform/aura_window_properties.cc @@ -6,10 +6,14 @@ #include "ui/base/class_property.h" +DECLARE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AX_EXPORT, AXRole) + namespace ui { DEFINE_UI_CLASS_PROPERTY_KEY(AXTreeIDRegistry::AXTreeID, kChildAXTreeID, AXTreeIDRegistry::kNoAXTreeID); +DEFINE_UI_CLASS_PROPERTY_KEY(AXRole, kAXRoleOverride, ui::AX_ROLE_NONE); + } // namespace ui diff --git a/chromium/ui/accessibility/platform/aura_window_properties.h b/chromium/ui/accessibility/platform/aura_window_properties.h index 8c8ea138c3d..5f25a8e5c18 100644 --- a/chromium/ui/accessibility/platform/aura_window_properties.h +++ b/chromium/ui/accessibility/platform/aura_window_properties.h @@ -5,6 +5,7 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_AURA_WINDOW_PROPERTIES_H_ #define UI_ACCESSIBILITY_PLATFORM_AURA_WINDOW_PROPERTIES_H_ +#include "ui/accessibility/ax_enums.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_tree_id_registry.h" #include "ui/aura/window.h" @@ -14,6 +15,8 @@ namespace ui { AX_EXPORT extern const aura::WindowProperty<AXTreeIDRegistry::AXTreeID>* const kChildAXTreeID; +AX_EXPORT extern const aura::WindowProperty<AXRole>* const kAXRoleOverride; + } // namespace ui #endif // UI_ACCESSIBILITY_PLATFORM_AURA_WINDOW_PROPERTIES_H_ diff --git a/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc b/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc new file mode 100644 index 00000000000..3a66c1d7141 --- /dev/null +++ b/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc @@ -0,0 +1,245 @@ +// Copyright (c) 2017 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 "ui/accessibility/platform/ax_platform_atk_hyperlink.h" + +#include "ui/accessibility/ax_text_utils.h" +#include "ui/accessibility/platform/ax_platform_node_auralinux.h" +#include "ui/accessibility/platform/ax_platform_node_delegate.h" + +namespace ui { + +static gpointer ax_platform_atk_hyperlink_parent_class = nullptr; + +static AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinux( + AXPlatformAtkHyperlink* atk_hyperlink) { + if (!atk_hyperlink) + return nullptr; + + return atk_hyperlink->m_object; +} + +static void ax_platform_atk_hyperlink_finalize(GObject* atk_hyperlink) { + G_OBJECT_CLASS(ax_platform_atk_hyperlink_parent_class) + ->finalize(atk_hyperlink); +} + +static gchar* ax_platform_atk_hyperlink_get_uri(AtkHyperlink* atk_hyperlink, + gint index) { + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink)); + if (!obj) + return nullptr; + + if (index != 0) + return nullptr; + + return g_strdup(obj->GetStringAttribute(ui::AX_ATTR_URL).c_str()); +} + +static AtkObject* ax_platform_atk_hyperlink_get_object( + AtkHyperlink* atk_hyperlink, + gint index) { + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink)); + if (!obj) + return nullptr; + + if (index != 0) + return nullptr; + + return ATK_OBJECT(obj->GetNativeViewAccessible()); +} + +static gint ax_platform_atk_hyperlink_get_n_anchors( + AtkHyperlink* atk_hyperlink) { + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink)); + + return obj ? 1 : 0; +} + +static gboolean ax_platform_atk_hyperlink_is_valid( + AtkHyperlink* atk_hyperlink) { + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink)); + + return obj ? TRUE : FALSE; +} + +static gboolean ax_platform_atk_hyperlink_is_selected_link( + AtkHyperlink* atk_hyperlink) { + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink)); + + if (!obj) + return false; + + return obj->GetDelegate()->GetFocus() == obj->GetNativeViewAccessible(); +} + +static void ax_platform_atk_hyperlink_class_init(AtkHyperlinkClass* klass) { + GObjectClass* gobject_class = G_OBJECT_CLASS(klass); + ax_platform_atk_hyperlink_parent_class = g_type_class_peek_parent(klass); + + gobject_class->finalize = ax_platform_atk_hyperlink_finalize; + klass->get_uri = ax_platform_atk_hyperlink_get_uri; + klass->get_object = ax_platform_atk_hyperlink_get_object; + klass->is_valid = ax_platform_atk_hyperlink_is_valid; + klass->get_n_anchors = ax_platform_atk_hyperlink_get_n_anchors; + klass->is_selected_link = ax_platform_atk_hyperlink_is_selected_link; + // TODO(jose.dapena) implement get_start_index and get_end_index methods + // that should provide the range of the link in the embedding text. +} + +// +// AtkAction interface. +// + +static AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinuxFromHyperlinkAction( + AtkAction* atk_action) { + if (!IS_AX_PLATFORM_ATK_HYPERLINK(atk_action)) + return nullptr; + + return ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_action)); +} + +static gboolean ax_platform_atk_hyperlink_do_action(AtkAction* action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(action), FALSE); + g_return_val_if_fail(!index, FALSE); + + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action); + if (!obj) + return FALSE; + + obj->DoDefaultAction(); + + return TRUE; +} + +static gint ax_platform_atk_hyperlink_get_n_actions(AtkAction* action) { + g_return_val_if_fail(ATK_IS_ACTION(action), FALSE); + + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action); + if (!obj) + return 0; + + return 1; +} + +static const gchar* ax_platform_atk_hyperlink_get_description(AtkAction* action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(action), FALSE); + g_return_val_if_fail(!index, FALSE); + + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action); + if (!obj) + return nullptr; + + // Not implemented + return nullptr; +} + +static const gchar* ax_platform_atk_hyperlink_get_keybinding(AtkAction* action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(action), FALSE); + g_return_val_if_fail(!index, FALSE); + + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action); + if (!obj) + return nullptr; + + return obj->GetStringAttribute(ui::AX_ATTR_ACCESS_KEY).c_str(); +} + +static const gchar* ax_platform_atk_hyperlink_get_name(AtkAction* atk_action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE); + g_return_val_if_fail(!index, FALSE); + + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinuxFromHyperlinkAction(atk_action); + if (!obj) + return nullptr; + + int action; + if (!obj->GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action)) + return nullptr; + base::string16 action_verb = ui::ActionVerbToUnlocalizedString( + static_cast<ui::AXDefaultActionVerb>(action)); + ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb)); +} + +static const gchar* ax_platform_atk_hyperlink_get_localized_name( + AtkAction* atk_action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE); + g_return_val_if_fail(!index, FALSE); + + AXPlatformNodeAuraLinux* obj = + ToAXPlatformNodeAuraLinuxFromHyperlinkAction(atk_action); + if (!obj) + return nullptr; + + int action; + if (!obj->GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action)) + return nullptr; + base::string16 action_verb = ui::ActionVerbToLocalizedString( + static_cast<ui::AXDefaultActionVerb>(action)); + ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb)); +} + +static void atk_action_interface_init(AtkActionIface* iface) { + iface->do_action = ax_platform_atk_hyperlink_do_action; + iface->get_n_actions = ax_platform_atk_hyperlink_get_n_actions; + iface->get_description = ax_platform_atk_hyperlink_get_description; + iface->get_keybinding = ax_platform_atk_hyperlink_get_keybinding; + iface->get_name = ax_platform_atk_hyperlink_get_name; + iface->get_localized_name = ax_platform_atk_hyperlink_get_localized_name; +} + +void ax_platform_atk_hyperlink_set_object(AXPlatformAtkHyperlink* atk_hyperlink, + AXPlatformNodeAuraLinux* obj) { + g_return_if_fail(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink)); + atk_hyperlink->m_object = obj; +} + +GType ax_platform_atk_hyperlink_get_type() { + static volatile gsize type_volatile = 0; + + AXPlatformNodeAuraLinux::EnsureGTypeInit(); + + if (g_once_init_enter(&type_volatile)) { + static const GTypeInfo tinfo = { + sizeof(AXPlatformAtkHyperlinkClass), + (GBaseInitFunc) nullptr, + (GBaseFinalizeFunc) nullptr, + (GClassInitFunc)ax_platform_atk_hyperlink_class_init, + (GClassFinalizeFunc) nullptr, + nullptr, /* class data */ + sizeof(AXPlatformAtkHyperlink), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) nullptr, + nullptr /* value table */ + }; + + static const GInterfaceInfo actionInfo = { + (GInterfaceInitFunc)(GInterfaceInitFunc)atk_action_interface_init, + (GInterfaceFinalizeFunc)0, 0}; + + GType type = g_type_register_static( + ATK_TYPE_HYPERLINK, "AXPlatformAtkHyperlink", &tinfo, GTypeFlags(0)); + g_type_add_interface_static(type, ATK_TYPE_ACTION, &actionInfo); + g_once_init_leave(&type_volatile, type); + } + + return type_volatile; +} + +} // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.h b/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.h new file mode 100644 index 00000000000..9704f8b5553 --- /dev/null +++ b/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.h @@ -0,0 +1,51 @@ +// Copyright (c) 2017 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 UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_ATK_HYPERLINK_H_ +#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_ATK_HYPERLINK_H_ + +#include <atk/atk.h> + +namespace ui { + +class AXPlatformNodeAuraLinux; + +G_BEGIN_DECLS + +#define AX_PLATFORM_ATK_HYPERLINK_TYPE (ax_platform_atk_hyperlink_get_type()) +#define AX_PLATFORM_ATK_HYPERLINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), AX_PLATFORM_ATK_HYPERLINK_TYPE, \ + AXPlatformAtkHyperlink)) +#define AX_PLATFORM_ATK_HYPERLINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), AX_PLATFORM_ATK_HYPERLINK_TYPE, \ + AXPlatformAtkHyperlinkClass)) +#define IS_AX_PLATFORM_ATK_HYPERLINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), AX_PLATFORM_ATK_HYPERLINK_TYPE)) +#define IS_AX_PLATFORM_ATK_HYPERLINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), AX_PLATFORM_ATK_HYPERLINK_TYPE)) +#define AX_PLATFORM_ATK_HYPERLINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), AX_PLATFORM_ATK_HYPERLINK_TYPE, \ + AXPlatformAtkHyperlinkClass)) + +typedef struct _AXPlatformAtkHyperlink AXPlatformAtkHyperlink; +typedef struct _AXPlatformAtkHyperlinkClass AXPlatformAtkHyperlinkClass; + +struct _AXPlatformAtkHyperlink { + AtkHyperlink parent; + AXPlatformNodeAuraLinux* m_object; +}; + +struct _AXPlatformAtkHyperlinkClass { + AtkHyperlinkClass parent_class; +}; + +GType ax_platform_atk_hyperlink_get_type(void) G_GNUC_CONST; +void ax_platform_atk_hyperlink_set_object(AXPlatformAtkHyperlink* hyperlink, + AXPlatformNodeAuraLinux* obj); + +G_END_DECLS + +} // namespace ui + +#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_ATK_HYPERLINK_H_ diff --git a/chromium/ui/accessibility/platform/ax_platform_node.cc b/chromium/ui/accessibility/platform/ax_platform_node.cc index d7f68012f77..18bc0be25bf 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node.cc @@ -9,6 +9,7 @@ #include "build/build_config.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" +#include "ui/base/ui_features.h" namespace ui { @@ -16,6 +17,32 @@ namespace ui { base::LazyInstance<base::ObserverList<AXModeObserver>>::Leaky AXPlatformNode::ax_mode_observers_ = LAZY_INSTANCE_INITIALIZER; +// static +base::LazyInstance<AXPlatformNode::NativeWindowHandlerCallback>::Leaky + AXPlatformNode::native_window_handler_ = LAZY_INSTANCE_INITIALIZER; + +// static +AXPlatformNode* AXPlatformNode::FromNativeWindow( + gfx::NativeWindow native_window) { + if (native_window_handler_.Get()) + return native_window_handler_.Get().Run(native_window); + return nullptr; +} + +#if !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY() +// static +AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( + gfx::NativeViewAccessible accessible) { + return nullptr; +} +#endif // !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY() + +// static +void AXPlatformNode::RegisterNativeWindowHandler( + AXPlatformNode::NativeWindowHandlerCallback handler) { + native_window_handler_.Get() = handler; +} + AXPlatformNode::AXPlatformNode() {} AXPlatformNode::~AXPlatformNode() { diff --git a/chromium/ui/accessibility/platform/ax_platform_node.h b/chromium/ui/accessibility/platform/ax_platform_node.h index 8aa38ad0a82..56a0664a147 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node.h +++ b/chromium/ui/accessibility/platform/ax_platform_node.h @@ -5,6 +5,7 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_H_ #define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_H_ +#include "base/callback.h" #include "base/lazy_instance.h" #include "base/observer_list.h" #include "build/build_config.h" @@ -24,6 +25,9 @@ class AXPlatformNodeDelegate; // own the AXPlatformNode instance (or otherwise manage its lifecycle). class AX_EXPORT AXPlatformNode { public: + using NativeWindowHandlerCallback = + base::RepeatingCallback<AXPlatformNode*(gfx::NativeWindow)>; + // Create an appropriate platform-specific instance. The delegate owns the // AXPlatformNode instance (or manages its lifecycle in some other way). static AXPlatformNode* Create(AXPlatformNodeDelegate* delegate); @@ -33,6 +37,13 @@ class AX_EXPORT AXPlatformNode { static AXPlatformNode* FromNativeViewAccessible( gfx::NativeViewAccessible accessible); + // Return the AXPlatformNode at the root of the tree for a native window. + static AXPlatformNode* FromNativeWindow(gfx::NativeWindow native_window); + + // Provide a function that returns the AXPlatformNode at the root of the + // tree for a native window. + static void RegisterNativeWindowHandler(NativeWindowHandlerCallback handler); + // Register and unregister to receive notifications about AXMode changes // for this node. static void AddAXModeObserver(AXModeObserver* observer); @@ -66,6 +77,9 @@ class AX_EXPORT AXPlatformNode { // Global ObserverList for AXMode changes. static base::LazyInstance<base::ObserverList<AXModeObserver>>::Leaky ax_mode_observers_; + + static base::LazyInstance<NativeWindowHandlerCallback>::Leaky + native_window_handler_; }; } // 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 1350607a562..3829ccb31cd 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc @@ -1,4 +1,4 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// Copyright 2017 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. @@ -8,8 +8,13 @@ #include "base/command_line.h" #include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/ax_text_utils.h" +#include "ui/accessibility/ax_tree_data.h" #include "ui/accessibility/platform/atk_util_auralinux.h" +#include "ui/accessibility/platform/ax_platform_atk_hyperlink.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -75,6 +80,11 @@ static const gchar* ax_platform_node_auralinux_get_name(AtkObject* atk_object) { if (!obj) return nullptr; + if (obj->GetStringAttribute(ui::AX_ATTR_NAME).empty() && + !(obj->GetIntAttribute(ui::AX_ATTR_NAME_FROM) == + ui::AX_NAME_FROM_ATTRIBUTE_EXPLICITLY_EMPTY)) + return nullptr; + return obj->GetStringAttribute(ui::AX_ATTR_NAME).c_str(); } @@ -172,16 +182,17 @@ static AtkRole ax_platform_node_auralinux_get_role(AtkObject* atk_object) { static AtkStateSet* ax_platform_node_auralinux_ref_state_set( AtkObject* atk_object) { - ui::AXPlatformNodeAuraLinux* obj = - AtkObjectToAXPlatformNodeAuraLinux(atk_object); - if (!obj) - return NULL; - AtkStateSet* atk_state_set = ATK_OBJECT_CLASS(ax_platform_node_auralinux_parent_class)-> ref_state_set(atk_object); - obj->GetAtkState(atk_state_set); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) { + atk_state_set_add_state(atk_state_set, ATK_STATE_DEFUNCT); + } else { + obj->GetAtkState(atk_state_set); + } return atk_state_set; } @@ -266,10 +277,43 @@ static void ax_platform_node_auralinux_get_size(AtkComponent* atk_component, obj->GetSize(width, height); } +static AtkObject* ax_platform_node_auralinux_ref_accessible_at_point( + AtkComponent* atk_component, + gint x, + gint y, + AtkCoordType coord_type) { + g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), nullptr); + AtkObject* atk_object = ATK_OBJECT(atk_component); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + AtkObject* result = obj->HitTestSync(x, y, coord_type); + if (result) + g_object_ref(result); + return result; +} + +static gboolean ax_platform_node_auralinux_grab_focus( + AtkComponent* atk_component) { + g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE); + AtkObject* atk_object = ATK_OBJECT(atk_component); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return FALSE; + + return obj->GrabFocus(); +} + void ax_component_interface_base_init(AtkComponentIface* iface) { iface->get_extents = ax_platform_node_auralinux_get_extents; iface->get_position = ax_platform_node_auralinux_get_position; iface->get_size = ax_platform_node_auralinux_get_size; + iface->ref_accessible_at_point = + ax_platform_node_auralinux_ref_accessible_at_point; + iface->grab_focus = ax_platform_node_auralinux_grab_focus; } static const GInterfaceInfo ComponentInfo = { @@ -277,7 +321,282 @@ static const GInterfaceInfo ComponentInfo = { }; // -// The rest of the AXPlatformNodeAuraLinux code, not specific to one +// AtkAction interface +// + +static gboolean ax_platform_node_auralinux_do_action(AtkAction* atk_action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE); + g_return_val_if_fail(!index, FALSE); + + AtkObject* atk_object = ATK_OBJECT(atk_action); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return FALSE; + + return obj->DoDefaultAction(); +} + +static gint ax_platform_node_auralinux_get_n_actions(AtkAction* atk_action) { + g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0); + + AtkObject* atk_object = ATK_OBJECT(atk_action); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return 0; + + return 1; +} + +static const gchar* ax_platform_node_auralinux_get_action_description( + AtkAction*, + gint) { + // Not implemented. Right now Orca does not provide this and + // Chromium is not providing a string for the action description. + return nullptr; +} + +static const gchar* ax_platform_node_auralinux_get_action_name( + AtkAction* atk_action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(atk_action), nullptr); + g_return_val_if_fail(!index, nullptr); + + AtkObject* atk_object = ATK_OBJECT(atk_action); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + return obj->GetDefaultActionName(); +} + +static const gchar* ax_platform_node_auralinux_get_action_keybinding( + AtkAction* atk_action, + gint index) { + g_return_val_if_fail(ATK_IS_ACTION(atk_action), nullptr); + g_return_val_if_fail(!index, nullptr); + + AtkObject* atk_object = ATK_OBJECT(atk_action); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + return obj->GetStringAttribute(ui::AX_ATTR_ACCESS_KEY).c_str(); +} + +void ax_action_interface_base_init(AtkActionIface* iface) { + iface->do_action = ax_platform_node_auralinux_do_action; + iface->get_n_actions = ax_platform_node_auralinux_get_n_actions; + iface->get_description = ax_platform_node_auralinux_get_action_description; + iface->get_name = ax_platform_node_auralinux_get_action_name; + iface->get_keybinding = ax_platform_node_auralinux_get_action_keybinding; +} + +static const GInterfaceInfo ActionInfo = { + reinterpret_cast<GInterfaceInitFunc>(ax_action_interface_base_init), + nullptr, nullptr}; + +// AtkDocument interface. + +static const gchar* ax_platform_node_auralinux_get_document_attribute_value( + AtkDocument* atk_doc, + const gchar* attribute) { + g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), nullptr); + + AtkObject* atk_object = ATK_OBJECT(atk_doc); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + return obj->GetDocumentAttributeValue(attribute); +} + +static AtkAttributeSet* ax_platform_node_auralinux_get_document_attributes( + AtkDocument* atk_doc) { + g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), 0); + + AtkObject* atk_object = ATK_OBJECT(atk_doc); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + return obj->GetDocumentAttributes(); +} + +void ax_document_interface_base_init(AtkDocumentIface* iface) { + iface->get_document_attribute_value = + ax_platform_node_auralinux_get_document_attribute_value; + iface->get_document_attributes = + ax_platform_node_auralinux_get_document_attributes; +} + +static const GInterfaceInfo DocumentInfo = { + reinterpret_cast<GInterfaceInitFunc>(ax_document_interface_base_init), + nullptr, nullptr}; + +// +// AtkImage interface. +// + +static void ax_platform_node_auralinux_get_image_position( + AtkImage* atk_img, + gint* x, + gint* y, + AtkCoordType coord_type) { + g_return_if_fail(ATK_IMAGE(atk_img)); + + AtkObject* atk_object = ATK_OBJECT(atk_img); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return; + + obj->GetPosition(x, y, coord_type); +} + +static const gchar* ax_platform_node_auralinux_get_image_description( + AtkImage* atk_img) { + g_return_val_if_fail(ATK_IMAGE(atk_img), nullptr); + + AtkObject* atk_object = ATK_OBJECT(atk_img); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return nullptr; + + return obj->GetStringAttribute(ui::AX_ATTR_DESCRIPTION).c_str(); +} + +static void ax_platform_node_auralinux_get_image_size(AtkImage* atk_img, + gint* width, + gint* height) { + g_return_if_fail(ATK_IMAGE(atk_img)); + + AtkObject* atk_object = ATK_OBJECT(atk_img); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return; + + obj->GetSize(width, height); +} + +void ax_image_interface_base_init(AtkImageIface* iface) { + iface->get_image_position = ax_platform_node_auralinux_get_image_position; + iface->get_image_description = + ax_platform_node_auralinux_get_image_description; + iface->get_image_size = ax_platform_node_auralinux_get_image_size; +} + +static const GInterfaceInfo ImageInfo = { + reinterpret_cast<GInterfaceInitFunc>(ax_image_interface_base_init), nullptr, + nullptr}; + +// +// AtkValue interface +// + +static void ax_platform_node_auralinux_get_current_value(AtkValue* atk_value, + GValue* value) { + g_return_if_fail(ATK_VALUE(atk_value)); + + AtkObject* atk_object = ATK_OBJECT(atk_value); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return; + + obj->GetFloatAttributeInGValue(ui::AX_ATTR_VALUE_FOR_RANGE, value); +} + +static void ax_platform_node_auralinux_get_minimum_value(AtkValue* atk_value, + GValue* value) { + g_return_if_fail(ATK_VALUE(atk_value)); + + AtkObject* atk_object = ATK_OBJECT(atk_value); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return; + + obj->GetFloatAttributeInGValue(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, value); +} + +static void ax_platform_node_auralinux_get_maximum_value(AtkValue* atk_value, + GValue* value) { + g_return_if_fail(ATK_VALUE(atk_value)); + + AtkObject* atk_object = ATK_OBJECT(atk_value); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return; + + obj->GetFloatAttributeInGValue(ui::AX_ATTR_MAX_VALUE_FOR_RANGE, value); +} + +static void ax_platform_node_auralinux_get_minimum_increment( + AtkValue* atk_value, + GValue* value) { + g_return_if_fail(ATK_VALUE(atk_value)); + + AtkObject* atk_object = ATK_OBJECT(atk_value); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return; + + obj->GetFloatAttributeInGValue(ui::AX_ATTR_STEP_VALUE_FOR_RANGE, value); +} + +static void ax_value_interface_base_init(AtkValueIface* iface) { + iface->get_current_value = ax_platform_node_auralinux_get_current_value; + iface->get_maximum_value = ax_platform_node_auralinux_get_maximum_value; + iface->get_minimum_value = ax_platform_node_auralinux_get_minimum_value; + iface->get_minimum_increment = + ax_platform_node_auralinux_get_minimum_increment; +} + +static const GInterfaceInfo ValueInfo = { + reinterpret_cast<GInterfaceInitFunc>(ax_value_interface_base_init), nullptr, + nullptr}; + +// +// AtkHyperlinkImpl interface. +// + +static AtkHyperlink* ax_platform_node_auralinux_get_hyperlink( + AtkHyperlinkImpl* atk_hyperlink_impl) { + g_return_val_if_fail(ATK_HYPERLINK_IMPL(atk_hyperlink_impl), 0); + + AtkObject* atk_object = ATK_OBJECT(atk_hyperlink_impl); + ui::AXPlatformNodeAuraLinux* obj = + AtkObjectToAXPlatformNodeAuraLinux(atk_object); + if (!obj) + return 0; + + AtkHyperlink* atk_hyperlink = obj->GetAtkHyperlink(); + g_object_ref(atk_hyperlink); + + return atk_hyperlink; +} + +void ax_hyperlink_impl_interface_base_init(AtkHyperlinkImplIface* iface) { + iface->get_hyperlink = ax_platform_node_auralinux_get_hyperlink; +} + +static const GInterfaceInfo HyperlinkImplInfo = { + reinterpret_cast<GInterfaceInitFunc>(ax_hyperlink_impl_interface_base_init), + nullptr, nullptr}; + +// +// The rest of the AXPlatformNodeAtk code, not specific to one // of the Atk* interfaces. // @@ -315,55 +634,158 @@ static void ax_platform_node_auralinux_class_init(AtkObjectClass* klass) { } GType ax_platform_node_auralinux_get_type() { - static volatile gsize type_volatile = 0; + ui::AXPlatformNodeAuraLinux::EnsureGTypeInit(); + static volatile gsize type_volatile = 0; if (g_once_init_enter(&type_volatile)) { static const GTypeInfo tinfo = { - sizeof(AXPlatformNodeAuraLinuxClass), - (GBaseInitFunc) 0, - (GBaseFinalizeFunc) 0, - (GClassInitFunc) ax_platform_node_auralinux_class_init, - (GClassFinalizeFunc) 0, - 0, /* class data */ - sizeof(AXPlatformNodeAuraLinuxObject), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) 0, - 0 /* value table */ + sizeof(AXPlatformNodeAuraLinuxClass), + (GBaseInitFunc) nullptr, + (GBaseFinalizeFunc) nullptr, + (GClassInitFunc)ax_platform_node_auralinux_class_init, + (GClassFinalizeFunc) nullptr, + nullptr, /* class data */ + sizeof(AXPlatformNodeAuraLinuxObject), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) nullptr, + nullptr /* value table */ }; GType type = g_type_register_static( ATK_TYPE_OBJECT, "AXPlatformNodeAuraLinux", &tinfo, GTypeFlags(0)); - g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo); g_once_init_leave(&type_volatile, type); } return type_volatile; } -AXPlatformNodeAuraLinuxObject* ax_platform_node_auralinux_new( - ui::AXPlatformNodeAuraLinux* obj) { - #if !GLIB_CHECK_VERSION(2, 36, 0) +void ax_platform_node_auralinux_detach( + AXPlatformNodeAuraLinuxObject* atk_object) { + if (atk_object->m_object) { + atk_object_notify_state_change(ATK_OBJECT(atk_object), ATK_STATE_DEFUNCT, + TRUE); + } + atk_object->m_object = nullptr; +} + +G_END_DECLS + +namespace ui { + +void AXPlatformNodeAuraLinux::EnsureGTypeInit() { +#if !GLIB_CHECK_VERSION(2, 36, 0) static bool first_time = true; - if (first_time) { + if (UNLIKELY(first_time)) { g_type_init(); first_time = false; } - #endif +#endif +} - GType type = AX_PLATFORM_NODE_AURALINUX_TYPE; - AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0)); - atk_object_initialize(atk_object, obj); - return AX_PLATFORM_NODE_AURALINUX(atk_object); +const char* AXPlatformNodeAuraLinux::GetUniqueAccessibilityGTypeName( + int interface_mask) { + // 37 characters is enough for "AXPlatformNodeAuraLinux%x" with any integer + // value. + static char name[37]; + snprintf(name, sizeof(name), "AXPlatformNodeAuraLinux%x", interface_mask); + return name; } -void ax_platform_node_auralinux_detach( - AXPlatformNodeAuraLinuxObject* atk_object) { - atk_object->m_object = nullptr; +int AXPlatformNodeAuraLinux::GetGTypeInterfaceMask() { + int interface_mask = 0; + + // Component interface is always supported. + interface_mask |= 1 << ATK_COMPONENT_INTERFACE; + + // Action interface is basic one. It just relays on executing default action + // for each object. + interface_mask |= 1 << ATK_ACTION_INTERFACE; + + // Value Interface + int role = GetAtkRole(); + if (role == ATK_ROLE_SCROLL_BAR || role == ATK_ROLE_SLIDER || + role == ATK_ROLE_PROGRESS_BAR || role == ATK_ROLE_SEPARATOR || + role == ATK_ROLE_SPIN_BUTTON) { + interface_mask |= 1 << ATK_VALUE_INTERFACE; + } + + // Document Interface + if (role == ATK_ROLE_DOCUMENT_WEB) + interface_mask |= 1 << ATK_DOCUMENT_INTERFACE; + + // Image Interface + if (role == ATK_ROLE_IMAGE || role == ATK_ROLE_IMAGE_MAP) + interface_mask |= 1 << ATK_IMAGE_INTERFACE; + + // HyperlinkImpl interface + if (role == ATK_ROLE_LINK) + interface_mask |= 1 << ATK_HYPERLINK_INTERFACE; + + return interface_mask; } -G_END_DECLS +GType AXPlatformNodeAuraLinux::GetAccessibilityGType() { + static const GTypeInfo type_info = { + sizeof(AXPlatformNodeAuraLinuxClass), + (GBaseInitFunc) nullptr, + (GBaseFinalizeFunc) nullptr, + (GClassInitFunc) nullptr, + (GClassFinalizeFunc) nullptr, + nullptr, /* class data */ + sizeof(AXPlatformNodeAuraLinuxObject), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) nullptr, + nullptr /* value table */ + }; + + const char* atk_type_name = GetUniqueAccessibilityGTypeName(interface_mask_); + GType type = g_type_from_name(atk_type_name); + if (type) + return type; + + type = g_type_register_static(AX_PLATFORM_NODE_AURALINUX_TYPE, atk_type_name, + &type_info, GTypeFlags(0)); + if (interface_mask_ & (1 << ATK_COMPONENT_INTERFACE)) + g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo); + if (interface_mask_ & (1 << ATK_ACTION_INTERFACE)) + g_type_add_interface_static(type, ATK_TYPE_ACTION, &ActionInfo); + if (interface_mask_ & (1 << ATK_DOCUMENT_INTERFACE)) + g_type_add_interface_static(type, ATK_TYPE_DOCUMENT, &DocumentInfo); + if (interface_mask_ & (1 << ATK_IMAGE_INTERFACE)) + g_type_add_interface_static(type, ATK_TYPE_IMAGE, &ImageInfo); + if (interface_mask_ & (1 << ATK_VALUE_INTERFACE)) + g_type_add_interface_static(type, ATK_TYPE_VALUE, &ValueInfo); + if (interface_mask_ & (1 << ATK_HYPERLINK_INTERFACE)) + g_type_add_interface_static(type, ATK_TYPE_HYPERLINK_IMPL, + &HyperlinkImplInfo); + + return type; +} -namespace ui { +AtkObject* AXPlatformNodeAuraLinux::CreateAtkObject() { + EnsureGTypeInit(); + interface_mask_ = GetGTypeInterfaceMask(); + GType type = GetAccessibilityGType(); + AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, nullptr)); + + atk_object_initialize(atk_object, this); + + return ATK_OBJECT(atk_object); +} + +void AXPlatformNodeAuraLinux::DestroyAtkObjects() { + if (atk_hyperlink_) { + ax_platform_atk_hyperlink_set_object( + AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink_), nullptr); + g_object_unref(atk_hyperlink_); + atk_hyperlink_ = nullptr; + } + if (atk_object_) { + ax_platform_node_auralinux_detach(AX_PLATFORM_NODE_AURALINUX(atk_object_)); + g_object_unref(atk_object_); + atk_object_ = nullptr; + } +} // static AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { @@ -399,6 +821,8 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() { switch (GetData().role) { case ui::AX_ROLE_ALERT: return ATK_ROLE_ALERT; + case ui::AX_ROLE_ALERT_DIALOG: + return ATK_ROLE_ALERT; case ui::AX_ROLE_APPLICATION: return ATK_ROLE_APPLICATION; case ui::AX_ROLE_AUDIO: @@ -413,12 +837,30 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() { #endif case ui::AX_ROLE_BUTTON: return ATK_ROLE_PUSH_BUTTON; + case ui::AX_ROLE_CANVAS: + return ATK_ROLE_CANVAS; + case ui::AX_ROLE_CAPTION: + return ATK_ROLE_CAPTION; case ui::AX_ROLE_CHECK_BOX: return ATK_ROLE_CHECK_BOX; - case ui::AX_ROLE_COMBO_BOX: + case ui::AX_ROLE_COLOR_WELL: + return ATK_ROLE_COLOR_CHOOSER; + case ui::AX_ROLE_COLUMN_HEADER: + return ATK_ROLE_COLUMN_HEADER; + case ui::AX_ROLE_COMBO_BOX_GROUPING: + return ATK_ROLE_COMBO_BOX; + case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON: return ATK_ROLE_COMBO_BOX; + case ui::AX_ROLE_DATE: + return ATK_ROLE_DATE_EDITOR; + case ui::AX_ROLE_DATE_TIME: + return ATK_ROLE_DATE_EDITOR; case ui::AX_ROLE_DIALOG: return ATK_ROLE_DIALOG; + case ui::AX_ROLE_DOCUMENT: + return ATK_ROLE_DOCUMENT_WEB; + case ui::AX_ROLE_FORM: + return ATK_ROLE_FORM; case ui::AX_ROLE_GENERIC_CONTAINER: return ATK_ROLE_PANEL; case ui::AX_ROLE_GROUP: @@ -427,24 +869,82 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() { return ATK_ROLE_REDUNDANT_OBJECT; case ui::AX_ROLE_IMAGE: return ATK_ROLE_IMAGE; + case ui::AX_ROLE_IMAGE_MAP: + return ATK_ROLE_IMAGE_MAP; + case ui::AX_ROLE_LABEL_TEXT: + return ATK_ROLE_LABEL; + case ui::AX_ROLE_LINK: + return ATK_ROLE_LINK; + case ui::AX_ROLE_LIST: + return ATK_ROLE_LIST; + case ui::AX_ROLE_LIST_BOX: + return ATK_ROLE_LIST_BOX; + case ui::AX_ROLE_LIST_ITEM: + return ATK_ROLE_LIST_ITEM; + case ui::AX_ROLE_MATH: +#if defined(ATK_CHECK_VERSION) +#if ATK_CHECK_VERSION(2, 12, 0) + return ATK_ROLE_MATH; +#else + return ATK_ROLE_TEXT; +#endif +#else + return ATK_ROLE_TEXT; +#endif + case ui::AX_ROLE_MENU: + return ATK_ROLE_MENU; + case ui::AX_ROLE_MENU_BAR: + return ATK_ROLE_MENU_BAR; case ui::AX_ROLE_MENU_ITEM: return ATK_ROLE_MENU_ITEM; + case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: + return ATK_ROLE_CHECK_MENU_ITEM; + case ui::AX_ROLE_MENU_ITEM_RADIO: + return ATK_ROLE_RADIO_MENU_ITEM; + case ui::AX_ROLE_METER: + return ATK_ROLE_PROGRESS_BAR; + case ui::AX_ROLE_PARAGRAPH: + return ATK_ROLE_PARAGRAPH; + case ui::AX_ROLE_RADIO_BUTTON: + return ATK_ROLE_RADIO_BUTTON; + case ui::AX_ROLE_ROW_HEADER: + return ATK_ROLE_ROW_HEADER; + case ui::AX_ROLE_ROOT_WEB_AREA: + return ATK_ROLE_DOCUMENT_WEB; case ui::AX_ROLE_SCROLL_BAR: return ATK_ROLE_SCROLL_BAR; case ui::AX_ROLE_SLIDER: return ATK_ROLE_SLIDER; + case ui::AX_ROLE_SPIN_BUTTON: + return ATK_ROLE_SPIN_BUTTON; case ui::AX_ROLE_SPLITTER: return ATK_ROLE_SEPARATOR; case ui::AX_ROLE_STATIC_TEXT: return ATK_ROLE_TEXT; + case ui::AX_ROLE_STATUS: + return ATK_ROLE_STATUSBAR; case ui::AX_ROLE_TAB: return ATK_ROLE_PAGE_TAB; + case ui::AX_ROLE_TABLE: + return ATK_ROLE_TABLE; case ui::AX_ROLE_TAB_LIST: return ATK_ROLE_PAGE_TAB_LIST; case ui::AX_ROLE_TEXT_FIELD: return ATK_ROLE_ENTRY; + case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX: + return ATK_ROLE_COMBO_BOX; + case ui::AX_ROLE_TOGGLE_BUTTON: + return ATK_ROLE_TOGGLE_BUTTON; case ui::AX_ROLE_TOOLBAR: return ATK_ROLE_TOOL_BAR; + case ui::AX_ROLE_TOOLTIP: + return ATK_ROLE_TOOL_TIP; + case ui::AX_ROLE_TREE: + return ATK_ROLE_TREE; + case ui::AX_ROLE_TREE_ITEM: + return ATK_ROLE_TREE_ITEM; + case ui::AX_ROLE_TREE_GRID: + return ATK_ROLE_TREE_TABLE; case ui::AX_ROLE_VIDEO: #if defined(ATK_CHECK_VERSION) #if ATK_CHECK_VERSION(2, 12, 0) @@ -455,6 +955,8 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() { #else return ATK_ROLE_SECTION; #endif + case ui::AX_ROLE_WEB_AREA: + return ATK_ROLE_DOCUMENT_WEB; case ui::AX_ROLE_WINDOW: return ATK_ROLE_WINDOW; default: @@ -505,10 +1007,11 @@ void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) { atk_state_set_add_state(atk_state_set, ATK_STATE_ENABLED); break; case ui::AX_RESTRICTION_READ_ONLY: - // The following would require ATK 2.16 or later, which many - // systems do not have. Since we aren't officially supporting ATK - // it's best to leave this out rather than break people's builds: - // atk_state_set_add_state(atk_state_set, ATK_STATE_READ_ONLY); +#if defined(ATK_CHECK_VERSION) +#if ATK_CHECK_VERSION(2, 16, 0) + atk_state_set_add_state(atk_state_set, ATK_STATE_READ_ONLY); +#endif +#endif break; } @@ -521,17 +1024,58 @@ void AXPlatformNodeAuraLinux::GetAtkRelations(AtkRelationSet* atk_relation_set) } AXPlatformNodeAuraLinux::AXPlatformNodeAuraLinux() - : atk_object_(nullptr) { -} + : interface_mask_(0), atk_object_(nullptr), atk_hyperlink_(nullptr) {} AXPlatformNodeAuraLinux::~AXPlatformNodeAuraLinux() { - g_object_unref(atk_object_); + DestroyAtkObjects(); +} + +void AXPlatformNodeAuraLinux::Destroy() { + DestroyAtkObjects(); + AXPlatformNodeBase::Destroy(); } void AXPlatformNodeAuraLinux::Init(AXPlatformNodeDelegate* delegate) { // Initialize ATK. AXPlatformNodeBase::Init(delegate); - atk_object_ = ATK_OBJECT(ax_platform_node_auralinux_new(this)); + DataChanged(); +} + +void AXPlatformNodeAuraLinux::DataChanged() { + if (atk_object_) { + // If the object's role changes and that causes its + // interface mask to change, we need to create a new + // AtkObject for it. + int interface_mask = GetGTypeInterfaceMask(); + if (interface_mask != interface_mask_) + DestroyAtkObjects(); + } + + if (!atk_object_) { + atk_object_ = CreateAtkObject(); + } +} + +void AXPlatformNodeAuraLinux::AddAccessibilityTreeProperties( + base::DictionaryValue* dict) { + AtkRole role = GetAtkRole(); + if (role != ATK_ROLE_UNKNOWN) + dict->SetString("role", std::string(atk_role_get_name(role))); + const gchar* name = atk_object_get_name(atk_object_); + if (name) + dict->SetString("name", std::string(name)); + const gchar* description = atk_object_get_description(atk_object_); + if (description) + dict->SetString("description", std::string(description)); + + AtkStateSet* state_set = atk_object_ref_state_set(atk_object_); + auto states = std::make_unique<base::ListValue>(); + for (int i = ATK_STATE_INVALID; i < ATK_STATE_LAST_DEFINED; i++) { + AtkStateType state_type = static_cast<AtkStateType>(i); + if (atk_state_set_contains_state(state_set, state_type)) + states->AppendString(atk_state_type_get_name(state_type)); + } + dict->Set("states", std::move(states)); } gfx::NativeViewAccessible AXPlatformNodeAuraLinux::GetNativeViewAccessible() { @@ -580,7 +1124,7 @@ void AXPlatformNodeAuraLinux::GetExtents(gint* x, gint* y, void AXPlatformNodeAuraLinux::GetPosition(gint* x, gint* y, AtkCoordType coord_type) { SetExtentsRelativeToAtkCoordinateType(x, y, - nullptr,nullptr, + nullptr, nullptr, coord_type); } @@ -592,4 +1136,107 @@ void AXPlatformNodeAuraLinux::GetSize(gint* width, gint* height) { *height = rect_size.height(); } +gfx::NativeViewAccessible +AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) { + if (coord_type == ATK_XY_WINDOW) { + if (AtkObject* atk_object = GetParent()) { + gfx::Point window_coords = FindAtkObjectParentCoords(atk_object); + x += window_coords.x(); + y += window_coords.y(); + } + } + + return delegate_->HitTestSync(x, y); +} + +bool AXPlatformNodeAuraLinux::GrabFocus() { + AXActionData action_data; + action_data.action = AX_ACTION_FOCUS; + return delegate_->AccessibilityPerformAction(action_data); +} + +bool AXPlatformNodeAuraLinux::DoDefaultAction() { + AXActionData action_data; + action_data.action = AX_ACTION_DO_DEFAULT; + return delegate_->AccessibilityPerformAction(action_data); +} + +const gchar* AXPlatformNodeAuraLinux::GetDefaultActionName() { + int action; + if (!GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action)) + return nullptr; + + base::string16 action_verb = ui::ActionVerbToUnlocalizedString( + static_cast<ui::AXDefaultActionVerb>(action)); + + ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb)); +} + +// AtkDocumentHelpers + +const gchar* AXPlatformNodeAuraLinux::GetDocumentAttributeValue( + const gchar* attribute) const { + if (!g_ascii_strcasecmp(attribute, "DocType")) + return delegate_->GetTreeData().doctype.c_str(); + else if (!g_ascii_strcasecmp(attribute, "MimeType")) + return delegate_->GetTreeData().mimetype.c_str(); + else if (!g_ascii_strcasecmp(attribute, "Title")) + return delegate_->GetTreeData().title.c_str(); + else if (!g_ascii_strcasecmp(attribute, "URI")) + return delegate_->GetTreeData().url.c_str(); + + return nullptr; +} + +AtkAttributeSet* AXPlatformNodeAuraLinux::GetDocumentAttributes() const { + AtkAttributeSet* attribute_set = nullptr; + const gchar* doc_attributes[] = {"DocType", "MimeType", "Title", "URI"}; + const gchar* value = nullptr; + + for (unsigned i = 0; i < G_N_ELEMENTS(doc_attributes); i++) { + value = GetDocumentAttributeValue(doc_attributes[i]); + if (value) { + AtkAttribute* attribute = + static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute))); + attribute->name = g_strdup(doc_attributes[i]); + attribute->value = g_strdup(value); + attribute_set = g_slist_prepend(attribute_set, attribute); + } + } + + return attribute_set; +} + +// +// AtkHyperlink helpers +// + +AtkHyperlink* AXPlatformNodeAuraLinux::GetAtkHyperlink() { + DCHECK(ATK_HYPERLINK_IMPL(atk_object_)); + g_return_val_if_fail(ATK_HYPERLINK_IMPL(atk_object_), 0); + + if (!atk_hyperlink_) { + atk_hyperlink_ = + ATK_HYPERLINK(g_object_new(AX_PLATFORM_ATK_HYPERLINK_TYPE, 0)); + ax_platform_atk_hyperlink_set_object( + AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink_), this); + } + + return atk_hyperlink_; +} + +// +// Misc helpers +// + +void AXPlatformNodeAuraLinux::GetFloatAttributeInGValue(AXFloatAttribute attr, + GValue* value) { + float float_val; + if (GetFloatAttribute(attr, &float_val)) { + memset(value, 0, sizeof(*value)); + g_value_init(value, G_TYPE_FLOAT); + g_value_set_float(value, float_val); + } +} + } // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h index 1504bfbf67b..4b28b903606 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h +++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h @@ -8,24 +8,42 @@ #include <atk/atk.h> #include "base/macros.h" +#include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/platform/ax_platform_node_base.h" +// Some ATK interfaces require returning a (const gchar*), use +// this macro to make it safe to return a pointer to a temporary +// string. +#define ATK_AURALINUX_RETURN_STRING(str_expr) \ + { \ + static std::string result; \ + result = (str_expr); \ + return result.c_str(); \ + } + namespace ui { // Implements accessibility on Aura Linux using ATK. class AXPlatformNodeAuraLinux : public AXPlatformNodeBase { public: AXPlatformNodeAuraLinux(); + ~AXPlatformNodeAuraLinux() override; // Set or get the root-level Application object that's the parent of all // top-level windows. AX_EXPORT static void SetApplication(AXPlatformNode* application); static AXPlatformNode* application() { return application_; } + static void EnsureGTypeInit(); + // Do asynchronous static initialization. AX_EXPORT static void StaticInitialize(); + AX_EXPORT void DataChanged(); + void Destroy() override; + AX_EXPORT void AddAccessibilityTreeProperties(base::DictionaryValue* dict); + AtkRole GetAtkRole(); void GetAtkState(AtkStateSet* state_set); void GetAtkRelations(AtkRelationSet* atk_relation_set); @@ -33,11 +51,27 @@ class AXPlatformNodeAuraLinux : public AXPlatformNodeBase { AtkCoordType coord_type); void GetPosition(gint* x, gint* y, AtkCoordType coord_type); void GetSize(gint* width, gint* height); + gfx::NativeViewAccessible HitTestSync(gint x, + gint y, + AtkCoordType coord_type); + bool GrabFocus(); + bool DoDefaultAction(); + const gchar* GetDefaultActionName(); void SetExtentsRelativeToAtkCoordinateType( gint* x, gint* y, gint* width, gint* height, AtkCoordType coord_type); + // AtkDocument helpers + const gchar* GetDocumentAttributeValue(const gchar* attribute) const; + AtkAttributeSet* GetDocumentAttributes() const; + + // AtkHyperlink helpers + AtkHyperlink* GetAtkHyperlink(); + + // Misc helpers + void GetFloatAttributeInGValue(AXFloatAttribute attr, GValue* value); + // AXPlatformNode overrides. gfx::NativeViewAccessible GetNativeViewAccessible() override; void NotifyAccessibilityEvent(ui::AXEvent event_type) override; @@ -47,10 +81,32 @@ class AXPlatformNodeAuraLinux : public AXPlatformNodeBase { int GetIndexInParent() override; private: - ~AXPlatformNodeAuraLinux() override; - - // We own a reference to this ref-counted object. + enum AtkInterfaces { + ATK_ACTION_INTERFACE, + ATK_COMPONENT_INTERFACE, + ATK_DOCUMENT_INTERFACE, + ATK_EDITABLE_TEXT_INTERFACE, + ATK_HYPERLINK_INTERFACE, + ATK_HYPERTEXT_INTERFACE, + ATK_IMAGE_INTERFACE, + ATK_SELECTION_INTERFACE, + ATK_TABLE_INTERFACE, + ATK_TEXT_INTERFACE, + ATK_VALUE_INTERFACE, + }; + static const char* GetUniqueAccessibilityGTypeName(int interface_mask); + int GetGTypeInterfaceMask(); + GType GetAccessibilityGType(); + AtkObject* CreateAtkObject(); + void DestroyAtkObjects(); + + // Keep information of latest AtkInterfaces mask to refresh atk object + // interfaces accordingly if needed. + int interface_mask_; + + // We own a reference to these ref-counted objects. AtkObject* atk_object_; + AtkHyperlink* atk_hyperlink_; // The root-level Application object that's the parent of all // top-level windows. diff --git a/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc new file mode 100644 index 00000000000..e20de0f8cdd --- /dev/null +++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc @@ -0,0 +1,497 @@ +// Copyright 2017 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. + +// Chromium cannot upgrade to ATK 2.12 API as it still needs to run +// valid builds for Ubuntu Trusty. +#define ATK_DISABLE_DEPRECATION_WARNINGS + +#include <atk/atk.h> + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/accessibility/platform/ax_platform_node_unittest.h" +#include "ui/accessibility/platform/test_ax_node_wrapper.h" + +namespace ui { + +class AXPlatformNodeAuraLinuxTest : public AXPlatformNodeTest { + public: + AXPlatformNodeAuraLinuxTest() {} + ~AXPlatformNodeAuraLinuxTest() override {} + + void SetUp() override {} + + protected: + AtkObject* AtkObjectFromNode(AXNode* node) { + TestAXNodeWrapper* wrapper = + TestAXNodeWrapper::GetOrCreate(tree_.get(), node); + if (!wrapper) + return nullptr; + AXPlatformNode* ax_platform_node = wrapper->ax_platform_node(); + AtkObject* atk_object = ax_platform_node->GetNativeViewAccessible(); + return atk_object; + } + + AtkObject* GetRootAtkObject() { return AtkObjectFromNode(GetRootNode()); } +}; + +// +// AtkObject tests +// + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectDetachedObject) { + AXNodeData root; + root.id = 1; + root.SetName("Name"); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + g_object_ref(root_obj); + + const gchar* name = atk_object_get_name(root_obj); + EXPECT_STREQ("Name", name); + + AtkStateSet* state_set = atk_object_ref_state_set(root_obj); + ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); + EXPECT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_DEFUNCT)); + g_object_unref(state_set); + + tree_.reset(new AXTree()); + EXPECT_EQ(nullptr, atk_object_get_name(root_obj)); + + state_set = atk_object_ref_state_set(root_obj); + ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); + EXPECT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_DEFUNCT)); + g_object_unref(state_set); + + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectName) { + AXNodeData root; + root.id = 1; + root.SetName("Name"); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + g_object_ref(root_obj); + + const gchar* name = atk_object_get_name(root_obj); + EXPECT_STREQ("Name", name); + + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectDescription) { + AXNodeData root; + root.id = 1; + root.AddStringAttribute(AX_ATTR_DESCRIPTION, "Description"); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + g_object_ref(root_obj); + + const gchar* description = atk_object_get_description(root_obj); + EXPECT_STREQ("Description", description); + + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectRole) { + AXNodeData root; + root.id = 1; + root.child_ids.push_back(2); + + AXNodeData child; + child.id = 2; + + Init(root, child); + AXNode* child_node = GetRootNode()->children()[0]; + + child.role = AX_ROLE_ALERT; + child_node->SetData(child); + AtkObject* child_obj(AtkObjectFromNode(child_node)); + ASSERT_TRUE(ATK_IS_OBJECT(child_obj)); + g_object_ref(child_obj); + EXPECT_EQ(ATK_ROLE_ALERT, atk_object_get_role(child_obj)); + g_object_unref(child_obj); + + child.role = AX_ROLE_BUTTON; + child_node->SetData(child); + child_obj = AtkObjectFromNode(child_node); + ASSERT_TRUE(ATK_IS_OBJECT(child_obj)); + g_object_ref(child_obj); + EXPECT_EQ(ATK_ROLE_PUSH_BUTTON, atk_object_get_role(child_obj)); + g_object_unref(child_obj); + + child.role = AX_ROLE_CANVAS; + child_node->SetData(child); + child_obj = AtkObjectFromNode(child_node); + ASSERT_TRUE(ATK_IS_OBJECT(child_obj)); + g_object_ref(child_obj); + EXPECT_EQ(ATK_ROLE_CANVAS, atk_object_get_role(child_obj)); + g_object_unref(child_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectState) { + AXNodeData root; + root.id = 1; + root.AddState(AX_STATE_DEFAULT); + root.AddState(AX_STATE_EXPANDED); + + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + g_object_ref(root_obj); + + AtkStateSet* state_set = atk_object_ref_state_set(root_obj); + ASSERT_TRUE(ATK_IS_STATE_SET(state_set)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_DEFAULT)); + ASSERT_TRUE(atk_state_set_contains_state(state_set, ATK_STATE_EXPANDED)); + ASSERT_FALSE(atk_state_set_contains_state(state_set, ATK_STATE_SELECTED)); + g_object_unref(state_set); + + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectChildAndParent) { + AXNodeData root; + root.id = 1; + root.child_ids.push_back(2); + root.child_ids.push_back(3); + + AXNodeData button; + button.role = AX_ROLE_BUTTON; + button.id = 2; + + AXNodeData checkbox; + checkbox.role = AX_ROLE_CHECK_BOX; + checkbox.id = 3; + + Init(root, button, checkbox); + AXNode* button_node = GetRootNode()->children()[0]; + AXNode* checkbox_node = GetRootNode()->children()[1]; + AtkObject* root_obj = GetRootAtkObject(); + AtkObject* button_obj = AtkObjectFromNode(button_node); + AtkObject* checkbox_obj = AtkObjectFromNode(checkbox_node); + + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + EXPECT_EQ(2, atk_object_get_n_accessible_children(root_obj)); + ASSERT_TRUE(ATK_IS_OBJECT(button_obj)); + EXPECT_EQ(0, atk_object_get_n_accessible_children(button_obj)); + ASSERT_TRUE(ATK_IS_OBJECT(checkbox_obj)); + EXPECT_EQ(0, atk_object_get_n_accessible_children(checkbox_obj)); + + { + AtkObject* result = atk_object_ref_accessible_child(root_obj, 0); + EXPECT_TRUE(ATK_IS_OBJECT(root_obj)); + EXPECT_EQ(result, button_obj); + g_object_unref(result); + } + { + AtkObject* result = atk_object_ref_accessible_child(root_obj, 1); + EXPECT_TRUE(ATK_IS_OBJECT(root_obj)); + EXPECT_EQ(result, checkbox_obj); + g_object_unref(result); + } + + // Now check parents. + { + AtkObject* result = atk_object_get_parent(button_obj); + EXPECT_TRUE(ATK_IS_OBJECT(result)); + EXPECT_EQ(result, root_obj); + } + { + AtkObject* result = atk_object_get_parent(checkbox_obj); + EXPECT_TRUE(ATK_IS_OBJECT(result)); + EXPECT_EQ(result, root_obj); + } +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectIndexInParent) { + AXNodeData root; + root.id = 1; + root.child_ids.push_back(2); + root.child_ids.push_back(3); + + AXNodeData left; + left.id = 2; + + AXNodeData right; + right.id = 3; + + Init(root, left, right); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + g_object_ref(root_obj); + + AtkObject* left_obj = atk_object_ref_accessible_child(root_obj, 0); + ASSERT_TRUE(ATK_IS_OBJECT(left_obj)); + AtkObject* right_obj = atk_object_ref_accessible_child(root_obj, 1); + ASSERT_TRUE(ATK_IS_OBJECT(right_obj)); + + EXPECT_EQ(0, atk_object_get_index_in_parent(left_obj)); + EXPECT_EQ(1, atk_object_get_index_in_parent(right_obj)); + + g_object_unref(left_obj); + g_object_unref(right_obj); + g_object_unref(root_obj); +} + +// +// AtkComponent tests +// + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentRefAtPoint) { + AXNodeData root; + root.id = 0; + root.child_ids.push_back(1); + root.child_ids.push_back(2); + root.location = gfx::RectF(0, 0, 30, 30); + + AXNodeData node1; + node1.id = 1; + node1.location = gfx::RectF(0, 0, 10, 10); + node1.SetName("Name1"); + + AXNodeData node2; + node2.id = 2; + node2.location = gfx::RectF(20, 20, 10, 10); + node2.SetName("Name2"); + + Init(root, node1, node2); + + AtkObject* root_obj(GetRootAtkObject()); + EXPECT_TRUE(ATK_IS_OBJECT(root_obj)); + EXPECT_TRUE(ATK_IS_COMPONENT(root_obj)); + g_object_ref(root_obj); + + AtkObject* child_obj = atk_component_ref_accessible_at_point( + ATK_COMPONENT(root_obj), 50, 50, ATK_XY_SCREEN); + EXPECT_EQ(nullptr, child_obj); + + // this is directly on node 1. + child_obj = atk_component_ref_accessible_at_point(ATK_COMPONENT(root_obj), 5, + 5, ATK_XY_SCREEN); + ASSERT_NE(nullptr, child_obj); + EXPECT_TRUE(ATK_IS_OBJECT(child_obj)); + + const gchar* name = atk_object_get_name(child_obj); + EXPECT_STREQ("Name1", name); + + g_object_unref(child_obj); + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentsGetExtentsPositionSize) { + AXNodeData root; + root.id = 1; + root.role = AX_ROLE_WINDOW; + root.location = gfx::RectF(10, 40, 800, 600); + root.child_ids.push_back(2); + + AXNodeData child; + child.id = 2; + child.location = gfx::RectF(100, 150, 200, 200); + Init(root, child); + + TestAXNodeWrapper::SetGlobalCoordinateOffset(gfx::Vector2d(100, 200)); + + AtkObject* root_obj = GetRootAtkObject(); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + ASSERT_TRUE(ATK_IS_COMPONENT(root_obj)); + g_object_ref(root_obj); + + gint x_left, y_top, width, height; + atk_component_get_extents(ATK_COMPONENT(root_obj), &x_left, &y_top, &width, + &height, ATK_XY_SCREEN); + EXPECT_EQ(110, x_left); + EXPECT_EQ(240, y_top); + EXPECT_EQ(800, width); + EXPECT_EQ(600, height); + + atk_component_get_position(ATK_COMPONENT(root_obj), &x_left, &y_top, + ATK_XY_SCREEN); + EXPECT_EQ(110, x_left); + EXPECT_EQ(240, y_top); + + atk_component_get_extents(ATK_COMPONENT(root_obj), &x_left, &y_top, &width, + &height, ATK_XY_WINDOW); + EXPECT_EQ(110, x_left); + EXPECT_EQ(240, y_top); + EXPECT_EQ(800, width); + EXPECT_EQ(600, height); + + atk_component_get_position(ATK_COMPONENT(root_obj), &x_left, &y_top, + ATK_XY_WINDOW); + EXPECT_EQ(110, x_left); + EXPECT_EQ(240, y_top); + + atk_component_get_size(ATK_COMPONENT(root_obj), &width, &height); + EXPECT_EQ(800, width); + EXPECT_EQ(600, height); + + AXNode* child_node = GetRootNode()->children()[0]; + AtkObject* child_obj = AtkObjectFromNode(child_node); + ASSERT_TRUE(ATK_IS_OBJECT(child_obj)); + ASSERT_TRUE(ATK_IS_COMPONENT(child_obj)); + g_object_ref(child_obj); + + atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width, + &height, ATK_XY_SCREEN); + EXPECT_EQ(200, x_left); + EXPECT_EQ(350, y_top); + EXPECT_EQ(200, width); + EXPECT_EQ(200, height); + + atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width, + &height, ATK_XY_WINDOW); + EXPECT_EQ(90, x_left); + EXPECT_EQ(110, y_top); + EXPECT_EQ(200, width); + EXPECT_EQ(200, height); + + atk_component_get_extents(ATK_COMPONENT(child_obj), nullptr, &y_top, &width, + &height, ATK_XY_SCREEN); + EXPECT_EQ(200, height); + atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, nullptr, &width, + &height, ATK_XY_SCREEN); + EXPECT_EQ(200, x_left); + atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, nullptr, + &height, ATK_XY_SCREEN); + EXPECT_EQ(350, y_top); + atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width, + nullptr, ATK_XY_SCREEN); + EXPECT_EQ(200, width); + + g_object_unref(child_obj); + g_object_unref(root_obj); +} + +// +// AtkValue tests +// + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetCurrentValue) { + AXNodeData root; + root.id = 1; + root.role = AX_ROLE_SLIDER; + root.AddFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, 5.0); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + ASSERT_TRUE(ATK_IS_VALUE(root_obj)); + g_object_ref(root_obj); + + GValue current_value = G_VALUE_INIT; + atk_value_get_current_value(ATK_VALUE(root_obj), ¤t_value); + + EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(¤t_value)); + EXPECT_EQ(5.0, g_value_get_float(¤t_value)); + + g_value_unset(¤t_value); + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMaximumValue) { + AXNodeData root; + root.id = 1; + root.role = AX_ROLE_SLIDER; + root.AddFloatAttribute(AX_ATTR_MAX_VALUE_FOR_RANGE, 5.0); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + ASSERT_TRUE(ATK_IS_VALUE(root_obj)); + g_object_ref(root_obj); + + GValue max_value = G_VALUE_INIT; + atk_value_get_maximum_value(ATK_VALUE(root_obj), &max_value); + + EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&max_value)); + EXPECT_EQ(5.0, g_value_get_float(&max_value)); + + g_value_unset(&max_value); + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumValue) { + AXNodeData root; + root.id = 1; + root.role = AX_ROLE_SLIDER; + root.AddFloatAttribute(AX_ATTR_MIN_VALUE_FOR_RANGE, 5.0); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + ASSERT_TRUE(ATK_IS_VALUE(root_obj)); + g_object_ref(root_obj); + + GValue min_value = G_VALUE_INIT; + atk_value_get_minimum_value(ATK_VALUE(root_obj), &min_value); + + EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&min_value)); + EXPECT_EQ(5.0, g_value_get_float(&min_value)); + + g_value_unset(&min_value); + g_object_unref(root_obj); +} + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumIncrement) { + AXNodeData root; + root.id = 1; + root.role = AX_ROLE_SLIDER; + root.AddFloatAttribute(AX_ATTR_STEP_VALUE_FOR_RANGE, 5.0); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + ASSERT_TRUE(ATK_IS_VALUE(root_obj)); + g_object_ref(root_obj); + + GValue increment = G_VALUE_INIT; + atk_value_get_minimum_increment(ATK_VALUE(root_obj), &increment); + + EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&increment)); + EXPECT_EQ(5.0, g_value_get_float(&increment)); + + g_value_unset(&increment); + g_object_unref(root_obj); +} + +// +// AtkHyperlinkImpl interface +// + +TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkHyperlink) { + AXNodeData root; + root.id = 1; + root.role = AX_ROLE_LINK; + root.AddStringAttribute(AX_ATTR_URL, "http://foo.com"); + Init(root); + + AtkObject* root_obj(GetRootAtkObject()); + ASSERT_TRUE(ATK_IS_OBJECT(root_obj)); + ASSERT_TRUE(ATK_IS_HYPERLINK_IMPL(root_obj)); + g_object_ref(root_obj); + + AtkHyperlink* hyperlink( + atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(root_obj))); + ASSERT_TRUE(ATK_IS_HYPERLINK(hyperlink)); + + EXPECT_EQ(1, atk_hyperlink_get_n_anchors(hyperlink)); + gchar* uri = atk_hyperlink_get_uri(hyperlink, 0); + EXPECT_STREQ("http://foo.com", uri); + g_free(uri); + + g_object_unref(hyperlink); + g_object_unref(root_obj); +} + +} // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node_base.cc b/chromium/ui/accessibility/platform/ax_platform_node_base.cc index cf0ff4cc8c2..97afb682632 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_base.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_base.cc @@ -262,43 +262,20 @@ bool AXPlatformNodeBase::IsTextOnlyObject() const { GetData().role == AX_ROLE_INLINE_TEXT_BOX; } -bool AXPlatformNodeBase::IsNativeTextControl() const { - const std::string& html_tag = GetStringAttribute(AX_ATTR_HTML_TAG); - if (html_tag == "input") { - std::string input_type; - if (!GetData().GetHtmlAttribute("type", &input_type)) - return true; - return input_type.empty() || input_type == "email" || - input_type == "password" || input_type == "search" || - input_type == "tel" || input_type == "text" || input_type == "url" || - input_type == "number"; - } - return html_tag == "textarea"; -} - -bool AXPlatformNodeBase::IsSimpleTextControl() const { - // Time fields, color wells and spinner buttons might also use text fields as - // constituent parts, but they are not considered text fields as a whole. - switch (GetData().role) { - case AX_ROLE_COMBO_BOX: - case AX_ROLE_SEARCH_BOX: - return true; - case AX_ROLE_TEXT_FIELD: - return !GetData().HasState(AX_STATE_RICHLY_EDITABLE); - default: - return false; - } +bool AXPlatformNodeBase::IsPlainTextField() const { + // We need to check both the role and editable state, because some ARIA text + // fields may in fact not be editable, whilst some editable fields might not + // have the role. + return !GetData().HasState(AX_STATE_RICHLY_EDITABLE) && + (GetData().role == AX_ROLE_TEXT_FIELD || + GetData().role == AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX || + GetData().role == AX_ROLE_SEARCH_BOX || + GetBoolAttribute(AX_ATTR_EDITABLE_ROOT)); } -// Indicates if this object is at the root of a rich edit text control. -bool AXPlatformNodeBase::IsRichTextControl() { - gfx::NativeViewAccessible parent_accessible = GetParent(); - AXPlatformNodeBase* parent = FromNativeViewAccessible(parent_accessible); - if (!parent) - return false; - - return GetData().HasState(AX_STATE_RICHLY_EDITABLE) && - (!parent || !parent->GetData().HasState(AX_STATE_RICHLY_EDITABLE)); +bool AXPlatformNodeBase::IsRichTextField() const { + return GetBoolAttribute(AX_ATTR_EDITABLE_ROOT) && + GetData().HasState(AX_STATE_RICHLY_EDITABLE); } base::string16 AXPlatformNodeBase::GetInnerText() { @@ -337,7 +314,7 @@ base::string16 AXPlatformNodeBase::GetRangeValueText() { base::string16 value = GetString16Attribute(AX_ATTR_VALUE); if (value.empty() && GetFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, &fval)) { - value = base::UTF8ToUTF16(base::DoubleToString(fval)); + value = base::NumberToString16(fval); } return value; } @@ -466,7 +443,7 @@ int AXPlatformNodeBase::GetTableRowSpan() const { } bool AXPlatformNodeBase::HasCaret() { - if (IsSimpleTextControl() && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) && + if (IsPlainTextField() && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) { return true; } @@ -504,10 +481,7 @@ bool AXPlatformNodeBase::IsLeaf() { // implementation details, but we want to expose them as leaves to platform // accessibility APIs because screen readers might be confused if they find // any children. - // Note that if a combo box, search box or text field are not native, they - // might present a menu of choices using aria-owns which should not be hidden - // from tree. - if (IsNativeTextControl() || IsTextOnlyObject()) + if (IsPlainTextField() || IsTextOnlyObject()) return true; // Roles whose children are only presentational according to the ARIA and @@ -556,8 +530,7 @@ base::string16 AXPlatformNodeBase::GetValue() { // Some screen readers like Jaws and VoiceOver require a // value to be set in text fields with rich content, even though the same // information is available on the children. - if (value.empty() && (IsSimpleTextControl() || IsRichTextControl()) && - !IsNativeTextControl()) + if (value.empty() && IsRichTextField()) return GetInnerText(); return value; diff --git a/chromium/ui/accessibility/platform/ax_platform_node_base.h b/chromium/ui/accessibility/platform/ax_platform_node_base.h index 32eeb4a2bc5..1099e6446e2 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_base.h +++ b/chromium/ui/accessibility/platform/ax_platform_node_base.h @@ -147,9 +147,8 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode { ~AXPlatformNodeBase() override; bool IsTextOnlyObject() const; - bool IsNativeTextControl() const; - bool IsSimpleTextControl() const; - bool IsRichTextControl(); + bool IsPlainTextField() const; + bool IsRichTextField() const; bool IsRangeValueSupported() const; // Get the range value text, which might come from aria-valuetext or diff --git a/chromium/ui/accessibility/platform/ax_platform_node_mac.mm b/chromium/ui/accessibility/platform/ax_platform_node_mac.mm index fdc0cb47c40..bd87791d135 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/chromium/ui/accessibility/platform/ax_platform_node_mac.mm @@ -44,7 +44,8 @@ RoleMap BuildRoleMap() { {ui::AX_ROLE_COLOR_WELL, NSAccessibilityColorWellRole}, {ui::AX_ROLE_COLUMN, NSAccessibilityColumnRole}, {ui::AX_ROLE_COLUMN_HEADER, @"AXCell"}, - {ui::AX_ROLE_COMBO_BOX, NSAccessibilityComboBoxRole}, + {ui::AX_ROLE_COMBO_BOX_GROUPING, NSAccessibilityGroupRole}, + {ui::AX_ROLE_COMBO_BOX_MENU_BUTTON, NSAccessibilityButtonRole}, {ui::AX_ROLE_COMPLEMENTARY, NSAccessibilityGroupRole}, {ui::AX_ROLE_CONTENT_INFO, NSAccessibilityGroupRole}, {ui::AX_ROLE_DATE, @"AXDateField"}, @@ -134,6 +135,7 @@ RoleMap BuildRoleMap() { {ui::AX_ROLE_TAB_PANEL, NSAccessibilityGroupRole}, {ui::AX_ROLE_TERM, NSAccessibilityGroupRole}, {ui::AX_ROLE_TEXT_FIELD, NSAccessibilityTextFieldRole}, + {ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX, NSAccessibilityComboBoxRole}, {ui::AX_ROLE_TIME, NSAccessibilityGroupRole}, {ui::AX_ROLE_TIMER, NSAccessibilityGroupRole}, {ui::AX_ROLE_TOGGLE_BUTTON, NSAccessibilityCheckBoxRole}, @@ -430,13 +432,14 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) { switch (node_->GetData().role) { case ui::AX_ROLE_TEXT_FIELD: + case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX: case ui::AX_ROLE_STATIC_TEXT: [axAttributes addObject:kTextAttributes]; if (!node_->GetData().HasState(ui::AX_STATE_PROTECTED)) [axAttributes addObjectsFromArray:kUnprotectedTextAttributes]; // Fallthrough. case ui::AX_ROLE_CHECK_BOX: - case ui::AX_ROLE_COMBO_BOX: + case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON: case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: case ui::AX_ROLE_MENU_ITEM_RADIO: case ui::AX_ROLE_RADIO_BUTTON: diff --git a/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc b/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc new file mode 100644 index 00000000000..de424716d22 --- /dev/null +++ b/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc @@ -0,0 +1,257 @@ +// Copyright 2017 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 "ui/accessibility/platform/ax_platform_node_unittest.h" + +namespace ui { + +AXPlatformNodeTest::AXPlatformNodeTest() {} + +AXPlatformNodeTest::~AXPlatformNodeTest() {} + +void AXPlatformNodeTest::Init(const AXTreeUpdate& initial_state) { + tree_.reset(new AXTree(initial_state)); +} + +void AXPlatformNodeTest::Init(const AXNodeData& node1) { + AXTreeUpdate update; + update.root_id = node1.id; + update.nodes.push_back(node1); + Init(update); +} + +void AXPlatformNodeTest::Init(const AXNodeData& node1, + const AXNodeData& node2) { + AXTreeUpdate update; + update.root_id = node1.id; + update.nodes.push_back(node1); + update.nodes.push_back(node2); + Init(update); +} + +void AXPlatformNodeTest::Init(const AXNodeData& node1, + const AXNodeData& node2, + const AXNodeData& node3) { + AXTreeUpdate update; + update.root_id = node1.id; + update.nodes.push_back(node1); + update.nodes.push_back(node2); + update.nodes.push_back(node3); + Init(update); +} + +void AXPlatformNodeTest::Init(const AXNodeData& node1, + const AXNodeData& node2, + const AXNodeData& node3, + const AXNodeData& node4) { + AXTreeUpdate update; + update.root_id = node1.id; + update.nodes.push_back(node1); + update.nodes.push_back(node2); + update.nodes.push_back(node3); + update.nodes.push_back(node4); + Init(update); +} + +AXTreeUpdate AXPlatformNodeTest::BuildTextField() { + AXNodeData text_field_node; + text_field_node.id = 1; + text_field_node.role = AX_ROLE_TEXT_FIELD; + text_field_node.AddState(AX_STATE_EDITABLE); + text_field_node.SetValue("How now brown cow."); + + AXTreeUpdate update; + update.root_id = text_field_node.id; + update.nodes.push_back(text_field_node); + return update; +} + +AXTreeUpdate AXPlatformNodeTest::BuildTextFieldWithSelectionRange( + int32_t start, + int32_t stop) { + AXNodeData text_field_node; + text_field_node.id = 1; + text_field_node.role = AX_ROLE_TEXT_FIELD; + text_field_node.AddState(AX_STATE_EDITABLE); + text_field_node.AddState(AX_STATE_SELECTED); + text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, start); + text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, stop); + text_field_node.SetValue("How now brown cow."); + + AXTreeUpdate update; + update.root_id = text_field_node.id; + update.nodes.push_back(text_field_node); + return update; +} + +AXTreeUpdate AXPlatformNodeTest::BuildContentEditable() { + AXNodeData content_editable_node; + content_editable_node.id = 1; + content_editable_node.role = AX_ROLE_GROUP; + content_editable_node.AddState(AX_STATE_RICHLY_EDITABLE); + content_editable_node.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true); + content_editable_node.SetValue("How now brown cow."); + + AXTreeUpdate update; + update.root_id = content_editable_node.id; + update.nodes.push_back(content_editable_node); + return update; +} + +AXTreeUpdate AXPlatformNodeTest::BuildContentEditableWithSelectionRange( + int32_t start, + int32_t end) { + AXNodeData content_editable_node; + content_editable_node.id = 1; + content_editable_node.role = AX_ROLE_GROUP; + content_editable_node.AddState(AX_STATE_RICHLY_EDITABLE); + content_editable_node.AddState(AX_STATE_SELECTED); + content_editable_node.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true); + content_editable_node.SetValue("How now brown cow."); + + AXTreeUpdate update; + update.root_id = content_editable_node.id; + update.nodes.push_back(content_editable_node); + + update.has_tree_data = true; + update.tree_data.sel_anchor_object_id = content_editable_node.id; + update.tree_data.sel_focus_object_id = content_editable_node.id; + update.tree_data.sel_anchor_offset = start; + update.tree_data.sel_focus_offset = end; + + return update; +} + +AXTreeUpdate AXPlatformNodeTest::AXPlatformNodeTest::Build3X3Table() { + /* + Build a table that looks like: + + ---------------------- (A) Column Header + | | (A) | (B) | (B) Column Header + ---------------------- (C) Row Header + | (C) | 1 | 2 | (D) Row Header + ---------------------- + | (D) | 3 | 4 | + ---------------------- + */ + + AXNodeData table; + table.id = 0; + table.role = AX_ROLE_TABLE; + + table.AddIntAttribute(AX_ATTR_TABLE_ROW_COUNT, 3); + table.AddIntAttribute(AX_ATTR_TABLE_COLUMN_COUNT, 3); + + // Ordering in this list matters. It is used in the calculation + // of where cells are by the following: + // int position = row * GetTableColumnCount() + column; + + std::vector<int32_t> ids{51, 52, 53, 2, 3, 4, 11, 12, 13}; + table.AddIntListAttribute(AX_ATTR_CELL_IDS, ids); + table.AddIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS, ids); + + table.child_ids.push_back(50); // Header + table.child_ids.push_back(1); // Row 1 + table.child_ids.push_back(10); // Row 2 + + // Table column header + AXNodeData table_row_header; + table_row_header.id = 50; + table_row_header.role = AX_ROLE_ROW; + table_row_header.child_ids.push_back(51); + table_row_header.child_ids.push_back(52); + table_row_header.child_ids.push_back(53); + + AXNodeData table_column_header_1; + table_column_header_1.id = 51; + table_column_header_1.role = AX_ROLE_COLUMN_HEADER; + + AXNodeData table_column_header_2; + table_column_header_2.id = 52; + table_column_header_2.role = AX_ROLE_COLUMN_HEADER; + table_column_header_2.SetName("column header 1"); + + AXNodeData table_column_header_3; + table_column_header_3.id = 53; + table_column_header_3.role = AX_ROLE_COLUMN_HEADER; + // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a + // description + table_column_header_3.AddStringAttribute(AX_ATTR_DESCRIPTION, + "column header 2"); + + // Row 1 + AXNodeData table_row_1; + table_row_1.id = 1; + table_row_1.role = AX_ROLE_ROW; + table_row_1.child_ids.push_back(2); + table_row_1.child_ids.push_back(3); + table_row_1.child_ids.push_back(4); + + AXNodeData table_row_header_1; + table_row_header_1.id = 2; + table_row_header_1.role = AX_ROLE_ROW_HEADER; + table_row_header_1.SetName("row header 1"); + + AXNodeData table_cell_1; + table_cell_1.id = 3; + table_cell_1.role = AX_ROLE_CELL; + table_cell_1.SetName("1"); + + AXNodeData table_cell_2; + table_cell_2.id = 4; + table_cell_2.role = AX_ROLE_CELL; + table_cell_2.SetName("2"); + + // Row 2 + AXNodeData table_row_2; + table_row_2.id = 10; + table_row_2.role = AX_ROLE_ROW; + table_row_2.child_ids.push_back(11); + table_row_2.child_ids.push_back(12); + table_row_2.child_ids.push_back(13); + + AXNodeData table_row_header_2; + table_row_header_2.id = 11; + table_row_header_2.role = AX_ROLE_ROW_HEADER; + // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a + // description + table_row_header_2.AddStringAttribute(AX_ATTR_DESCRIPTION, "row header 2"); + + AXNodeData table_cell_3; + table_cell_3.id = 12; + table_cell_3.role = AX_ROLE_CELL; + table_cell_3.SetName("3"); + + AXNodeData table_cell_4; + table_cell_4.id = 13; + table_cell_4.role = AX_ROLE_CELL; + table_cell_4.SetName("4"); + + AXTreeUpdate update; + update.root_id = table.id; + + // Some of the table testing code will index into |nodes| + // and change the state of the given node. If you reorder + // these, you're going to need to update the tests. + update.nodes.push_back(table); // 0 + + update.nodes.push_back(table_row_header); // 1 + update.nodes.push_back(table_column_header_1); // 2 + update.nodes.push_back(table_column_header_2); // 3 + update.nodes.push_back(table_column_header_3); // 4 + + update.nodes.push_back(table_row_1); // 5 + update.nodes.push_back(table_row_header_1); // 6 + update.nodes.push_back(table_cell_1); // 7 + update.nodes.push_back(table_cell_2); // 8 + + update.nodes.push_back(table_row_2); // 9 + update.nodes.push_back(table_row_header_2); // 10 + update.nodes.push_back(table_cell_3); // 11 + update.nodes.push_back(table_cell_4); // 12 + + return update; +} + +} // namespace ui diff --git a/chromium/ui/accessibility/platform/ax_platform_node_unittest.h b/chromium/ui/accessibility/platform/ax_platform_node_unittest.h new file mode 100644 index 00000000000..d2f8189e6f9 --- /dev/null +++ b/chromium/ui/accessibility/platform/ax_platform_node_unittest.h @@ -0,0 +1,50 @@ +// Copyright 2017 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 UI_ACCESSIBILITY_AX_PLATFORM_NODE_UNITTEST_H_ +#define UI_ACCESSIBILITY_AX_PLATFORM_NODE_UNITTEST_H_ + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/accessibility/ax_node.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/ax_tree.h" +#include "ui/accessibility/ax_tree_update.h" + +namespace ui { + +class AXPlatformNodeTest : public testing::Test { + public: + AXPlatformNodeTest(); + ~AXPlatformNodeTest() override; + + // Initialize given an AXTreeUpdate. + void Init(const AXTreeUpdate& initial_state); + + // Convenience functions to initialize directly from a few AXNodeData objects. + void Init(const AXNodeData& node1); + void Init(const AXNodeData& node1, const AXNodeData& node2); + void Init(const AXNodeData& node1, + const AXNodeData& node2, + const AXNodeData& node3); + void Init(const AXNodeData& node1, + const AXNodeData& node2, + const AXNodeData& node3, + const AXNodeData& node4); + + protected: + AXNode* GetRootNode() { return tree_->root(); } + + AXTreeUpdate BuildTextField(); + AXTreeUpdate BuildTextFieldWithSelectionRange(int32_t start, int32_t stop); + AXTreeUpdate BuildContentEditable(); + AXTreeUpdate BuildContentEditableWithSelectionRange(int32_t start, + int32_t end); + AXTreeUpdate Build3X3Table(); + + std::unique_ptr<AXTree> tree_; +}; + +} // namespace ui + +#endif // UI_ACCESSIBILITY_AX_PLATFORM_NODE_UNITTEST_H_ diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win.cc b/chromium/ui/accessibility/platform/ax_platform_node_win.cc index c97259f9158..083abf25f8f 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_win.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_win.cc @@ -4,6 +4,8 @@ #include "ui/accessibility/platform/ax_platform_node_win.h" +#include <wrl/client.h> + #include <vector> #include "base/containers/hash_tables.h" @@ -12,7 +14,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/win/enum_variant.h" -#include "base/win/scoped_comptr.h" #include "base/win/scoped_variant.h" #include "third_party/iaccessible2/ia2_api_all.h" #include "third_party/skia/include/core/SkColor.h" @@ -42,34 +43,44 @@ if (!delegate_) \ return E_FAIL; \ if (!arg) \ - return E_INVALIDARG; + return E_INVALIDARG; \ + *arg = {}; #define COM_OBJECT_VALIDATE_2_ARGS(arg1, arg2) \ if (!delegate_) \ return E_FAIL; \ if (!arg1) \ return E_INVALIDARG; \ + *arg1 = {}; \ if (!arg2) \ - return E_INVALIDARG; + return E_INVALIDARG; \ + *arg2 = {}; #define COM_OBJECT_VALIDATE_3_ARGS(arg1, arg2, arg3) \ if (!delegate_) \ return E_FAIL; \ if (!arg1) \ return E_INVALIDARG; \ + *arg1 = {}; \ if (!arg2) \ return E_INVALIDARG; \ + *arg2 = {}; \ if (!arg3) \ - return E_INVALIDARG; + return E_INVALIDARG; \ + *arg3 = {}; #define COM_OBJECT_VALIDATE_4_ARGS(arg1, arg2, arg3, arg4) \ if (!delegate_) \ return E_FAIL; \ if (!arg1) \ return E_INVALIDARG; \ + *arg1 = {}; \ if (!arg2) \ return E_INVALIDARG; \ + *arg2 = {}; \ if (!arg3) \ return E_INVALIDARG; \ + *arg3 = {}; \ if (!arg4) \ - return E_INVALIDARG; + return E_INVALIDARG; \ + *arg4 = {}; #define COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target) \ if (!delegate_) \ return E_FAIL; \ @@ -83,6 +94,7 @@ return E_FAIL; \ if (!arg) \ return E_INVALIDARG; \ + *arg = {}; \ target = GetTargetFromChildID(var_id); \ if (!target) \ return E_INVALIDARG; \ @@ -94,8 +106,10 @@ return E_FAIL; \ if (!arg1) \ return E_INVALIDARG; \ + *arg1 = {}; \ if (!arg2) \ return E_INVALIDARG; \ + *arg2 = {}; \ target = GetTargetFromChildID(var_id); \ if (!target) \ return E_INVALIDARG; \ @@ -107,10 +121,13 @@ return E_FAIL; \ if (!arg1) \ return E_INVALIDARG; \ + *arg1 = {}; \ if (!arg2) \ return E_INVALIDARG; \ + *arg2 = {}; \ if (!arg3) \ return E_INVALIDARG; \ + *arg3 = {}; \ target = GetTargetFromChildID(var_id); \ if (!target) \ return E_INVALIDARG; \ @@ -122,12 +139,16 @@ return E_FAIL; \ if (!arg1) \ return E_INVALIDARG; \ + *arg1 = {}; \ if (!arg2) \ return E_INVALIDARG; \ + *arg2 = {}; \ if (!arg3) \ return E_INVALIDARG; \ + *arg3 = {}; \ if (!arg4) \ return E_INVALIDARG; \ + *arg4 = {}; \ target = GetTargetFromChildID(var_id); \ if (!target) \ return E_INVALIDARG; \ @@ -310,7 +331,7 @@ AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( gfx::NativeViewAccessible accessible) { if (!accessible) return nullptr; - base::win::ScopedComPtr<AXPlatformNodeWin> ax_platform_node; + Microsoft::WRL::ComPtr<AXPlatformNodeWin> ax_platform_node; accessible->QueryInterface(ax_platform_node.GetAddressOf()); return ax_platform_node.Get(); } @@ -598,8 +619,8 @@ void AXPlatformNodeWin::NotifyAccessibilityEvent(AXEvent event_type) { } int AXPlatformNodeWin::GetIndexInParent() { - base::win::ScopedComPtr<IDispatch> parent_dispatch; - base::win::ScopedComPtr<IAccessible> parent_accessible; + Microsoft::WRL::ComPtr<IDispatch> parent_dispatch; + Microsoft::WRL::ComPtr<IAccessible> parent_accessible; if (S_OK != get_accParent(parent_dispatch.GetAddressOf())) return -1; if (S_OK != parent_dispatch.CopyTo(parent_accessible.GetAddressOf())) @@ -610,8 +631,8 @@ int AXPlatformNodeWin::GetIndexInParent() { return -1; for (LONG index = 1; index <= child_count; ++index) { base::win::ScopedVariant childid_index(index); - base::win::ScopedComPtr<IDispatch> child_dispatch; - base::win::ScopedComPtr<IAccessible> child_accessible; + Microsoft::WRL::ComPtr<IDispatch> child_dispatch; + Microsoft::WRL::ComPtr<IAccessible> child_accessible; if (S_OK == parent_accessible->get_accChild( childid_index, child_dispatch.GetAddressOf()) && S_OK == child_dispatch.CopyTo(child_accessible.GetAddressOf())) { @@ -1041,7 +1062,7 @@ STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) { if (result.empty() && target->IsRangeValueSupported()) { float fval; if (target->GetFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, &fval)) { - result = base::UTF8ToUTF16(base::DoubleToString(fval)); + result = base::NumberToString16(fval); *value = SysAllocString(result.c_str()); DCHECK(*value); return S_OK; @@ -1049,11 +1070,8 @@ STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) { } // Last resort (Use innerText) - if (result.empty() && - (target->IsSimpleTextControl() || target->IsRichTextControl()) && - !target->IsNativeTextControl()) { + if (result.empty() && target->IsRichTextField()) result = target->GetInnerText(); - } *value = SysAllocString(result.c_str()); DCHECK(*value); @@ -1076,7 +1094,7 @@ STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, STDMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) { WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_SELECTION); COM_OBJECT_VALIDATE_1_ARG(selected); - std::vector<base::win::ScopedComPtr<IDispatch>> selected_nodes; + std::vector<Microsoft::WRL::ComPtr<IDispatch>> selected_nodes; for (int i = 0; i < delegate_->GetChildCount(); ++i) { auto* node = static_cast<AXPlatformNodeWin*>( FromNativeViewAccessible(delegate_->ChildAtIndex(i))); @@ -2092,6 +2110,9 @@ STDMETHODIMP AXPlatformNodeWin::get_columnHeaderCells( return E_INVALIDARG; *n_column_header_cells = 0; + if (GetData().role != AX_ROLE_CELL) + return S_FALSE; + AXPlatformNodeBase* table = GetTable(); if (!table) { return S_FALSE; @@ -2157,6 +2178,9 @@ STDMETHODIMP AXPlatformNodeWin::get_rowHeaderCells(IUnknown*** cell_accessibles, return E_INVALIDARG; *n_row_header_cells = 0; + if (GetData().role != AX_ROLE_CELL) + return S_FALSE; + AXPlatformNodeBase* table = GetTable(); if (!table) { return S_FALSE; @@ -2638,7 +2662,8 @@ int AXPlatformNodeWin::MSAARole() { case AX_ROLE_COLUMN_HEADER: return ROLE_SYSTEM_COLUMNHEADER; - case AX_ROLE_COMBO_BOX: + case AX_ROLE_COMBO_BOX_GROUPING: + case AX_ROLE_COMBO_BOX_MENU_BUTTON: return ROLE_SYSTEM_COMBOBOX; case AX_ROLE_COMPLEMENTARY: @@ -2868,6 +2893,9 @@ int AXPlatformNodeWin::MSAARole() { case AX_ROLE_SEARCH_BOX: return ROLE_SYSTEM_TEXT; + case AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX: + return ROLE_SYSTEM_COMBOBOX; + case AX_ROLE_ABBR: case AX_ROLE_TIME: return ROLE_SYSTEM_TEXT; @@ -2990,7 +3018,6 @@ bool AXPlatformNodeWin::IsWebAreaForPresentationalIframe() { int32_t AXPlatformNodeWin::ComputeIA2State() { const AXNodeData& data = GetData(); - int32_t ia2_state = IA2_STATE_OPAQUE; const auto checked_state = @@ -3009,20 +3036,16 @@ int32_t AXPlatformNodeWin::ComputeIA2State() { if (data.HasState(AX_STATE_HORIZONTAL)) ia2_state |= IA2_STATE_HORIZONTAL; - const bool is_editable = data.HasState(AX_STATE_EDITABLE); - if (is_editable) + if (data.HasState(AX_STATE_EDITABLE)) ia2_state |= IA2_STATE_EDITABLE; - if (IsRichTextControl() || IsEditField(data.role)) { - // Support multi/single line states if root editable or appropriate role. - // We support the edit box roles even if the area is not actually editable, - // because it is technically feasible for JS to implement the edit box - // by controlling selection. + if (IsPlainTextField() || IsRichTextField()) { if (data.HasState(AX_STATE_MULTILINE)) { ia2_state |= IA2_STATE_MULTI_LINE; } else { ia2_state |= IA2_STATE_SINGLE_LINE; } + ia2_state |= IA2_STATE_SELECTABLE_TEXT; } if (!GetStringAttribute(AX_ATTR_AUTO_COMPLETE).empty()) @@ -3033,20 +3056,9 @@ int32_t AXPlatformNodeWin::ComputeIA2State() { switch (data.role) { case AX_ROLE_MENU_LIST_POPUP: - ia2_state &= ~(IA2_STATE_EDITABLE); - break; case AX_ROLE_MENU_LIST_OPTION: ia2_state &= ~(IA2_STATE_EDITABLE); break; - case AX_ROLE_TEXT_FIELD: - case AX_ROLE_SEARCH_BOX: - if (data.HasState(AX_STATE_MULTILINE)) { - ia2_state |= IA2_STATE_MULTI_LINE; - } else { - ia2_state |= IA2_STATE_SINGLE_LINE; - } - ia2_state |= IA2_STATE_SELECTABLE_TEXT; - break; default: break; } @@ -3250,6 +3262,9 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() { case AX_ARIA_CURRENT_STATE_LOCATION: result.push_back(L"current:location"); break; + case AX_ARIA_CURRENT_STATE_UNCLIPPED_LOCATION: + result.push_back(L"current:unclippedLocation"); + break; case AX_ARIA_CURRENT_STATE_DATE: result.push_back(L"current:date"); break; @@ -3334,7 +3349,8 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() { if (IsRangeValueSupported()) { base::string16 value = GetRangeValueText(); SanitizeStringAttributeForIA2(value, &value); - result.push_back(L"valuetext:" + value); + if (!value.empty()) + result.push_back(L"valuetext:" + value); } // Expose dropeffect attribute. @@ -3386,14 +3402,13 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() { // object (as opposed to treating it like a native Windows text box). // The text-model:a1 attribute is documented here: // http://www.linuxfoundation.org/collaborate/workgroups/accessibility/ia2/ia2_implementation_guide - if (GetData().role == AX_ROLE_TEXT_FIELD) { + if (IsPlainTextField() || IsRichTextField()) result.push_back(L"text-model:a1;"); - } // Expose input-text type attribute. base::string16 type; base::string16 html_tag = GetString16Attribute(AX_ATTR_HTML_TAG); - if (IsSimpleTextControl() && html_tag == L"input" && + if (IsPlainTextField() && html_tag == L"input" && GetData().GetHtmlAttribute("type", &type)) { SanitizeStringAttributeForIA2(type, &type); result.push_back(L"text-input-type:" + type); @@ -3419,7 +3434,7 @@ base::string16 AXPlatformNodeWin::GetValue() { AXHypertext AXPlatformNodeWin::ComputeHypertext() { AXHypertext result; - if (IsSimpleTextControl()) { + if (IsPlainTextField()) { result.hypertext = GetValue(); return result; } @@ -3427,7 +3442,7 @@ AXHypertext AXPlatformNodeWin::ComputeHypertext() { int child_count = delegate_->GetChildCount(); if (!child_count) { - if (IsRichTextControl()) { + if (IsRichTextField()) { // We don't want to expose any associated label in IA2 Hypertext. return result; } @@ -3650,6 +3665,11 @@ int AXPlatformNodeWin::MSAAState() { if (GetData().role == AX_ROLE_LINK) msaa_state |= STATE_SYSTEM_LINKED; + // Special case for indeterminate progressbar. + if (GetData().role == AX_ROLE_PROGRESS_INDICATOR && + !HasFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE)) + msaa_state |= STATE_SYSTEM_MIXED; + return msaa_state; } @@ -3708,7 +3728,7 @@ void AXPlatformNodeWin::RemoveAlertTarget() { base::string16 AXPlatformNodeWin::TextForIAccessibleText() { // Special case allows us to get text even in non-HTML case, e.g. browser UI. - if (IsSimpleTextControl()) + if (IsPlainTextField()) return GetString16Attribute(AX_ATTR_VALUE); return GetText(); } @@ -3717,7 +3737,11 @@ void AXPlatformNodeWin::HandleSpecialTextOffset(LONG* offset) { if (*offset == IA2_TEXT_OFFSET_LENGTH) { *offset = static_cast<LONG>(GetText().length()); } else if (*offset == IA2_TEXT_OFFSET_CARET) { - *offset = static_cast<LONG>(GetIntAttribute(AX_ATTR_TEXT_SEL_END)); + int selection_start, selection_end; + GetSelectionOffsets(&selection_start, &selection_end); + if (selection_end < 0) + *offset = 0; + *offset = static_cast<LONG>(selection_end); } } @@ -3886,10 +3910,10 @@ int32_t AXPlatformNodeWin::GetHypertextOffsetFromChild( AXPlatformNodeWin* child) { // TODO(dougt) DCHECK(child.owner()->PlatformGetParent() == owner()); - // Handle the case when we are dealing with a direct text-only child. - // (Note that this object might be a platform leaf, e.g. an ARIA searchbox, - // Also, direct text-only children should not be present at tree roots and so - // no cross-tree traversal is necessary. + // Handle the case when we are dealing with a text-only child. + // Note that this object might be a platform leaf, e.g. an ARIA searchbox. + // Also, text-only children should not be present at tree roots and so no + // cross-tree traversal is necessary. if (child->IsTextOnlyObject()) { int32_t hypertext_offset = 0; int32_t index_in_parent = child->delegate_->GetIndexInParent(); @@ -4096,7 +4120,7 @@ void AXPlatformNodeWin::GetSelectionOffsets(int* selection_start, int* selection_end) { DCHECK(selection_start && selection_end); - if (IsSimpleTextControl() && + if (IsPlainTextField() && GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) && GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) { return; diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win.h b/chromium/ui/accessibility/platform/ax_platform_node_win.h index c91efb44867..9bfdd15a196 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_win.h +++ b/chromium/ui/accessibility/platform/ax_platform_node_win.h @@ -9,11 +9,11 @@ #include <atlcom.h> #include <oleacc.h> #include <vector> +#include <wrl/client.h> #include "base/compiler_specific.h" #include "base/metrics/histogram_macros.h" #include "base/observer_list.h" -#include "base/win/scoped_comptr.h" #include "third_party/iaccessible2/ia2_api_all.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_text_utils.h" @@ -261,7 +261,7 @@ class AXPlatformNodeRelationWin : public CComObjectRootEx<CComMultiThreadModel>, private: base::string16 type_; - base::win::ScopedComPtr<AXPlatformNodeWin> owner_; + Microsoft::WRL::ComPtr<AXPlatformNodeWin> owner_; std::vector<int> target_ids_; }; 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 a6d25a1c817..32b67e0cd16 100644 --- a/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc @@ -7,21 +7,22 @@ #include <atlbase.h> #include <atlcom.h> #include <oleacc.h> +#include <wrl/client.h> #include <memory> #include "base/win/scoped_bstr.h" -#include "base/win/scoped_comptr.h" #include "base/win/scoped_variant.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/iaccessible2/ia2_api_all.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/platform/ax_platform_node_unittest.h" #include "ui/accessibility/platform/ax_platform_node_win.h" #include "ui/accessibility/platform/test_ax_node_wrapper.h" #include "ui/base/win/atl_module.h" +using Microsoft::WRL::ComPtr; using base::win::ScopedBstr; -using base::win::ScopedComPtr; using base::win::ScopedVariant; namespace ui { @@ -34,7 +35,7 @@ ScopedVariant SELF(CHILDID_SELF); } // namespace -class AXPlatformNodeWinTest : public testing::Test { +class AXPlatformNodeWinTest : public ui::AXPlatformNodeTest { public: AXPlatformNodeWinTest() {} ~AXPlatformNodeWinTest() override {} @@ -43,92 +44,42 @@ class AXPlatformNodeWinTest : public testing::Test { win::CreateATLModuleIfNeeded(); } - // Initialize given an AXTreeUpdate. - void Init(const AXTreeUpdate& initial_state) { - tree_.reset(new AXTree(initial_state)); - } - - // Convenience functions to initialize directly from a few AXNodeData objects. - void Init(const AXNodeData& node1) { - AXTreeUpdate update; - update.root_id = node1.id; - update.nodes.push_back(node1); - Init(update); - } - - void Init(const AXNodeData& node1, - const AXNodeData& node2) { - AXTreeUpdate update; - update.root_id = node1.id; - update.nodes.push_back(node1); - update.nodes.push_back(node2); - Init(update); - } - - void Init(const AXNodeData& node1, - const AXNodeData& node2, - const AXNodeData& node3) { - AXTreeUpdate update; - update.root_id = node1.id; - update.nodes.push_back(node1); - update.nodes.push_back(node2); - update.nodes.push_back(node3); - Init(update); - } - void Init(const AXNodeData& node1, - const AXNodeData& node2, - const AXNodeData& node3, - const AXNodeData& node4) { - AXTreeUpdate update; - update.root_id = node1.id; - update.nodes.push_back(node1); - update.nodes.push_back(node2); - update.nodes.push_back(node3); - update.nodes.push_back(node4); - Init(update); - } - protected: - AXNode* GetRootNode() { - return tree_->root(); - } - - void BuildRelationships(ScopedComPtr<IAccessible2> accessible) { + void BuildRelationships(ComPtr<IAccessible2> accessible) { CHECK(accessible); AXPlatformNodeWin* node = static_cast<AXPlatformNodeWin*>(accessible.Get()); node->CalculateRelationships(); } - ScopedComPtr<IAccessible> IAccessibleFromNode(AXNode* node) { + ComPtr<IAccessible> IAccessibleFromNode(AXNode* node) { TestAXNodeWrapper* wrapper = TestAXNodeWrapper::GetOrCreate(tree_.get(), node); if (!wrapper) - return ScopedComPtr<IAccessible>(); + return ComPtr<IAccessible>(); AXPlatformNode* ax_platform_node = wrapper->ax_platform_node(); IAccessible* iaccessible = ax_platform_node->GetNativeViewAccessible(); - return ScopedComPtr<IAccessible>(iaccessible); + return ComPtr<IAccessible>(iaccessible); } - ScopedComPtr<IAccessible> GetRootIAccessible() { + ComPtr<IAccessible> GetRootIAccessible() { return IAccessibleFromNode(GetRootNode()); } - ScopedComPtr<IAccessible2> ToIAccessible2(ScopedComPtr<IUnknown> unknown) { + ComPtr<IAccessible2> ToIAccessible2(ComPtr<IUnknown> unknown) { CHECK(unknown); - ScopedComPtr<IServiceProvider> service_provider; + ComPtr<IServiceProvider> service_provider; unknown.CopyTo(service_provider.GetAddressOf()); - ScopedComPtr<IAccessible2> result; + ComPtr<IAccessible2> result; CHECK(SUCCEEDED(service_provider->QueryService(IID_IAccessible2, result.GetAddressOf()))); return result; } - ScopedComPtr<IAccessible2> ToIAccessible2( - ScopedComPtr<IAccessible> accessible) { + ComPtr<IAccessible2> ToIAccessible2(ComPtr<IAccessible> accessible) { CHECK(accessible); - ScopedComPtr<IServiceProvider> service_provider; + ComPtr<IServiceProvider> service_provider; accessible.CopyTo(service_provider.GetAddressOf()); - ScopedComPtr<IAccessible2> result; + ComPtr<IAccessible2> result; CHECK(SUCCEEDED(service_provider->QueryService(IID_IAccessible2, result.GetAddressOf()))); return result; @@ -137,7 +88,7 @@ class AXPlatformNodeWinTest : public testing::Test { void CheckVariantHasName(ScopedVariant& variant, const wchar_t* expected_name) { ASSERT_NE(nullptr, variant.ptr()); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(variant.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -146,9 +97,9 @@ class AXPlatformNodeWinTest : public testing::Test { EXPECT_STREQ(expected_name, name); } - void CheckIUnknownHasName(ScopedComPtr<IUnknown> unknown, + void CheckIUnknownHasName(ComPtr<IUnknown> unknown, const wchar_t* expected_name) { - ScopedComPtr<IAccessible2> accessible = ToIAccessible2(unknown); + ComPtr<IAccessible2> accessible = ToIAccessible2(unknown); ASSERT_NE(nullptr, accessible.Get()); ScopedBstr name; @@ -156,222 +107,23 @@ class AXPlatformNodeWinTest : public testing::Test { EXPECT_STREQ(expected_name, name); } - AXTreeUpdate BuildTextField() { - AXNodeData text_field_node; - text_field_node.id = 1; - text_field_node.role = AX_ROLE_TEXT_FIELD; - text_field_node.AddState(AX_STATE_EDITABLE); - text_field_node.SetValue("How now brown cow."); - - AXTreeUpdate update; - update.root_id = text_field_node.id; - update.nodes.push_back(text_field_node); - return update; - } - - AXTreeUpdate BuildTextFieldWithSelectionRange(int32_t start, int32_t stop) { - AXNodeData text_field_node; - text_field_node.id = 1; - text_field_node.role = AX_ROLE_TEXT_FIELD; - text_field_node.AddState(AX_STATE_EDITABLE); - text_field_node.AddState(AX_STATE_SELECTED); - text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, start); - text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, stop); - text_field_node.SetValue("How now brown cow."); - - AXTreeUpdate update; - update.root_id = text_field_node.id; - update.nodes.push_back(text_field_node); - return update; - } + ComPtr<IAccessibleTableCell> GetCellInTable() { + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - AXTreeUpdate BuildContentEditable() { - AXNodeData content_editable_node; - content_editable_node.id = 1; - content_editable_node.role = AX_ROLE_GROUP; - content_editable_node.AddState(AX_STATE_RICHLY_EDITABLE); - content_editable_node.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true); - content_editable_node.SetValue("How now brown cow."); - - AXTreeUpdate update; - update.root_id = content_editable_node.id; - update.nodes.push_back(content_editable_node); - return update; - } - - AXTreeUpdate BuildContentEditableWithSelectionRange(int32_t start, - int32_t end) { - AXNodeData content_editable_node; - content_editable_node.id = 1; - content_editable_node.role = AX_ROLE_GROUP; - content_editable_node.AddState(AX_STATE_RICHLY_EDITABLE); - content_editable_node.AddState(AX_STATE_SELECTED); - content_editable_node.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true); - content_editable_node.SetValue("How now brown cow."); - - AXTreeUpdate update; - update.root_id = content_editable_node.id; - update.nodes.push_back(content_editable_node); - - update.has_tree_data = true; - update.tree_data.sel_anchor_object_id = content_editable_node.id; - update.tree_data.sel_focus_object_id = content_editable_node.id; - update.tree_data.sel_anchor_offset = start; - update.tree_data.sel_focus_offset = end; - - return update; - } - - AXTreeUpdate Build3X3Table() { - /* - Build a table that looks like: - - ---------------------- (A) Column Header - | | (A) | (B) | (B) Column Header - ---------------------- (C) Row Header - | (C) | 1 | 2 | (D) Row Header - ---------------------- - | (D) | 3 | 4 | - ---------------------- - */ - - AXNodeData table; - table.id = 0; - table.role = AX_ROLE_TABLE; - - table.AddIntAttribute(AX_ATTR_TABLE_ROW_COUNT, 3); - table.AddIntAttribute(AX_ATTR_TABLE_COLUMN_COUNT, 3); - - // Ordering in this list matters. It is used in the calculation - // of where cells are by the following: - // int position = row * GetTableColumnCount() + column; - - std::vector<int32_t> ids{51, 52, 53, 2, 3, 4, 11, 12, 13}; - table.AddIntListAttribute(AX_ATTR_CELL_IDS, ids); - table.AddIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS, ids); - - table.child_ids.push_back(50); // Header - table.child_ids.push_back(1); // Row 1 - table.child_ids.push_back(10); // Row 2 - - // Table column header - AXNodeData table_row_header; - table_row_header.id = 50; - table_row_header.role = AX_ROLE_ROW; - table_row_header.child_ids.push_back(51); - table_row_header.child_ids.push_back(52); - table_row_header.child_ids.push_back(53); - - AXNodeData table_column_header_1; - table_column_header_1.id = 51; - table_column_header_1.role = AX_ROLE_COLUMN_HEADER; - - AXNodeData table_column_header_2; - table_column_header_2.id = 52; - table_column_header_2.role = AX_ROLE_COLUMN_HEADER; - table_column_header_2.SetName("column header 1"); - - AXNodeData table_column_header_3; - table_column_header_3.id = 53; - table_column_header_3.role = AX_ROLE_COLUMN_HEADER; - // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a - // description - table_column_header_3.AddStringAttribute(AX_ATTR_DESCRIPTION, - "column header 2"); - - // Row 1 - AXNodeData table_row_1; - table_row_1.id = 1; - table_row_1.role = AX_ROLE_ROW; - table_row_1.child_ids.push_back(2); - table_row_1.child_ids.push_back(3); - table_row_1.child_ids.push_back(4); - - AXNodeData table_row_header_1; - table_row_header_1.id = 2; - table_row_header_1.role = AX_ROLE_ROW_HEADER; - table_row_header_1.SetName("row header 1"); - - AXNodeData table_cell_1; - table_cell_1.id = 3; - table_cell_1.role = AX_ROLE_CELL; - table_cell_1.SetName("1"); - - AXNodeData table_cell_2; - table_cell_2.id = 4; - table_cell_2.role = AX_ROLE_CELL; - table_cell_2.SetName("2"); - - // Row 2 - AXNodeData table_row_2; - table_row_2.id = 10; - table_row_2.role = AX_ROLE_ROW; - table_row_2.child_ids.push_back(11); - table_row_2.child_ids.push_back(12); - table_row_2.child_ids.push_back(13); - - AXNodeData table_row_header_2; - table_row_header_2.id = 11; - table_row_header_2.role = AX_ROLE_ROW_HEADER; - // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a - // description - table_row_header_2.AddStringAttribute(AX_ATTR_DESCRIPTION, "row header 2"); - - AXNodeData table_cell_3; - table_cell_3.id = 12; - table_cell_3.role = AX_ROLE_CELL; - table_cell_3.SetName("3"); - - AXNodeData table_cell_4; - table_cell_4.id = 13; - table_cell_4.role = AX_ROLE_CELL; - table_cell_4.SetName("4"); - - AXTreeUpdate update; - update.root_id = table.id; - - // Some of the table testing code will index into |nodes| - // and change the state of the given node. If you reorder - // these, you're going to need to update the tests. - update.nodes.push_back(table); // 0 - - update.nodes.push_back(table_row_header); // 1 - update.nodes.push_back(table_column_header_1); // 2 - update.nodes.push_back(table_column_header_2); // 3 - update.nodes.push_back(table_column_header_3); // 4 - - update.nodes.push_back(table_row_1); // 5 - update.nodes.push_back(table_row_header_1); // 6 - update.nodes.push_back(table_cell_1); // 7 - update.nodes.push_back(table_cell_2); // 8 - - update.nodes.push_back(table_row_2); // 9 - update.nodes.push_back(table_row_header_2); // 10 - update.nodes.push_back(table_cell_3); // 11 - update.nodes.push_back(table_cell_4); // 12 - - return update; - } - - ScopedComPtr<IAccessibleTableCell> GetCellInTable() { - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); - - ScopedComPtr<IAccessibleTable2> table; + ComPtr<IAccessibleTable2> table; root_obj.CopyTo(table.GetAddressOf()); if (!table) - return ScopedComPtr<IAccessibleTableCell>(); + return ComPtr<IAccessibleTableCell>(); - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; table->get_cellAt(1, 1, cell.GetAddressOf()); if (!cell) - return ScopedComPtr<IAccessibleTableCell>(); + return ComPtr<IAccessibleTableCell>(); - ScopedComPtr<IAccessibleTableCell> table_cell; + ComPtr<IAccessibleTableCell> table_cell; cell.CopyTo(table_cell.GetAddressOf()); return table_cell; } - - std::unique_ptr<AXTree> tree_; }; TEST_F(AXPlatformNodeWinTest, TestIAccessibleDetachedObject) { @@ -380,7 +132,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleDetachedObject) { root.SetName("Name"); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ScopedBstr name; EXPECT_EQ(S_OK, root_obj->get_accName(SELF, name.Receive())); EXPECT_STREQ(L"Name", name); @@ -409,7 +161,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleHitTest) { Init(root, node1, node2); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ScopedVariant obj; @@ -430,7 +182,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleName) { root.SetName("Name"); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ScopedBstr name; EXPECT_EQ(S_OK, root_obj->get_accName(SELF, name.Receive())); EXPECT_STREQ(L"Name", name); @@ -447,7 +199,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleDescription) { root.AddStringAttribute(AX_ATTR_DESCRIPTION, "Description"); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ScopedBstr description; EXPECT_EQ(S_OK, root_obj->get_accDescription(SELF, description.Receive())); EXPECT_STREQ(L"Description", description); @@ -464,7 +216,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleValue) { root.AddStringAttribute(AX_ATTR_VALUE, "Value"); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ScopedBstr value; EXPECT_EQ(S_OK, root_obj->get_accValue(SELF, value.Receive())); EXPECT_STREQ(L"Value", value); @@ -481,7 +233,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleShortcut) { root.AddStringAttribute(AX_ATTR_KEY_SHORTCUTS, "Shortcut"); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ScopedBstr shortcut; EXPECT_EQ(S_OK, root_obj->get_accKeyboardShortcut(SELF, shortcut.Receive())); EXPECT_STREQ(L"Shortcut", shortcut); @@ -514,7 +266,7 @@ TEST_F(AXPlatformNodeWinTest, Init(list, list_item_1, list_item_2); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); ScopedVariant selection; @@ -544,7 +296,7 @@ TEST_F(AXPlatformNodeWinTest, Init(list, list_item_1, list_item_2); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); ScopedVariant selection; @@ -583,7 +335,7 @@ TEST_F(AXPlatformNodeWinTest, Init(list, list_item_1, list_item_2, list_item_3); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); ScopedVariant selection; @@ -592,7 +344,7 @@ TEST_F(AXPlatformNodeWinTest, ASSERT_NE(nullptr, selection.ptr()); // Loop through the selections and make sure we have the right ones. - ScopedComPtr<IEnumVARIANT> accessibles; + ComPtr<IEnumVARIANT> accessibles; ASSERT_HRESULT_SUCCEEDED( V_UNKNOWN(selection.ptr()) ->QueryInterface(IID_PPV_ARGS(accessibles.GetAddressOf()))); @@ -604,7 +356,7 @@ TEST_F(AXPlatformNodeWinTest, HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count); EXPECT_EQ(S_OK, hr); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(item.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -619,7 +371,7 @@ TEST_F(AXPlatformNodeWinTest, HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count); EXPECT_EQ(S_OK, hr); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(item.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -639,7 +391,7 @@ TEST_F(AXPlatformNodeWinTest, TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableNothingSelected) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); ScopedVariant selection; @@ -655,7 +407,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableRowOneSelected) { Init(update); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); ScopedVariant selection; @@ -663,7 +415,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableRowOneSelected) { EXPECT_EQ(VT_DISPATCH, selection.type()); ASSERT_NE(nullptr, selection.ptr()); - ScopedComPtr<IAccessible> row; + ComPtr<IAccessible> row; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(selection.ptr()) ->QueryInterface(IID_PPV_ARGS(row.GetAddressOf()))); @@ -684,7 +436,7 @@ TEST_F(AXPlatformNodeWinTest, Init(update); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); ScopedVariant selection; @@ -693,7 +445,7 @@ TEST_F(AXPlatformNodeWinTest, ASSERT_NE(nullptr, selection.ptr()); // Loop through the selections and make sure we have the right ones. - ScopedComPtr<IEnumVARIANT> accessibles; + ComPtr<IEnumVARIANT> accessibles; ASSERT_HRESULT_SUCCEEDED( V_UNKNOWN(selection.ptr()) ->QueryInterface(IID_PPV_ARGS(accessibles.GetAddressOf()))); @@ -705,7 +457,7 @@ TEST_F(AXPlatformNodeWinTest, HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count); EXPECT_EQ(S_OK, hr); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(item.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -720,7 +472,7 @@ TEST_F(AXPlatformNodeWinTest, HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count); EXPECT_EQ(S_OK, hr); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(item.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -745,13 +497,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableCellOneSelected) { Init(update); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); - ScopedComPtr<IDispatch> row2; + ComPtr<IDispatch> row2; ASSERT_HRESULT_SUCCEEDED( root_obj->get_accChild(ScopedVariant(2), row2.GetAddressOf())); - ScopedComPtr<IAccessible> row2_accessible; + ComPtr<IAccessible> row2_accessible; ASSERT_HRESULT_SUCCEEDED(row2.As(&row2_accessible)); ScopedVariant selection; @@ -759,7 +511,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableCellOneSelected) { EXPECT_EQ(VT_DISPATCH, selection.type()); ASSERT_NE(nullptr, selection.ptr()); - ScopedComPtr<IAccessible> cell; + ComPtr<IAccessible> cell; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(selection.ptr()) ->QueryInterface(IID_PPV_ARGS(cell.GetAddressOf()))); @@ -784,13 +536,13 @@ TEST_F(AXPlatformNodeWinTest, Init(update); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); ASSERT_NE(nullptr, root_obj.Get()); - ScopedComPtr<IDispatch> row3; + ComPtr<IDispatch> row3; ASSERT_HRESULT_SUCCEEDED( root_obj->get_accChild(ScopedVariant(3), row3.GetAddressOf())); - ScopedComPtr<IAccessible> row3_accessible; + ComPtr<IAccessible> row3_accessible; ASSERT_HRESULT_SUCCEEDED(row3.As(&row3_accessible)); ScopedVariant selection; @@ -799,7 +551,7 @@ TEST_F(AXPlatformNodeWinTest, ASSERT_NE(nullptr, selection.ptr()); // Loop through the selections and make sure we have the right ones. - ScopedComPtr<IEnumVARIANT> accessibles; + ComPtr<IEnumVARIANT> accessibles; ASSERT_HRESULT_SUCCEEDED( V_UNKNOWN(selection.ptr()) ->QueryInterface(IID_PPV_ARGS(accessibles.GetAddressOf()))); @@ -811,7 +563,7 @@ TEST_F(AXPlatformNodeWinTest, HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count); EXPECT_EQ(S_OK, hr); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(item.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -826,7 +578,7 @@ TEST_F(AXPlatformNodeWinTest, HRESULT hr = accessibles->Next(1, item.Receive(), &retrieved_count); EXPECT_EQ(S_OK, hr); - ScopedComPtr<IAccessible> accessible; + ComPtr<IAccessible> accessible; ASSERT_HRESULT_SUCCEEDED( V_DISPATCH(item.ptr()) ->QueryInterface(IID_PPV_ARGS(accessible.GetAddressOf()))); @@ -853,8 +605,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleRole) { Init(root, child); AXNode* child_node = GetRootNode()->children()[0]; - ScopedComPtr<IAccessible> child_iaccessible( - IAccessibleFromNode(child_node)); + ComPtr<IAccessible> child_iaccessible(IAccessibleFromNode(child_node)); ScopedVariant role; @@ -925,11 +676,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { Init(root, button, checkbox); AXNode* button_node = GetRootNode()->children()[0]; AXNode* checkbox_node = GetRootNode()->children()[1]; - ScopedComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); - ScopedComPtr<IAccessible> button_iaccessible( - IAccessibleFromNode(button_node)); - ScopedComPtr<IAccessible> checkbox_iaccessible( - IAccessibleFromNode(checkbox_node)); + ComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); + ComPtr<IAccessible> button_iaccessible(IAccessibleFromNode(button_node)); + ComPtr<IAccessible> checkbox_iaccessible(IAccessibleFromNode(checkbox_node)); LONG child_count; EXPECT_EQ(S_OK, root_iaccessible->get_accChildCount(&child_count)); @@ -940,14 +689,14 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { EXPECT_EQ(0L, child_count); { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; EXPECT_EQ(S_OK, root_iaccessible->get_accChild(SELF, result.GetAddressOf())); EXPECT_EQ(result.Get(), root_iaccessible.Get()); } { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; ScopedVariant child1(1); EXPECT_EQ(S_OK, root_iaccessible->get_accChild(child1, result.GetAddressOf())); @@ -955,7 +704,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { } { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; ScopedVariant child2(2); EXPECT_EQ(S_OK, root_iaccessible->get_accChild(child2, result.GetAddressOf())); @@ -964,7 +713,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { { // Asking for child id 3 should fail. - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; ScopedVariant child3(3); EXPECT_EQ(E_INVALIDARG, root_iaccessible->get_accChild(child3, result.GetAddressOf())); @@ -972,12 +721,11 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { // We should be able to ask for the button by its unique id too. LONG button_unique_id; - ScopedComPtr<IAccessible2> button_iaccessible2 = - ToIAccessible2(button_iaccessible); + ComPtr<IAccessible2> button_iaccessible2 = ToIAccessible2(button_iaccessible); button_iaccessible2->get_uniqueID(&button_unique_id); ASSERT_LT(button_unique_id, 0); { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; ScopedVariant button_id_variant(button_unique_id); EXPECT_EQ(S_OK, root_iaccessible->get_accChild(button_id_variant, result.GetAddressOf())); @@ -987,12 +735,11 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { // 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); + ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible); root_iaccessible2->get_uniqueID(&root_unique_id); ASSERT_LT(root_unique_id, 0); { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; ScopedVariant root_id_variant(root_unique_id); EXPECT_EQ(E_INVALIDARG, button_iaccessible->get_accChild( root_id_variant, result.GetAddressOf())); @@ -1000,19 +747,19 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) { // Now check parents. { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; EXPECT_EQ(S_OK, button_iaccessible->get_accParent(result.GetAddressOf())); EXPECT_EQ(result.Get(), root_iaccessible.Get()); } { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; EXPECT_EQ(S_OK, checkbox_iaccessible->get_accParent(result.GetAddressOf())); EXPECT_EQ(result.Get(), root_iaccessible.Get()); } { - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; EXPECT_EQ(S_FALSE, root_iaccessible->get_accParent(result.GetAddressOf())); } } @@ -1030,17 +777,14 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2IndexInParent) { right.id = 3; Init(root, left, right); - ScopedComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); - ScopedComPtr<IAccessible2> root_iaccessible2 = - ToIAccessible2(root_iaccessible); - ScopedComPtr<IAccessible> left_iaccessible( + ComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); + ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible); + ComPtr<IAccessible> left_iaccessible( IAccessibleFromNode(GetRootNode()->children()[0])); - ScopedComPtr<IAccessible2> left_iaccessible2 = - ToIAccessible2(left_iaccessible); - ScopedComPtr<IAccessible> right_iaccessible( + ComPtr<IAccessible2> left_iaccessible2 = ToIAccessible2(left_iaccessible); + ComPtr<IAccessible> right_iaccessible( IAccessibleFromNode(GetRootNode()->children()[1])); - ScopedComPtr<IAccessible2> right_iaccessible2 = - ToIAccessible2(right_iaccessible); + ComPtr<IAccessible2> right_iaccessible2 = ToIAccessible2(right_iaccessible); LONG index; EXPECT_EQ(E_FAIL, root_iaccessible2->get_indexInParent(&index)); @@ -1068,18 +812,18 @@ TEST_F(AXPlatformNodeWinTest, TestAccNavigate) { root.child_ids.push_back(3); Init(root, child1, child2); - ScopedComPtr<IAccessible> ia_root(GetRootIAccessible()); - ScopedComPtr<IDispatch> disp_root; + ComPtr<IAccessible> ia_root(GetRootIAccessible()); + ComPtr<IDispatch> disp_root; ASSERT_HRESULT_SUCCEEDED(ia_root.CopyTo(disp_root.GetAddressOf())); ScopedVariant var_root(disp_root.Get()); - ScopedComPtr<IAccessible> ia_child1( + ComPtr<IAccessible> ia_child1( IAccessibleFromNode(GetRootNode()->children()[0])); - ScopedComPtr<IDispatch> disp_child1; + ComPtr<IDispatch> disp_child1; ASSERT_HRESULT_SUCCEEDED(ia_child1.CopyTo(disp_child1.GetAddressOf())); ScopedVariant var_child1(disp_child1.Get()); - ScopedComPtr<IAccessible> ia_child2( + ComPtr<IAccessible> ia_child2( IAccessibleFromNode(GetRootNode()->children()[1])); - ScopedComPtr<IDispatch> disp_child2; + ComPtr<IDispatch> disp_child2; ASSERT_HRESULT_SUCCEEDED(ia_child2.CopyTo(disp_child2.GetAddressOf())); ScopedVariant var_child2(disp_child2.Get()); ScopedVariant end; @@ -1148,9 +892,8 @@ TEST_F(AXPlatformNodeWinTest, TestAccNavigate) { TEST_F(AXPlatformNodeWinTest, TestIAccessible2TextFieldSetSelection) { Init(BuildTextField()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -1171,9 +914,8 @@ TEST_F(AXPlatformNodeWinTest, DISABLED_TestIAccessible2ContentEditableSetSelection) { Init(BuildContentEditable()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> content_editable; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> content_editable; ia2_text_field.CopyTo(content_editable.GetAddressOf()); ASSERT_NE(nullptr, content_editable.Get()); @@ -1190,25 +932,25 @@ TEST_F(AXPlatformNodeWinTest, TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetAccessibilityAt) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); - ScopedComPtr<IUnknown> cell_1; + ComPtr<IUnknown> cell_1; EXPECT_EQ(S_OK, result->get_accessibleAt(1, 1, cell_1.GetAddressOf())); CheckIUnknownHasName(cell_1, L"1"); - ScopedComPtr<IUnknown> cell_2; + ComPtr<IUnknown> cell_2; EXPECT_EQ(S_OK, result->get_accessibleAt(1, 2, cell_2.GetAddressOf())); CheckIUnknownHasName(cell_2, L"2"); - ScopedComPtr<IUnknown> cell_3; + ComPtr<IUnknown> cell_3; EXPECT_EQ(S_OK, result->get_accessibleAt(2, 1, cell_3.GetAddressOf())); CheckIUnknownHasName(cell_3, L"3"); - ScopedComPtr<IUnknown> cell_4; + ComPtr<IUnknown> cell_4; EXPECT_EQ(S_OK, result->get_accessibleAt(2, 2, cell_4.GetAddressOf())); CheckIUnknownHasName(cell_4, L"4"); } @@ -1217,32 +959,32 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetAccessibilityAtOutOfBounds) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); { - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(-1, -1, cell.GetAddressOf())); } { - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(0, 5, cell.GetAddressOf())); } { - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(5, 0, cell.GetAddressOf())); } { - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; EXPECT_EQ(E_INVALIDARG, result->get_accessibleAt(10, 10, cell.GetAddressOf())); } @@ -1262,11 +1004,11 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollToPoint) { Init(root, child1); - ScopedComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); - ScopedComPtr<IDispatch> result; + ComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); + ComPtr<IDispatch> result; EXPECT_EQ(S_OK, root_iaccessible->get_accChild(ScopedVariant(1), result.GetAddressOf())); - ScopedComPtr<IAccessible2> ax_child1; + ComPtr<IAccessible2> ax_child1; EXPECT_EQ(S_OK, result.CopyTo(ax_child1.GetAddressOf())); result.Reset(); @@ -1278,8 +1020,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollToPoint) { EXPECT_EQ(10, width); EXPECT_EQ(10, height); - ScopedComPtr<IAccessible2> root_iaccessible2 = - ToIAccessible2(root_iaccessible); + ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible); EXPECT_EQ(S_OK, root_iaccessible2->scrollToPoint( IA2_COORDTYPE_SCREEN_RELATIVE, 600, 650)); @@ -1315,11 +1056,11 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollTo) { Init(root, child1); - ScopedComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); - ScopedComPtr<IDispatch> result; + ComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); + ComPtr<IDispatch> result; EXPECT_EQ(S_OK, root_iaccessible->get_accChild(ScopedVariant(1), result.GetAddressOf())); - ScopedComPtr<IAccessible2> ax_child1; + ComPtr<IAccessible2> ax_child1; EXPECT_EQ(S_OK, result.CopyTo(ax_child1.GetAddressOf())); result.Reset(); @@ -1331,8 +1072,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollTo) { EXPECT_EQ(10, width); EXPECT_EQ(10, height); - ScopedComPtr<IAccessible2> root_iaccessible2 = - ToIAccessible2(root_iaccessible); + ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible); EXPECT_EQ(S_OK, ax_child1->scrollTo(IA2_SCROLL_TYPE_ANYWHERE)); EXPECT_EQ(S_OK, @@ -1346,9 +1086,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollTo) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetChildIndex) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1374,9 +1114,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetChildIndex) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnDescription) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1402,9 +1142,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnExtentAt) { // tests get_columnExtentAt for (1) and an invalid input. Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1418,9 +1158,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnExtentAt) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnIndex) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1434,9 +1174,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetColumnIndex) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNColumns) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1448,9 +1188,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNColumns) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNRows) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1462,9 +1202,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNRows) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowDescription) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1490,9 +1230,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowExtentAt) { // tests get_rowExtentAt for (1) and an invalid input. Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1506,9 +1246,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowExtentAt) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowIndex) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1522,9 +1262,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowIndex) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowColumnExtentsAtIndex) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1547,20 +1287,20 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetRowColumnExtentsAtIndex) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetCellAt) { Init(Build3X3Table()); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessibleTable2> result; + ComPtr<IAccessibleTable2> result; root_obj.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); { - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; EXPECT_EQ(S_OK, result->get_cellAt(1, 1, cell.GetAddressOf())); CheckIUnknownHasName(cell, L"1"); } { - ScopedComPtr<IUnknown> cell; + ComPtr<IUnknown> cell; EXPECT_EQ(E_INVALIDARG, result->get_cellAt(-1, -1, cell.GetAddressOf())); } } @@ -1568,7 +1308,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetCellAt) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnExtent) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); long column_spanned; @@ -1579,7 +1319,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnExtent) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnHeaderCells) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); IUnknown** cell_accessibles; @@ -1593,7 +1333,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnHeaderCells) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnIndex) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); long index; @@ -1604,7 +1344,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetColumnIndex) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowExtent) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); long rows_spanned; @@ -1615,7 +1355,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowExtent) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowHeaderCells) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); IUnknown** cell_accessibles; @@ -1631,7 +1371,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowHeaderCells) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowIndex) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); long index; @@ -1642,7 +1382,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowIndex) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowColumnExtent) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); long row, column, row_extents, column_extents; @@ -1658,18 +1398,18 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowColumnExtent) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetTable) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); // Check to make sure that this is the right table by checking one cell. - ScopedComPtr<IUnknown> cell_1; + ComPtr<IUnknown> cell_1; EXPECT_EQ(S_OK, result->get_accessibleAt(1, 1, cell_1.GetAddressOf())); CheckIUnknownHasName(cell_1, L"1"); } @@ -1698,20 +1438,19 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetNRelations) { root.child_ids.push_back(3); Init(root, child1, child2); - ScopedComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); - ScopedComPtr<IAccessible2> root_iaccessible2 = - ToIAccessible2(root_iaccessible); + ComPtr<IAccessible> root_iaccessible(GetRootIAccessible()); + ComPtr<IAccessible2> root_iaccessible2 = ToIAccessible2(root_iaccessible); - ScopedComPtr<IDispatch> result; + ComPtr<IDispatch> result; EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(1), result.GetAddressOf())); - ScopedComPtr<IAccessible2> ax_child1; + ComPtr<IAccessible2> ax_child1; EXPECT_EQ(S_OK, result.CopyTo(ax_child1.GetAddressOf())); result.Reset(); EXPECT_EQ(S_OK, root_iaccessible2->get_accChild(ScopedVariant(2), result.GetAddressOf())); - ScopedComPtr<IAccessible2> ax_child2; + ComPtr<IAccessible2> ax_child2; EXPECT_EQ(S_OK, result.CopyTo(ax_child2.GetAddressOf())); result.Reset(); @@ -1722,9 +1461,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetNRelations) { LONG n_relations = 0; LONG n_targets = 0; ScopedBstr relation_type; - ScopedComPtr<IAccessibleRelation> describedby_relation; - ScopedComPtr<IAccessibleRelation> description_for_relation; - ScopedComPtr<IUnknown> target; + ComPtr<IAccessibleRelation> describedby_relation; + ComPtr<IAccessibleRelation> description_for_relation; + ComPtr<IUnknown> target; EXPECT_HRESULT_SUCCEEDED(root_iaccessible2->get_nRelations(&n_relations)); EXPECT_EQ(1, n_relations); @@ -1790,13 +1529,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetNRelations) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedChildrenZero) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1812,13 +1551,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedChildrenOne) { update.nodes[7].AddState(AX_STATE_SELECTED); Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1841,13 +1580,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedChildrenMany) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1859,13 +1598,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedChildrenMany) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedColumnsZero) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1886,13 +1625,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedColumnsOne) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1920,13 +1659,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedColumnsMany) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1938,13 +1677,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedColumnsMany) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedRowsZero) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1965,13 +1704,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedRowsOne) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -1999,13 +1738,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedRowsMany) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2024,13 +1763,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedChildren) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2053,13 +1792,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedChildrenZeroMax) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2078,13 +1817,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsZero) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2108,13 +1847,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsOne) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2146,13 +1885,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsMany) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2169,13 +1908,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsMany) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedRowsZero) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2198,13 +1937,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedRowsOne) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2235,13 +1974,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedRowsMany) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2266,13 +2005,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsColumnSelected) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2302,13 +2041,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsRowSelected) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2338,13 +2077,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsSelected) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable> result; + ComPtr<IAccessibleTable> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2376,13 +2115,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsSelected) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTable2GetSelectedChildrenZero) { Init(Build3X3Table()); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable2> result; + ComPtr<IAccessibleTable2> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2402,13 +2141,13 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTable2GetSelectedChildren) { Init(update); - ScopedComPtr<IAccessibleTableCell> cell = GetCellInTable(); + ComPtr<IAccessibleTableCell> cell = GetCellInTable(); ASSERT_NE(nullptr, cell.Get()); - ScopedComPtr<IUnknown> table; + ComPtr<IUnknown> table; EXPECT_EQ(S_OK, cell->get_table(table.GetAddressOf())); - ScopedComPtr<IAccessibleTable2> result; + ComPtr<IAccessibleTable2> result; table.CopyTo(result.GetAddressOf()); ASSERT_NE(nullptr, result.Get()); @@ -2417,10 +2156,10 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTable2GetSelectedChildren) { EXPECT_EQ(S_OK, result->get_selectedCells(&cell_accessibles, &count)); EXPECT_EQ(2, count); - ScopedComPtr<IUnknown> table_cell_1(cell_accessibles[0]); + ComPtr<IUnknown> table_cell_1(cell_accessibles[0]); CheckIUnknownHasName(table_cell_1, L"1"); - ScopedComPtr<IUnknown> table_cell_4(cell_accessibles[1]); + ComPtr<IUnknown> table_cell_4(cell_accessibles[1]); CheckIUnknownHasName(table_cell_4, L"4"); } @@ -2432,8 +2171,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetGroupPosition) { root.AddIntAttribute(AX_ATTR_POS_IN_SET, 1); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessible2> iaccessible2 = ToIAccessible2(root_obj); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible2> iaccessible2 = ToIAccessible2(root_obj); LONG level, similar, position; EXPECT_EQ(S_OK, iaccessible2->get_groupPosition(&level, &similar, &position)); EXPECT_EQ(1, level); @@ -2450,8 +2189,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetLocalizedExtendedRole) { root.AddStringAttribute(AX_ATTR_ROLE_DESCRIPTION, "extended role"); Init(root); - ScopedComPtr<IAccessible> root_obj(GetRootIAccessible()); - ScopedComPtr<IAccessible2> iaccessible2 = ToIAccessible2(root_obj); + ComPtr<IAccessible> root_obj(GetRootIAccessible()); + ComPtr<IAccessible2> iaccessible2 = ToIAccessible2(root_obj); ScopedBstr role; EXPECT_EQ(S_OK, iaccessible2->get_localizedExtendedRole(role.Receive())); EXPECT_STREQ(L"extended role", role); @@ -2471,10 +2210,10 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextGetNCharacters) { Init(root, node); AXNode* child_node = GetRootNode()->children()[0]; - ScopedComPtr<IAccessible> child_iaccessible(IAccessibleFromNode(child_node)); + ComPtr<IAccessible> child_iaccessible(IAccessibleFromNode(child_node)); ASSERT_NE(nullptr, child_iaccessible.Get()); - ScopedComPtr<IAccessibleText> text; + ComPtr<IAccessibleText> text; child_iaccessible.CopyTo(text.GetAddressOf()); ASSERT_NE(nullptr, text.Get()); @@ -2486,9 +2225,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextGetNCharacters) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldRemoveSelection) { Init(BuildTextFieldWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2509,9 +2247,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextContentEditableRemoveSelection) { Init(BuildTextFieldWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2531,9 +2268,8 @@ TEST_F(AXPlatformNodeWinTest, TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetSelected) { Init(BuildTextFieldWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2553,9 +2289,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetSelected) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetSelectedBackward) { Init(BuildTextFieldWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2569,9 +2304,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetSelectedBackward) { TEST_F(AXPlatformNodeWinTest, TestIAccessibleContentEditabledGetSelected) { Init(BuildContentEditableWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2592,9 +2326,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleContentEditabledGetSelectedBackward) { Init(BuildContentEditableWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2607,9 +2340,8 @@ TEST_F(AXPlatformNodeWinTest, TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldAddSelection) { Init(BuildTextField()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2633,9 +2365,8 @@ TEST_F(AXPlatformNodeWinTest, DISABLED_TestIAccessibleTextContentEditableAddSelection) { Init(BuildContentEditable()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2655,9 +2386,8 @@ TEST_F(AXPlatformNodeWinTest, TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetNSelectionsZero) { Init(BuildTextField()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2670,9 +2400,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextContentEditableGetNSelectionsZero) { Init(BuildContentEditable()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2684,9 +2413,8 @@ TEST_F(AXPlatformNodeWinTest, TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextContentEditableGetNSelections) { Init(BuildContentEditableWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2699,9 +2427,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetCaretOffsetNoCaret) { Init(BuildTextField()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2714,9 +2441,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextTextFieldGetCaretOffsetHasCaret) { Init(BuildTextFieldWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2729,9 +2455,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextContextEditableGetCaretOffsetNoCaret) { Init(BuildContentEditable()); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); @@ -2744,9 +2469,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextContentEditableGetCaretOffsetHasCaret) { Init(BuildContentEditableWithSelectionRange(1, 2)); - ScopedComPtr<IAccessible2> ia2_text_field = - ToIAccessible2(GetRootIAccessible()); - ScopedComPtr<IAccessibleText> text_field; + ComPtr<IAccessible2> ia2_text_field = ToIAccessible2(GetRootIAccessible()); + ComPtr<IAccessibleText> text_field; ia2_text_field.CopyTo(text_field.GetAddressOf()); ASSERT_NE(nullptr, text_field.Get()); diff --git a/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc b/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc index 4d0bfe41d93..83e083901df 100644 --- a/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc +++ b/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc @@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_enums.h" #include "ui/accessibility/ax_node.h" +#include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/ax_serializable_tree.h" #include "ui/accessibility/platform/ax_android_constants.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -41,15 +42,11 @@ bool HasOnlyTextChildren(const AXNode* node) { // TODO(muyuanli): share with BrowserAccessibility. bool IsSimpleTextControl(const AXNode* node, uint32_t state) { - switch (node->data().role) { - case AX_ROLE_COMBO_BOX: - case AX_ROLE_SEARCH_BOX: - return true; - case AX_ROLE_TEXT_FIELD: - return !node->data().HasState(AX_STATE_RICHLY_EDITABLE); - default: - return false; - } + return (node->data().role == AX_ROLE_TEXT_FIELD || + node->data().role == AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX || + node->data().role == AX_ROLE_SEARCH_BOX || + node->data().HasBoolAttribute(AX_ATTR_EDITABLE_ROOT)) && + !node->data().HasState(AX_STATE_RICHLY_EDITABLE); } bool IsRichTextEditable(const AXNode* node) { @@ -167,7 +164,8 @@ base::string16 GetText(const AXNode* node, bool show_password) { return value; switch (node->data().role) { - case AX_ROLE_COMBO_BOX: + case AX_ROLE_COMBO_BOX_MENU_BUTTON: + case AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX: case AX_ROLE_POP_UP_BUTTON: case AX_ROLE_TEXT_FIELD: return value; @@ -270,7 +268,7 @@ AX_EXPORT AXSnapshotNodeAndroid::~AXSnapshotNodeAndroid() = default; AX_EXPORT std::unique_ptr<AXSnapshotNodeAndroid> AXSnapshotNodeAndroid::Create( const AXTreeUpdate& update, bool show_password) { - auto tree = base::MakeUnique<AXSerializableTree>(); + auto tree = std::make_unique<AXSerializableTree>(); if (!tree->Unserialize(update)) { LOG(FATAL) << tree->error(); } @@ -317,11 +315,12 @@ AX_EXPORT const char* AXSnapshotNodeAndroid::AXRoleToAndroidClassName( case AX_ROLE_SEARCH_BOX: case AX_ROLE_SPIN_BUTTON: case AX_ROLE_TEXT_FIELD: + case AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX: return kAXEditTextClassname; case AX_ROLE_SLIDER: return kAXSeekBarClassname; case AX_ROLE_COLOR_WELL: - case AX_ROLE_COMBO_BOX: + case AX_ROLE_COMBO_BOX_MENU_BUTTON: case AX_ROLE_DATE: case AX_ROLE_POP_UP_BUTTON: case AX_ROLE_INPUT_TIME: diff --git a/chromium/ui/accessibility/platform/ax_system_caret_win.cc b/chromium/ui/accessibility/platform/ax_system_caret_win.cc index aaf82cf9e52..53609cac6fc 100644 --- a/chromium/ui/accessibility/platform/ax_system_caret_win.cc +++ b/chromium/ui/accessibility/platform/ax_system_caret_win.cc @@ -25,15 +25,25 @@ AXSystemCaretWin::AXSystemCaretWin(gfx::AcceleratedWidget event_target) // According to MSDN, "Edit" should be the name of the caret object. data_.SetName(L"Edit"); data_.offset_container_id = -1; + + if (event_target_) { + ::NotifyWinEvent(EVENT_OBJECT_CREATE, event_target_, OBJID_CARET, + -data_.id); + } } AXSystemCaretWin::~AXSystemCaretWin() { caret_->Destroy(); - caret_ = nullptr; + // We shouldn't set |caret_| to nullptr because event clients might try to + // retrieve the destroyed object in this stack frame. + if (event_target_) { + ::NotifyWinEvent(EVENT_OBJECT_DESTROY, event_target_, OBJID_CARET, + -data_.id); + } } -base::win::ScopedComPtr<IAccessible> AXSystemCaretWin::GetCaret() const { - base::win::ScopedComPtr<IAccessible> caret_accessible; +Microsoft::WRL::ComPtr<IAccessible> AXSystemCaretWin::GetCaret() const { + Microsoft::WRL::ComPtr<IAccessible> caret_accessible; HRESULT hr = caret_->QueryInterface( IID_IAccessible, reinterpret_cast<void**>(caret_accessible.GetAddressOf())); diff --git a/chromium/ui/accessibility/platform/ax_system_caret_win.h b/chromium/ui/accessibility/platform/ax_system_caret_win.h index 21652b6abf1..4e2d09ae55e 100644 --- a/chromium/ui/accessibility/platform/ax_system_caret_win.h +++ b/chromium/ui/accessibility/platform/ax_system_caret_win.h @@ -6,9 +6,9 @@ #define UI_ACCESSIBILITY_PLATFORM_AX_SYSTEM_CARET_WIN_H_ #include <oleacc.h> +#include <wrl/client.h> #include "base/macros.h" -#include "base/win/scoped_comptr.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_tree_data.h" @@ -29,7 +29,7 @@ class AX_EXPORT AXSystemCaretWin : private AXPlatformNodeDelegate { explicit AXSystemCaretWin(gfx::AcceleratedWidget event_target); virtual ~AXSystemCaretWin(); - base::win::ScopedComPtr<IAccessible> GetCaret() const; + Microsoft::WRL::ComPtr<IAccessible> GetCaret() const; void MoveCaretTo(const gfx::Rect& bounds); private: |