Commit e6093e9b authored by Martin Robinson's avatar Martin Robinson Committed by Commit Bot

Reland "Fix emission of AtkValue property change signal"

This version adds protected memory support to handle calling ATK methods
dynamically on the CFI bot.

Original change's description:
> Reland "Fix emission of AtkValue property change signal"
>
> This version checks at runtime for atk_value_set_value during testing.
> This should allow the change to work on bots running trusty.
>
> Original commit message:
>
> > The introduction of text-change signals for the omnibox included a
> > regression that prevented the emission of AtkValue property change
> > signals. Fix this error and also add an implementation of
> > atk_value_set_value. The implementation is used in a test to verify the
> > correct behavior.
> >
> > The fix is that we correct the misuse of a logical operator and now
> > always try to emit AtkValue property change events when receiving the
> > kValueChanged event in AXPlatformNodeAuraLinux.

Bug: 1015387
Bug: 1017177
Bug: 1017548

Change-Id: Iadaea4569944ad0a1be0e1211bbce4ed2c4f6935
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1879255Reviewed-by: default avatarTakuto Ikuta <tikuta@chromium.org>
Reviewed-by: default avatarJoanmarie Diggs <jdiggs@igalia.com>
Commit-Queue: Martin Robinson <mrobinson@igalia.com>
Cr-Commit-Position: refs/heads/master@{#710699}
parent dc9525d2
...@@ -764,11 +764,31 @@ void GetMinimumIncrement(AtkValue* atk_value, GValue* value) { ...@@ -764,11 +764,31 @@ void GetMinimumIncrement(AtkValue* atk_value, GValue* value) {
value); value);
} }
#if defined(ATK_212)
void SetValue(AtkValue* atk_value, const double new_value) {
g_return_if_fail(ATK_VALUE(atk_value));
AtkObject* atk_object = ATK_OBJECT(atk_value);
AXPlatformNodeAuraLinux* obj = AtkObjectToAXPlatformNodeAuraLinux(atk_object);
if (!obj)
return;
AXActionData data;
data.action = ax::mojom::Action::kSetValue;
data.value = base::NumberToString(new_value);
obj->GetDelegate()->AccessibilityPerformAction(data);
}
#endif // defined(ATK_212)
void Init(AtkValueIface* iface) { void Init(AtkValueIface* iface) {
iface->get_current_value = GetCurrentValue; iface->get_current_value = GetCurrentValue;
iface->get_maximum_value = GetMaximumValue; iface->get_maximum_value = GetMaximumValue;
iface->get_minimum_value = GetMinimumValue; iface->get_minimum_value = GetMinimumValue;
iface->get_minimum_increment = GetMinimumIncrement; iface->get_minimum_increment = GetMinimumIncrement;
#if defined(ATK_212)
iface->set_value = SetValue;
#endif // defined(ATK_212)
} }
const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init), const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
...@@ -3425,10 +3445,8 @@ void AXPlatformNodeAuraLinux::OnValueChanged() { ...@@ -3425,10 +3445,8 @@ void AXPlatformNodeAuraLinux::OnValueChanged() {
// If this is a non-web-content text entry, then we need to trigger text // If this is a non-web-content text entry, then we need to trigger text
// change signals when the value changes. This is handled by browser // change signals when the value changes. This is handled by browser
// accessibility for web content. // accessibility for web content.
if (IsPlainTextField() || !GetDelegate()->IsWebContent()) { if (IsPlainTextField() && !GetDelegate()->IsWebContent())
UpdateHypertext(); UpdateHypertext();
return;
}
if (!IsRangeValueSupported(GetData())) if (!IsRangeValueSupported(GetData()))
return; return;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "base/memory/protected_memory_cfi.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/platform/ax_platform_node_auralinux.h" #include "ui/accessibility/platform/ax_platform_node_auralinux.h"
#include "ui/accessibility/platform/ax_platform_node_unittest.h" #include "ui/accessibility/platform/ax_platform_node_unittest.h"
...@@ -973,6 +974,71 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumIncrement) { ...@@ -973,6 +974,71 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumIncrement) {
g_object_unref(root_obj); g_object_unref(root_obj);
} }
#if ATK_CHECK_VERSION(2, 12, 0)
typedef bool (*SetValueFunction)(AtkValue* component, double value);
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueChangedSignal) {
// There's a chance we may be compiled with a newer version of ATK and then
// run with an older one, so we need to do a runtime check for this method
// that is available in ATK 2.12 instead of linking directly.
static PROTECTED_MEMORY_SECTION base::ProtectedMemory<SetValueFunction>
g_atk_value_set_value;
static base::ProtectedMemory<SetValueFunction>::Initializer
init_atk_value_set_value(&g_atk_value_set_value,
reinterpret_cast<SetValueFunction>(
dlsym(RTLD_DEFAULT, "atk_value_set_value")));
if (!*g_atk_value_set_value) {
LOG(WARNING) << "Skipping TestAtkValueChangedSignal"
" because ATK version < 2.12 detected.";
return;
}
AXNodeData root;
root.id = 1;
root.role = ax::mojom::Role::kSlider;
root.AddFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, 5.0);
Init(root);
AtkObject* root_object(GetRootAtkObject());
ASSERT_TRUE(ATK_IS_OBJECT(root_object));
ASSERT_TRUE(ATK_IS_VALUE(root_object));
g_object_ref(root_object);
bool saw_value_change = false;
g_signal_connect(
root_object, "property-change::accessible-value",
G_CALLBACK(+[](AtkObject*, void* property, bool* saw_value_change) {
*saw_value_change = true;
}),
&saw_value_change);
base::UnsanitizedCfiCall(g_atk_value_set_value)(ATK_VALUE(root_object), 24.0);
GetRootPlatformNode()->NotifyAccessibilityEvent(
ax::mojom::Event::kValueChanged);
GValue current_value = G_VALUE_INIT;
atk_value_get_current_value(ATK_VALUE(root_object), &current_value);
EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&current_value));
EXPECT_EQ(24.0, g_value_get_float(&current_value));
EXPECT_TRUE(saw_value_change);
saw_value_change = false;
base::UnsanitizedCfiCall(g_atk_value_set_value)(ATK_VALUE(root_object),
100.0);
GetRootPlatformNode()->NotifyAccessibilityEvent(
ax::mojom::Event::kValueChanged);
g_value_unset(&current_value);
atk_value_get_current_value(ATK_VALUE(root_object), &current_value);
EXPECT_EQ(G_TYPE_FLOAT, G_VALUE_TYPE(&current_value));
EXPECT_EQ(100.0, g_value_get_float(&current_value));
EXPECT_TRUE(saw_value_change);
g_value_unset(&current_value);
g_object_unref(root_object);
}
#endif // ATK_CHECK_VERSION(2, 12, 0)
// //
// AtkHyperlinkImpl interface // AtkHyperlinkImpl interface
// //
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment