Chromium Code Reviews| Index: ui/accessibility/platform/atk_util_auralinux.cc |
| diff --git a/ui/accessibility/platform/atk_util_auralinux.cc b/ui/accessibility/platform/atk_util_auralinux.cc |
| index 7fcaf219351289fe7eba1f670d7a6743a8b40ddc..fc076d278e8d9a83838af2eedbbaea7da70d23d9 100644 |
| --- a/ui/accessibility/platform/atk_util_auralinux.cc |
| +++ b/ui/accessibility/platform/atk_util_auralinux.cc |
| @@ -5,12 +5,21 @@ |
| #include <atk/atk.h> |
| #if defined(USE_GCONF) |
| #include <gconf/gconf-client.h> |
| +#elif defined(USE_DBUS) |
| +#include "dbus/bus.h" |
| +#include "dbus/message.h" |
| +#include "dbus/object_path.h" |
| +#include "dbus/object_proxy.h" |
| #endif |
| #include <glib-2.0/gmodule.h> |
| +#include "base/bind.h" |
| #include "base/files/file_path.h" |
| #include "base/logging.h" |
| #include "base/memory/singleton.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/message_loop/message_loop_proxy.h" |
| +#include "base/threading/thread.h" |
| #include "ui/accessibility/platform/atk_util_auralinux.h" |
| #include "ui/accessibility/platform/ax_platform_node_auralinux.h" |
| @@ -21,37 +30,34 @@ namespace { |
| const char kGnomeAccessibilityEnabledKey[] = |
| "/desktop/gnome/interface/accessibility"; |
| -bool ShouldEnableAccessibility() { |
| - GConfClient* client = gconf_client_get_default(); |
| - if (!client) { |
| - LOG(ERROR) << "gconf_client_get_default failed"; |
| - return false; |
| - } |
| +#elif defined(USE_DBUS) |
| - GError* error = nullptr; |
| - gboolean value = gconf_client_get_bool(client, |
| - kGnomeAccessibilityEnabledKey, |
| - &error); |
| - if (error) { |
| - VLOG(1) << "gconf_client_get_bool failed"; |
| - g_error_free(error); |
| - g_object_unref(client); |
| - return false; |
| - } |
| +const char kServiceName[] = "org.a11y.Bus"; |
| +const char kObjectPath[] = "/org/a11y/bus"; |
| +const char kInterfaceName[] = "org.a11y.Status"; |
| +const char kPropertyName[] = "IsEnabled"; |
| - g_object_unref(client); |
| - return value; |
| -} |
| +#endif |
| -#else // !defined(USE_GCONF) |
| +void accessibilityModuleInit() { |
|
dmazzoni
2015/04/20 16:33:22
AccessibilityModuleInit
|
| + // Try to load libatk-bridge.so. |
| + base::FilePath atk_bridge_path(ATK_LIB_DIR); |
| + atk_bridge_path = atk_bridge_path.Append("gtk-2.0/modules/libatk-bridge.so"); |
| + GModule* bridge = g_module_open(atk_bridge_path.value().c_str(), |
| + static_cast<GModuleFlags>(0)); |
| + if (!bridge) { |
| + VLOG(1) << "Unable to open module " << atk_bridge_path.value(); |
| + return; |
| + } |
| -bool ShouldEnableAccessibility() { |
| - // TODO(k.czech): implement this for non-GNOME desktops. |
| - return false; |
| + // Try to call gnome_accessibility_module_init from libatk-bridge.so. |
| + void (*gnome_accessibility_module_init)(); |
| + if (g_module_symbol(bridge, "gnome_accessibility_module_init", |
| + (gpointer *)&gnome_accessibility_module_init)) { |
| + (*gnome_accessibility_module_init)(); |
| + } |
| } |
| -#endif // defined(USE_GCONF) |
| - |
| } // namespace |
| G_BEGIN_DECLS |
| @@ -143,32 +149,124 @@ AtkUtilAuraLinux::AtkUtilAuraLinux() { |
| // Register our util class. |
| g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE)); |
| - if (!ShouldEnableAccessibility()) { |
| + char* enableAccessibility = getenv("ACCESSIBILITY_ENABLED"); |
|
dmazzoni
2015/04/20 16:33:22
Use enable_accessibility for the variable name.
M
|
| + if (enableAccessibility && atoi(enableAccessibility) == 1) { |
| + accessibilityModuleInit(); |
| + return; |
| + } |
| + |
| + CheckIfAccessibilityIsEnabled(); |
| +} |
| + |
| +AtkUtilAuraLinux::~AtkUtilAuraLinux() { |
| +} |
| + |
| +#if defined(USE_GCONF) || defined(USE_DBUS) |
| + |
| +void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabled() { |
| + isEnabled = false; |
| + |
| + accessibility_init_thread_.reset( |
| + new base::Thread("Accessibility Init Thread")); |
| + base::Thread::Options threadOptions(base::MessageLoop::Type::TYPE_IO, 0); |
|
dmazzoni
2015/04/20 16:33:22
thread_options
|
| + accessibility_init_thread_->StartWithOptions(threadOptions); |
| + accessibility_init_thread_->task_runner()->PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind(&AtkUtilAuraLinux::CheckPlatformAccessibilitySupport, |
| + base::Unretained(this)), |
| + base::Bind(&AtkUtilAuraLinux::OnStopAccessibilityThread, |
| + base::Unretained(this))); |
| +} |
| + |
| +void AtkUtilAuraLinux::OnStopAccessibilityThread() { |
| + accessibility_init_thread_.reset(); |
| + if (!isEnabled) { |
| VLOG(1) << "Will not enable ATK accessibility support."; |
| return; |
| } |
| VLOG(1) << "Enabling ATK accessibility support."; |
| + accessibilityModuleInit(); |
| +} |
| - // Try to load libatk-bridge.so. |
| - base::FilePath atk_bridge_path(ATK_LIB_DIR); |
| - atk_bridge_path = atk_bridge_path.Append("gtk-2.0/modules/libatk-bridge.so"); |
| - GModule* bridge = g_module_open(atk_bridge_path.value().c_str(), |
| - static_cast<GModuleFlags>(0)); |
| - if (!bridge) { |
| - VLOG(1) << "Unable to open module " << atk_bridge_path.value(); |
| +#else |
| + |
| +void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabled() { |
| +} |
| + |
| +void AtkUtilAuraLinux::OnStopAccessibilityThread() { |
| +} |
| + |
| +#endif |
| + |
| +#if defined(USE_GCONF) |
| +void AtkUtilAuraLinux::CheckPlatformAccessibilitySupport() { |
| + DCHECK(accessibility_init_thread_->task_runner()->RunsTasksOnCurrentThread()); |
| + |
| + GConfClient* client = gconf_client_get_default(); |
| + if (!client) { |
| + LOG(ERROR) << "gconf_client_get_default failed"; |
| return; |
| } |
| - // Try to call gnome_accessibility_module_init from libatk-bridge.so. |
| - void (*gnome_accessibility_module_init)(); |
| - if (g_module_symbol(bridge, "gnome_accessibility_module_init", |
| - (gpointer *)&gnome_accessibility_module_init)) { |
| - (*gnome_accessibility_module_init)(); |
| + GError* error = nullptr; |
| + isEnabled = gconf_client_get_bool(client, |
| + kGnomeAccessibilityEnabledKey, |
|
dmazzoni
2015/04/20 16:33:22
indentation
|
| + &error); |
| + |
| + g_object_unref(client); |
| + |
| + if (error) { |
| + VLOG(1) << "gconf_client_get_bool failed"; |
| + g_error_free(error); |
| + return; |
| } |
| } |
| -AtkUtilAuraLinux::~AtkUtilAuraLinux() { |
| +#elif defined(USE_DBUS) |
| + |
| +void AtkUtilAuraLinux::CheckPlatformAccessibilitySupport() { |
| + DCHECK(accessibility_init_thread_->task_runner()->RunsTasksOnCurrentThread()); |
| + |
| + dbus::Bus::Options options; |
| + options.dbus_task_runner = accessibility_init_thread_->task_runner(); |
| + |
| + scoped_refptr<dbus::Bus> dbus(new dbus::Bus(options)); |
| + dbus::ObjectProxy* objectProxy = dbus->GetObjectProxy( |
|
dmazzoni
2015/04/20 16:33:22
object_proxy
|
| + kServiceName, dbus::ObjectPath(kObjectPath)); |
| + |
| + DCHECK(objectProxy); |
| + |
| + dbus::MethodCall methodCall(DBUS_INTERFACE_PROPERTIES, "Get"); |
| + dbus::MessageWriter messageWriter(&methodCall); |
| + messageWriter.AppendString(kInterfaceName); |
| + messageWriter.AppendString(kPropertyName); |
| + |
| + scoped_ptr<dbus::Response> response( |
| + objectProxy->CallMethodAndBlock(&methodCall, |
| + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| + |
| + if (!response) { |
| + LOG(ERROR) << "AtSpi: failed to get " << kPropertyName; |
| + dbus->ShutdownAndBlock(); |
| + return; |
| + } |
| + |
| + dbus::MessageReader reader(response.get()); |
| + if (!reader.PopVariantOfBool(&isEnabled)) { |
| + LOG(ERROR) << "AtSpi: unexpected response"; |
| + dbus->ShutdownAndBlock(); |
| + return; |
| + } |
| + |
| + dbus->ShutdownAndBlock(); |
| } |
| +#else |
| + |
| +void AtkUtilAuraLinux::CheckPlatformAccessibilitySupport() { |
| +} |
| + |
| +#endif |
| + |
| } // namespace ui |