diff --git a/flutter/shell/platform/tizen/accessibility_settings.cc b/flutter/shell/platform/tizen/accessibility_settings.cc index 442c508..4258dee 100644 --- a/flutter/shell/platform/tizen/accessibility_settings.cc +++ b/flutter/shell/platform/tizen/accessibility_settings.cc @@ -15,23 +15,71 @@ namespace flutter { AccessibilitySettings::AccessibilitySettings(FlutterTizenEngine* engine) - : engine_(engine) { - bool tts_enabled = false; - int ret = system_settings_get_value_bool( - SYSTEM_SETTINGS_KEY_ACCESSIBILITY_TTS, &tts_enabled); - if (ret != SYSTEM_SETTINGS_ERROR_NONE) { - FT_LOG(Error) << "Failed to get value of accessibility tts."; + : engine_(engine), + dbus_is_enabled_(false), + dbus_screen_reader_enabled_(false), + dbus_proxy_(nullptr), + cancellable_(g_cancellable_new()) { + ConnectToA11yBus(); + InitializeHighContrast(); +} + +void AccessibilitySettings::ConnectToA11yBus() { + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, + nullptr, // GDBusInterfaceInfo + "org.a11y.Bus", // name + "/org/a11y/bus", // object path + "org.a11y.Status", // interface + cancellable_, // GCancellable + OnDBusProxyReady, // Callback + this); // GError +} + +void AccessibilitySettings::OnDBusProxyReady(GObject* source_object, + GAsyncResult* res, + gpointer user_data) { + GError* error = nullptr; + auto* self = static_cast(user_data); + + self->dbus_proxy_ = g_dbus_proxy_new_for_bus_finish(res, &error); + if (!self->dbus_proxy_) { + FT_LOG(Error) << "Failed to create GDBusProxy"; + if (error) { + FT_LOG(Error) << error->message; + g_error_free(error); + } + return; } - if (tts_enabled) { - screen_reader_enabled_ = tts_enabled; - engine_->SetSemanticsEnabled(tts_enabled); + self->SetupDBusPropertyMonitoring(); +} + +void AccessibilitySettings::SetupDBusPropertyMonitoring() { + UpdateStateFromProxy("IsEnabled", dbus_is_enabled_); + UpdateStateFromProxy("ScreenReaderEnabled", dbus_screen_reader_enabled_); + UpdateSemanticsState(); + + g_signal_connect_data(dbus_proxy_, "g-properties-changed", + G_CALLBACK(OnDBusPropertiesChanged), this, nullptr, + G_CONNECT_AFTER); +} + +void AccessibilitySettings::UpdateStateFromProxy(const char* property_name, + bool& property_state) { + GVariant* result = + g_dbus_proxy_get_cached_property(dbus_proxy_, property_name); + + if (result) { + property_state = g_variant_get_boolean(result); + g_variant_unref(result); + } else { + FT_LOG(Error) << "Failed to get " << property_name << " state."; } - system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_ACCESSIBILITY_TTS, - OnScreenReaderStateChanged, this); +} +void AccessibilitySettings::InitializeHighContrast() { #ifdef TV_PROFILE int high_contrast = 0; - ret = system_settings_get_value_int( + int ret = system_settings_get_value_int( SYSTEM_SETTINGS_KEY_ACCESSIBILITY_HIGHCONTRAST, &high_contrast); if (ret != SYSTEM_SETTINGS_ERROR_NONE) { FT_LOG(Error) << "Failed to get value of accessibility high contrast."; @@ -43,8 +91,33 @@ AccessibilitySettings::AccessibilitySettings(FlutterTizenEngine* engine) #endif } +void AccessibilitySettings::UpdateSemanticsState() { + bool should_enable = dbus_screen_reader_enabled_ || dbus_is_enabled_; + if (should_enable != semantics_enabled_) { + semantics_enabled_ = should_enable; + engine_->SetSemanticsEnabled(should_enable); + FT_LOG(Debug) << "Semantics state updated to: " + << (should_enable ? "enabled" : "disabled") << " (TTS: " + << (dbus_screen_reader_enabled_ ? "enabled" : "disabled") + << ", a11y: " << (dbus_is_enabled_ ? "enabled" : "disabled") + << ")"; + } +} + AccessibilitySettings::~AccessibilitySettings() { system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_ACCESSIBILITY_TTS); + + if (dbus_proxy_) { + g_object_unref(dbus_proxy_); + dbus_proxy_ = nullptr; + } + + if (cancellable_) { + g_cancellable_cancel(cancellable_); + g_object_unref(cancellable_); + cancellable_ = nullptr; + } + #ifdef TV_PROFILE system_settings_unset_changed_cb( SYSTEM_SETTINGS_KEY_ACCESSIBILITY_HIGHCONTRAST); @@ -69,21 +142,38 @@ void AccessibilitySettings::OnHighContrastStateChanged( #endif } -void AccessibilitySettings::OnScreenReaderStateChanged( - system_settings_key_e key, - void* user_data) { +void AccessibilitySettings::OnDBusPropertiesChanged( + GDBusProxy* proxy, + GVariant* changed_properties, + const gchar* const* invalidated_properties, + gpointer user_data) { auto* self = static_cast(user_data); + bool is_changed = false; - bool enabled = false; - int ret = system_settings_get_value_bool(key, &enabled); - if (ret != SYSTEM_SETTINGS_ERROR_NONE) { - FT_LOG(Error) << "Failed to get value of accessibility tts."; - return; + GVariant* is_enabled = g_variant_lookup_value(changed_properties, "IsEnabled", + G_VARIANT_TYPE_BOOLEAN); + if (is_enabled) { + bool old_dbus_is_enabled = self->dbus_is_enabled_; + self->dbus_is_enabled_ = g_variant_get_boolean(is_enabled); + if (old_dbus_is_enabled != self->dbus_is_enabled_) { + is_changed = true; + } + g_variant_unref(is_enabled); + } + + GVariant* tts_enabled = g_variant_lookup_value( + changed_properties, "ScreenReaderEnabled", G_VARIANT_TYPE_BOOLEAN); + if (tts_enabled) { + bool old_dbus_screen_reader_enabled = self->dbus_screen_reader_enabled_; + self->dbus_screen_reader_enabled_ = g_variant_get_boolean(tts_enabled); + if (old_dbus_screen_reader_enabled != self->dbus_screen_reader_enabled_) { + is_changed = true; + } + g_variant_unref(tts_enabled); } - if (enabled != self->screen_reader_enabled_) { - self->screen_reader_enabled_ = enabled; - self->engine_->SetSemanticsEnabled(enabled); + if (is_changed) { + self->UpdateSemanticsState(); } } diff --git a/flutter/shell/platform/tizen/accessibility_settings.h b/flutter/shell/platform/tizen/accessibility_settings.h index f986f91..7a208fd 100644 --- a/flutter/shell/platform/tizen/accessibility_settings.h +++ b/flutter/shell/platform/tizen/accessibility_settings.h @@ -5,6 +5,7 @@ #ifndef EMBEDDER_ACCESSIBILITY_SETTINGS_H_ #define EMBEDDER_ACCESSIBILITY_SETTINGS_H_ +#include #include namespace flutter { @@ -17,13 +18,29 @@ class AccessibilitySettings { virtual ~AccessibilitySettings(); private: + void UpdateSemanticsState(); + void ConnectToA11yBus(); + void InitializeHighContrast(); + void SetupDBusPropertyMonitoring(); + void UpdateStateFromProxy(const char* property_name, bool& property_state); + + static void OnDBusProxyReady(GObject* source_object, + GAsyncResult* res, + gpointer user_data); static void OnHighContrastStateChanged(system_settings_key_e key, void* user_data); - static void OnScreenReaderStateChanged(system_settings_key_e key, - void* user_data); + static void OnDBusPropertiesChanged( + GDBusProxy* proxy, + GVariant* changed_properties, + const gchar* const* invalidated_properties, + gpointer user_data); [[maybe_unused]] FlutterTizenEngine* engine_; - [[maybe_unused]] bool screen_reader_enabled_ = false; + bool semantics_enabled_ = false; + bool dbus_is_enabled_ = false; + bool dbus_screen_reader_enabled_ = false; + GDBusProxy* dbus_proxy_ = nullptr; + GCancellable* cancellable_ = nullptr; }; } // namespace flutter