// Copyright 2015 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 #if defined(USE_GCONF) #include #endif #include #include "base/bind.h" #include "base/files/file_path.h" #include "base/location.h" #include "base/logging.h" #include "base/memory/singleton.h" #include "ui/accessibility/platform/atk_util_auralinux.h" #include "ui/accessibility/platform/ax_platform_node_auralinux.h" namespace { typedef void (*gnome_accessibility_module_init)(); const char kAtkBridgePath[] = "gtk-2.0/modules/libatk-bridge.so"; const char kAtkBridgeSymbolName[] = "gnome_accessibility_module_init"; gnome_accessibility_module_init g_accessibility_module_init = nullptr; bool AccessibilityModuleInitOnFileThread() { // 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(0)); if (!bridge) { VLOG(1) << "Unable to open module " << atk_bridge_path.value(); return false; } if (!g_module_symbol(bridge, kAtkBridgeSymbolName, (gpointer *)&g_accessibility_module_init)) { VLOG(1) << "Unable to get symbol pointer from " << atk_bridge_path.value(); // Just to make sure it's null; g_accessibility_module_init = nullptr; return false; } return true; } #if defined(USE_GCONF) const char kAccessibilityEnabled[] = "ACCESSIBILITY_ENABLED"; const char kGnomeAccessibilityEnabledKey[] = "/desktop/gnome/interface/accessibility"; #endif } // namespace G_BEGIN_DECLS // // atk_util_auralinux AtkObject definition and implementation. // #define ATK_UTIL_AURALINUX_TYPE (atk_util_auralinux_get_type()) #define ATK_UTIL_AURALINUX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), \ ATK_UTIL_AURALINUX_TYPE, \ AtkUtilAuraLinux)) #define ATK_UTIL_AURALINUX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), \ ATK_UTIL_AURALINUX_TYPE, \ AtkUtilAuraLinuxClass)) #define IS_ATK_UTIL_AURALINUX(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj), ATK_UTIL_AURALINUX_TYPE)) #define IS_ATK_UTIL_AURALINUX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), ATK_UTIL_AURALINUX_TYPE)) #define ATK_UTIL_AURALINUX_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ ATK_UTIL_AURALINUX_TYPE, \ AtkUtilAuraLinuxClass)) typedef struct _AtkUtilAuraLinux AtkUtilAuraLinux; typedef struct _AtkUtilAuraLinuxClass AtkUtilAuraLinuxClass; struct _AtkUtilAuraLinux { AtkUtil parent; }; struct _AtkUtilAuraLinuxClass { AtkUtilClass parent_class; }; GType atk_util_auralinux_get_type(); G_DEFINE_TYPE(AtkUtilAuraLinux, atk_util_auralinux, ATK_TYPE_UTIL); static void atk_util_auralinux_init(AtkUtilAuraLinux *ax_util) { } static AtkObject* atk_util_auralinux_get_root() { ui::AXPlatformNode* application = ui::AXPlatformNodeAuraLinux::application(); if (application) { return application->GetNativeViewAccessible(); } return nullptr; } static G_CONST_RETURN gchar* atk_util_auralinux_get_toolkit_name(void) { return "Chromium"; } static G_CONST_RETURN gchar* atk_util_auralinux_get_toolkit_version(void) { return "1.0"; } static void atk_util_auralinux_class_init(AtkUtilAuraLinuxClass *klass) { AtkUtilClass *atk_class; gpointer data; data = g_type_class_peek(ATK_TYPE_UTIL); atk_class = ATK_UTIL_CLASS(data); atk_class->get_root = atk_util_auralinux_get_root; atk_class->get_toolkit_name = atk_util_auralinux_get_toolkit_name; atk_class->get_toolkit_version = atk_util_auralinux_get_toolkit_version; } G_END_DECLS // // AtkUtilAuraLinuxClass implementation. // namespace ui { // static AtkUtilAuraLinux* AtkUtilAuraLinux::GetInstance() { return base::Singleton::get(); } #if defined(USE_GCONF) AtkUtilAuraLinux::AtkUtilAuraLinux() : is_enabled_(false) { } #else AtkUtilAuraLinux::AtkUtilAuraLinux() { } #endif // defined(USE_GCONF) void AtkUtilAuraLinux::Initialize( scoped_refptr init_task_runner) { // Register our util class. g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE)); init_task_runner->PostTaskAndReply( FROM_HERE, base::Bind( &AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread, base::Unretained(this)), base::Bind( &AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread, base::Unretained(this))); } AtkUtilAuraLinux::~AtkUtilAuraLinux() { } #if defined(USE_GCONF) void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread() { char* enable_accessibility = getenv(kAccessibilityEnabled); if ((enable_accessibility && atoi(enable_accessibility) == 1) || CheckPlatformAccessibilitySupportOnFileThread()) is_enabled_ = AccessibilityModuleInitOnFileThread(); } bool AtkUtilAuraLinux::CheckPlatformAccessibilitySupportOnFileThread() { GConfClient* client = gconf_client_get_default(); if (!client) { LOG(ERROR) << "gconf_client_get_default failed"; return false; } GError* error = nullptr; bool is_enabled = gconf_client_get_bool(client, kGnomeAccessibilityEnabledKey, &error); g_object_unref(client); if (error) { VLOG(1) << "gconf_client_get_bool failed"; g_error_free(error); return false; } return is_enabled; } void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() { if (!is_enabled_) { VLOG(1) << "Will not enable ATK accessibility support."; return; } DCHECK(g_accessibility_module_init); g_accessibility_module_init(); } #else void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread() { } void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() { } #endif // defined(USE_GCONF) } // namespace ui