[Linux][A11y] report disabled animations and high contrast accessibility features (flutter/engine#33313)

* FlEngine: add fl_engine_update_accessibility_features()
* FlSettings: add API for high-contrast & animations
* FlEngine: allow passing mock messenger at construction time
* FlSettingsPlugin: report accessibility features
This commit is contained in:
J-P Nurmi 2022-06-27 00:10:55 +02:00 committed by GitHub
parent 1754324d02
commit 514b0a43b8
14 changed files with 294 additions and 15 deletions

View File

@ -73,6 +73,8 @@ G_DEFINE_TYPE_WITH_CODE(
G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
fl_engine_plugin_registry_iface_init))
enum { PROP_0, PROP_BINARY_MESSENGER, PROP_LAST };
// Parse a locale into its components.
static void parse_locale(const gchar* locale,
gchar** language,
@ -351,6 +353,22 @@ static void fl_engine_plugin_registry_iface_init(
iface->get_registrar_for_plugin = fl_engine_get_registrar_for_plugin;
}
static void fl_engine_set_property(GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec) {
FlEngine* self = FL_ENGINE(object);
switch (prop_id) {
case PROP_BINARY_MESSENGER:
g_set_object(&self->binary_messenger,
FL_BINARY_MESSENGER(g_value_get_object(value)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void fl_engine_dispose(GObject* object) {
FlEngine* self = FL_ENGINE(object);
@ -397,6 +415,15 @@ static void fl_engine_dispose(GObject* object) {
static void fl_engine_class_init(FlEngineClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_engine_dispose;
G_OBJECT_CLASS(klass)->set_property = fl_engine_set_property;
g_object_class_install_property(
G_OBJECT_CLASS(klass), PROP_BINARY_MESSENGER,
g_param_spec_object(
"binary-messenger", "messenger", "Binary messenger",
fl_binary_messenger_get_type(),
static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)));
}
static void fl_engine_init(FlEngine* self) {
@ -406,7 +433,6 @@ static void fl_engine_init(FlEngine* self) {
FlutterEngineGetProcAddresses(&self->embedder_api);
self->texture_registrar = fl_texture_registrar_new(self);
self->binary_messenger = fl_binary_messenger_new(self);
}
FlEngine* fl_engine_new(FlDartProject* project, FlRenderer* renderer) {
@ -416,6 +442,7 @@ FlEngine* fl_engine_new(FlDartProject* project, FlRenderer* renderer) {
FlEngine* self = FL_ENGINE(g_object_new(fl_engine_get_type(), nullptr));
self->project = FL_DART_PROJECT(g_object_ref(project));
self->renderer = FL_RENDERER(g_object_ref(renderer));
self->binary_messenger = fl_binary_messenger_new(self);
return self;
}
@ -522,7 +549,7 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
setup_locales(self);
g_autoptr(FlSettings) settings = fl_settings_new();
self->settings_plugin = fl_settings_plugin_new(self->binary_messenger);
self->settings_plugin = fl_settings_plugin_new(self);
fl_settings_plugin_start(self->settings_plugin, settings);
result = self->embedder_api.UpdateSemanticsEnabled(self->engine, TRUE);
@ -844,3 +871,14 @@ G_MODULE_EXPORT FlTextureRegistrar* fl_engine_get_texture_registrar(
g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
return self->texture_registrar;
}
void fl_engine_update_accessibility_features(FlEngine* self, int32_t flags) {
g_return_if_fail(FL_IS_ENGINE(self));
if (self->engine == nullptr) {
return;
}
self->embedder_api.UpdateAccessibilityFeatures(
self->engine, static_cast<FlutterAccessibilityFeature>(flags));
}

View File

@ -327,6 +327,15 @@ gboolean fl_engine_register_external_texture(FlEngine* engine,
gboolean fl_engine_unregister_external_texture(FlEngine* engine,
int64_t texture_id);
/**
* fl_engine_update_accessibility_features:
* @engine: an #FlEngine.
* @flags: the features to enable in the accessibility tree.
*
* Tells the Flutter engine to update the flags on the accessibility tree.
*/
void fl_engine_update_accessibility_features(FlEngine* engine, int32_t flags);
G_END_DECLS
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_PRIVATE_H_

View File

@ -63,6 +63,14 @@ static FlColorScheme fl_gnome_settings_get_color_scheme(FlSettings* settings) {
return color_scheme;
}
static gboolean fl_gnome_settings_get_enable_animations(FlSettings* settings) {
return true;
}
static gboolean fl_gnome_settings_get_high_contrast(FlSettings* settings) {
return false;
}
static gdouble fl_gnome_settings_get_text_scaling_factor(FlSettings* settings) {
FlGnomeSettings* self = FL_GNOME_SETTINGS(settings);
@ -133,6 +141,8 @@ static void fl_gnome_settings_class_init(FlGnomeSettingsClass* klass) {
static void fl_gnome_settings_iface_init(FlSettingsInterface* iface) {
iface->get_clock_format = fl_gnome_settings_get_clock_format;
iface->get_color_scheme = fl_gnome_settings_get_color_scheme;
iface->get_enable_animations = fl_gnome_settings_get_enable_animations;
iface->get_high_contrast = fl_gnome_settings_get_high_contrast;
iface->get_text_scaling_factor = fl_gnome_settings_get_text_scaling_factor;
}

View File

@ -69,6 +69,16 @@ TEST_F(FlGnomeSettingsTest, GtkTheme) {
EXPECT_EQ(fl_settings_get_color_scheme(settings), FL_COLOR_SCHEME_DARK);
}
TEST_F(FlGnomeSettingsTest, EnableAnimations) {
g_autoptr(FlSettings) settings = fl_gnome_settings_new();
EXPECT_TRUE(fl_settings_get_enable_animations(settings));
}
TEST_F(FlGnomeSettingsTest, HighContrast) {
g_autoptr(FlSettings) settings = fl_gnome_settings_new();
EXPECT_FALSE(fl_settings_get_high_contrast(settings));
}
TEST_F(FlGnomeSettingsTest, TextScalingFactor) {
g_autoptr(GSettings) interface_settings =
create_settings("ubuntu-20.04", "org.gnome.desktop.interface");

View File

@ -35,6 +35,14 @@ FlColorScheme fl_settings_get_color_scheme(FlSettings* self) {
return FL_SETTINGS_GET_IFACE(self)->get_color_scheme(self);
}
gboolean fl_settings_get_enable_animations(FlSettings* self) {
return FL_SETTINGS_GET_IFACE(self)->get_enable_animations(self);
}
gboolean fl_settings_get_high_contrast(FlSettings* self) {
return FL_SETTINGS_GET_IFACE(self)->get_high_contrast(self);
}
gdouble fl_settings_get_text_scaling_factor(FlSettings* self) {
return FL_SETTINGS_GET_IFACE(self)->get_text_scaling_factor(self);
}

View File

@ -43,6 +43,8 @@ struct _FlSettingsInterface {
GTypeInterface parent;
FlClockFormat (*get_clock_format)(FlSettings* settings);
FlColorScheme (*get_color_scheme)(FlSettings* settings);
gboolean (*get_enable_animations)(FlSettings* settings);
gboolean (*get_high_contrast)(FlSettings* settings);
gdouble (*get_text_scaling_factor)(FlSettings* settings);
};
@ -79,6 +81,31 @@ FlClockFormat fl_settings_get_clock_format(FlSettings* settings);
*/
FlColorScheme fl_settings_get_color_scheme(FlSettings* settings);
/**
* fl_settings_get_enable_animations:
* @settings: an #FlSettings.
*
* Whether animations should be enabled.
*
* This corresponds to `org.gnome.desktop.interface.enable-animations` in GNOME.
*
* Returns: %TRUE if animations are enabled.
*/
gboolean fl_settings_get_enable_animations(FlSettings* settings);
/**
* fl_settings_get_high_contrast:
* @settings: an #FlSettings.
*
* Whether to use high contrast theme.
*
* This corresponds to `org.gnome.desktop.a11y.interface.high-contrast` in
* GNOME.
*
* Returns: %TRUE if high contrast is used.
*/
gboolean fl_settings_get_high_contrast(FlSettings* settings);
/**
* fl_settings_get_text_scaling_factor:
* @settings: an #FlSettings.

View File

@ -6,7 +6,10 @@
#include <gmodule.h>
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
static constexpr char kChannelName[] = "flutter/settings";
@ -20,7 +23,7 @@ struct _FlSettingsPlugin {
GObject parent_instance;
FlBasicMessageChannel* channel;
FlEngine* engine;
FlSettings* settings;
};
@ -54,6 +57,17 @@ static void update_settings(FlSettingsPlugin* self) {
fl_value_new_string(to_platform_brightness(color_scheme)));
fl_basic_message_channel_send(self->channel, message, nullptr, nullptr,
nullptr);
if (self->engine != nullptr) {
int32_t flags = 0;
if (!fl_settings_get_enable_animations(self->settings)) {
flags |= kFlutterAccessibilityFeatureDisableAnimations;
}
if (fl_settings_get_high_contrast(self->settings)) {
flags |= kFlutterAccessibilityFeatureHighContrast;
}
fl_engine_update_accessibility_features(self->engine, flags);
}
}
static void fl_settings_plugin_dispose(GObject* object) {
@ -62,6 +76,12 @@ static void fl_settings_plugin_dispose(GObject* object) {
g_clear_object(&self->channel);
g_clear_object(&self->settings);
if (self->engine != nullptr) {
g_object_remove_weak_pointer(G_OBJECT(self),
reinterpret_cast<gpointer*>(&(self->engine)));
self->engine = nullptr;
}
G_OBJECT_CLASS(fl_settings_plugin_parent_class)->dispose(object);
}
@ -71,12 +91,17 @@ static void fl_settings_plugin_class_init(FlSettingsPluginClass* klass) {
static void fl_settings_plugin_init(FlSettingsPlugin* self) {}
FlSettingsPlugin* fl_settings_plugin_new(FlBinaryMessenger* messenger) {
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
FlSettingsPlugin* fl_settings_plugin_new(FlEngine* engine) {
g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr);
FlSettingsPlugin* self =
FL_SETTINGS_PLUGIN(g_object_new(fl_settings_plugin_get_type(), nullptr));
self->engine = engine;
g_object_add_weak_pointer(G_OBJECT(self),
reinterpret_cast<gpointer*>(&(self->engine)));
FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(engine);
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
self->channel = fl_basic_message_channel_new(messenger, kChannelName,
FL_MESSAGE_CODEC(codec));

View File

@ -6,7 +6,7 @@
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_SETTINGS_PLUGIN_H_
#include "flutter/shell/platform/linux/fl_settings.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
G_BEGIN_DECLS
@ -25,13 +25,13 @@ G_DECLARE_FINAL_TYPE(FlSettingsPlugin,
/**
* fl_settings_plugin_new:
* @messenger: an #FlBinaryMessenger
* @messenger: an #FlEngine
*
* Creates a new plugin that sends user settings to the Flutter engine.
*
* Returns: a new #FlSettingsPlugin
*/
FlSettingsPlugin* fl_settings_plugin_new(FlBinaryMessenger* messenger);
FlSettingsPlugin* fl_settings_plugin_new(FlEngine* engine);
/**
* fl_settings_plugin_start:

View File

@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "flutter/shell/platform/linux/fl_settings_plugin.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_value.h"
@ -38,7 +41,9 @@ TEST(FlSettingsPluginTest, AlwaysUse24HourFormat) {
::testing::NiceMock<flutter::testing::MockSettings> settings;
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(messenger);
g_autoptr(FlEngine) engine = FL_ENGINE(g_object_new(
fl_engine_get_type(), "binary-messenger", messenger, nullptr));
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(engine);
g_autoptr(FlValue) use_12h = fl_value_new_bool(false);
g_autoptr(FlValue) use_24h = fl_value_new_bool(true);
@ -61,7 +66,9 @@ TEST(FlSettingsPluginTest, PlatformBrightness) {
::testing::NiceMock<flutter::testing::MockSettings> settings;
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(messenger);
g_autoptr(FlEngine) engine = FL_ENGINE(g_object_new(
fl_engine_get_type(), "binary-messenger", messenger, nullptr));
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(engine);
g_autoptr(FlValue) light = fl_value_new_string("light");
g_autoptr(FlValue) dark = fl_value_new_string("dark");
@ -84,7 +91,9 @@ TEST(FlSettingsPluginTest, TextScaleFactor) {
::testing::NiceMock<flutter::testing::MockSettings> settings;
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(messenger);
g_autoptr(FlEngine) engine = FL_ENGINE(g_object_new(
fl_engine_get_type(), "binary-messenger", messenger, nullptr));
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(engine);
g_autoptr(FlValue) one = fl_value_new_float(1.0);
g_autoptr(FlValue) two = fl_value_new_float(2.0);
@ -102,3 +111,57 @@ TEST(FlSettingsPluginTest, TextScaleFactor) {
fl_settings_emit_changed(settings);
}
// MOCK_ENGINE_PROC is leaky by design
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
TEST(FlSettingsPluginTest, AccessibilityFeatures) {
g_autoptr(FlEngine) engine = make_mock_engine();
FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
std::vector<FlutterAccessibilityFeature> calls;
embedder_api->UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
UpdateAccessibilityFeatures,
([&calls](auto engine, FlutterAccessibilityFeature features) {
calls.push_back(features);
return kSuccess;
}));
g_autoptr(FlSettingsPlugin) plugin = fl_settings_plugin_new(engine);
::testing::NiceMock<flutter::testing::MockSettings> settings;
EXPECT_CALL(settings, fl_settings_get_enable_animations(
::testing::Eq<FlSettings*>(settings)))
.WillOnce(::testing::Return(false))
.WillOnce(::testing::Return(true))
.WillOnce(::testing::Return(false))
.WillOnce(::testing::Return(true));
EXPECT_CALL(settings, fl_settings_get_high_contrast(
::testing::Eq<FlSettings*>(settings)))
.WillOnce(::testing::Return(true))
.WillOnce(::testing::Return(false))
.WillOnce(::testing::Return(false))
.WillOnce(::testing::Return(true));
fl_settings_plugin_start(plugin, settings);
EXPECT_THAT(calls, ::testing::SizeIs(1));
EXPECT_EQ(calls.back(), static_cast<FlutterAccessibilityFeature>(
kFlutterAccessibilityFeatureDisableAnimations |
kFlutterAccessibilityFeatureHighContrast));
fl_settings_emit_changed(settings);
EXPECT_THAT(calls, ::testing::SizeIs(2));
EXPECT_EQ(calls.back(), static_cast<FlutterAccessibilityFeature>(0));
fl_settings_emit_changed(settings);
EXPECT_THAT(calls, ::testing::SizeIs(3));
EXPECT_EQ(calls.back(), static_cast<FlutterAccessibilityFeature>(
kFlutterAccessibilityFeatureDisableAnimations));
fl_settings_emit_changed(settings);
EXPECT_THAT(calls, ::testing::SizeIs(4));
EXPECT_EQ(calls.back(), static_cast<FlutterAccessibilityFeature>(
kFlutterAccessibilityFeatureHighContrast));
}
// NOLINTEND(clang-analyzer-core.StackAddressEscape)

View File

@ -24,12 +24,25 @@ static const FlSetting kColorScheme = {
G_VARIANT_TYPE_UINT32,
};
static constexpr char kGnomeA11yInterface[] =
"org.gnome.desktop.a11y.interface";
static const FlSetting kHighContrast = {
kGnomeA11yInterface,
"high-contrast",
G_VARIANT_TYPE_BOOLEAN,
};
static constexpr char kGnomeDesktopInterface[] = "org.gnome.desktop.interface";
static const FlSetting kClockFormat = {
kGnomeDesktopInterface,
"clock-format",
G_VARIANT_TYPE_STRING,
};
static const FlSetting kEnableAnimations = {
kGnomeDesktopInterface,
"enable-animations",
G_VARIANT_TYPE_BOOLEAN,
};
static const FlSetting kGtkTheme = {
kGnomeDesktopInterface,
"gtk-theme",
@ -42,10 +55,8 @@ static const FlSetting kTextScalingFactor = {
};
static const FlSetting kAllSettings[] = {
kClockFormat,
kColorScheme,
kGtkTheme,
kTextScalingFactor,
kClockFormat, kColorScheme, kEnableAnimations,
kGtkTheme, kHighContrast, kTextScalingFactor,
};
static constexpr char kClockFormat12Hour[] = "12h";
@ -185,6 +196,32 @@ static FlColorScheme fl_settings_portal_get_color_scheme(FlSettings* settings) {
return color_scheme;
}
static gboolean fl_settings_portal_get_enable_animations(FlSettings* settings) {
FlSettingsPortal* self = FL_SETTINGS_PORTAL(settings);
gboolean enable_animations = true;
g_autoptr(GVariant) value = nullptr;
if (get_value(self, &kEnableAnimations, &value)) {
enable_animations = g_variant_get_boolean(value);
}
return enable_animations;
}
static gboolean fl_settings_portal_get_high_contrast(FlSettings* settings) {
FlSettingsPortal* self = FL_SETTINGS_PORTAL(settings);
gboolean high_contrast = false;
g_autoptr(GVariant) value = nullptr;
if (get_value(self, &kHighContrast, &value)) {
high_contrast = g_variant_get_boolean(value);
}
return high_contrast;
}
static gdouble fl_settings_portal_get_text_scaling_factor(
FlSettings* settings) {
FlSettingsPortal* self = FL_SETTINGS_PORTAL(settings);
@ -216,6 +253,8 @@ static void fl_settings_portal_class_init(FlSettingsPortalClass* klass) {
static void fl_settings_portal_iface_init(FlSettingsInterface* iface) {
iface->get_clock_format = fl_settings_portal_get_clock_format;
iface->get_color_scheme = fl_settings_portal_get_color_scheme;
iface->get_enable_animations = fl_settings_portal_get_enable_animations;
iface->get_high_contrast = fl_settings_portal_get_high_contrast;
iface->get_text_scaling_factor = fl_settings_portal_get_text_scaling_factor;
}

View File

@ -97,6 +97,32 @@ TEST(FlSettingsPortalTest, GtkTheme) {
EXPECT_EQ(fl_settings_get_color_scheme(portal), FL_COLOR_SCHEME_LIGHT);
}
TEST(FlSettingsPortalTest, EnableAnimations) {
g_autoptr(GVariantDict) settings = g_variant_dict_new(nullptr);
g_autoptr(FlSettings) portal =
FL_SETTINGS(fl_settings_portal_new_with_values(settings));
EXPECT_TRUE(fl_settings_get_enable_animations(portal));
g_variant_dict_insert_value(settings,
"org.gnome.desktop.interface::enable-animations",
g_variant_new_boolean(false));
EXPECT_FALSE(fl_settings_get_enable_animations(portal));
}
TEST(FlSettingsPortalTest, HighContrast) {
g_autoptr(GVariantDict) settings = g_variant_dict_new(nullptr);
g_autoptr(FlSettings) portal =
FL_SETTINGS(fl_settings_portal_new_with_values(settings));
EXPECT_FALSE(fl_settings_get_high_contrast(portal));
g_variant_dict_insert_value(settings,
"org.gnome.desktop.a11y.interface::high-contrast",
g_variant_new_boolean(true));
EXPECT_TRUE(fl_settings_get_high_contrast(portal));
}
TEST(FlSettingsPortalTest, TextScalingFactor) {
g_autoptr(GVariantDict) settings = g_variant_dict_new(nullptr);

View File

@ -466,6 +466,12 @@ FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(
return kSuccess;
}
FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures(
FLUTTER_API_SYMBOL(FlutterEngine) engine,
FlutterAccessibilityFeature features) {
return kSuccess;
}
FlutterEngineResult FlutterEngineDispatchSemanticsAction(
FLUTTER_API_SYMBOL(FlutterEngine) engine,
uint64_t id,
@ -539,5 +545,7 @@ FlutterEngineResult FlutterEngineGetProcAddresses(
table->MarkExternalTextureFrameAvailable =
&FlutterEngineMarkExternalTextureFrameAvailable;
table->UnregisterExternalTexture = &FlutterEngineUnregisterExternalTexture;
table->UpdateAccessibilityFeatures =
&FlutterEngineUpdateAccessibilityFeatures;
return kSuccess;
}

View File

@ -40,6 +40,16 @@ static FlColorScheme fl_mock_settings_get_color_scheme(FlSettings* settings) {
return self->mock->fl_settings_get_color_scheme(settings);
}
static gboolean fl_mock_settings_get_enable_animations(FlSettings* settings) {
FlMockSettings* self = FL_MOCK_SETTINGS(settings);
return self->mock->fl_settings_get_enable_animations(settings);
}
static gboolean fl_mock_settings_get_high_contrast(FlSettings* settings) {
FlMockSettings* self = FL_MOCK_SETTINGS(settings);
return self->mock->fl_settings_get_high_contrast(settings);
}
static gdouble fl_mock_settings_get_text_scaling_factor(FlSettings* settings) {
FlMockSettings* self = FL_MOCK_SETTINGS(settings);
return self->mock->fl_settings_get_text_scaling_factor(settings);
@ -48,6 +58,8 @@ static gdouble fl_mock_settings_get_text_scaling_factor(FlSettings* settings) {
static void fl_mock_settings_iface_init(FlSettingsInterface* iface) {
iface->get_clock_format = fl_mock_settings_get_clock_format;
iface->get_color_scheme = fl_mock_settings_get_color_scheme;
iface->get_enable_animations = fl_mock_settings_get_enable_animations;
iface->get_high_contrast = fl_mock_settings_get_high_contrast;
iface->get_text_scaling_factor = fl_mock_settings_get_text_scaling_factor;
}

View File

@ -26,6 +26,10 @@ class MockSettings {
MOCK_METHOD1(fl_settings_get_color_scheme,
FlColorScheme(FlSettings* settings));
MOCK_METHOD1(fl_settings_get_enable_animations, bool(FlSettings* settings));
MOCK_METHOD1(fl_settings_get_high_contrast, bool(FlSettings* settings));
MOCK_METHOD1(fl_settings_get_text_scaling_factor,
gdouble(FlSettings* settings));