summaryrefslogtreecommitdiffstats
path: root/ui/accessibility
diff options
context:
space:
mode:
authork.czech <k.czech@samsung.com>2015-05-06 16:21:48 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-06 23:22:20 +0000
commit16e2d5a386e3ddd5be818a0d27610b1e9ee9c08e (patch)
tree87f429d168a3122677326d5a8b5a284a0770917d /ui/accessibility
parentf324f5095f912fba25ed1d79faaec98424f4c8fd (diff)
downloadchromium_src-16e2d5a386e3ddd5be818a0d27610b1e9ee9c08e.zip
chromium_src-16e2d5a386e3ddd5be818a0d27610b1e9ee9c08e.tar.gz
chromium_src-16e2d5a386e3ddd5be818a0d27610b1e9ee9c08e.tar.bz2
Linux Aura accessibility is enabled only on GNOME desktops
Linux Aura accessibility is not enabled on desktops different than GNOME2. GNOME3 has deprecated gconf in favor of gsettings and dconf. AT-SPI (cross-platform framework that provides communication between AT and application) bus launcher has a property called org.a11y.Bus.IsEnabled that could be easily read by dbus call. In generall this patch adds an additional check to enable accessibility. When gconf is available use gnome's accessibility key otherwise org.a11y.Bus.IsEnabled property. BUG=472183,468989,468112 TBR=stevenjb@chromium.org,jochen@chromium.org Review URL: https://codereview.chromium.org/1028553003 Cr-Commit-Position: refs/heads/master@{#328651}
Diffstat (limited to 'ui/accessibility')
-rw-r--r--ui/accessibility/DEPS1
-rw-r--r--ui/accessibility/accessibility.gyp12
-rw-r--r--ui/accessibility/platform/atk_util_auralinux.cc192
-rw-r--r--ui/accessibility/platform/atk_util_auralinux.h8
4 files changed, 169 insertions, 44 deletions
diff --git a/ui/accessibility/DEPS b/ui/accessibility/DEPS
index fd3b8f0..2b11d60 100644
--- a/ui/accessibility/DEPS
+++ b/ui/accessibility/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+dbus",
"+third_party/iaccessible2",
"+ui/base/win",
"+ui/gfx",
diff --git a/ui/accessibility/accessibility.gyp b/ui/accessibility/accessibility.gyp
index e417f10..aef0f10 100644
--- a/ui/accessibility/accessibility.gyp
+++ b/ui/accessibility/accessibility.gyp
@@ -63,10 +63,20 @@
'../../third_party/iaccessible2/iaccessible2.gyp:iaccessible2'
],
}],
+ ['OS=="linux" and chromeos==0 and use_gconf==1',{
+ 'dependencies': [
+ '../../build/linux/system.gyp:gconf',
+ ],
+ }],
+ ['OS=="linux" and chromeos==0 and use_dbus==1', {
+ 'dependencies': [
+ '../../build/linux/system.gyp:dbus',
+ '../../dbus/dbus.gyp:dbus',
+ ],
+ }],
['OS=="linux" and chromeos==0 and use_x11==1', {
'dependencies': [
'../../build/linux/system.gyp:atk',
- '../../build/linux/system.gyp:gconf',
'../../build/linux/system.gyp:glib',
],
'variables': {
diff --git a/ui/accessibility/platform/atk_util_auralinux.cc b/ui/accessibility/platform/atk_util_auralinux.cc
index 5d25c51..0f770c2 100644
--- a/ui/accessibility/platform/atk_util_auralinux.cc
+++ b/ui/accessibility/platform/atk_util_auralinux.cc
@@ -5,10 +5,17 @@
#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/location.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "ui/accessibility/platform/atk_util_auralinux.h"
@@ -16,41 +23,49 @@
namespace {
-#if defined(USE_GCONF)
+typedef void (*gnome_accessibility_module_init)();
-const char kGnomeAccessibilityEnabledKey[] =
- "/desktop/gnome/interface/accessibility";
+const char kAccessibilityEnabled[] = "ACCESSIBILITY_ENABLED";
+const char kAtkBridgePath[] = "gtk-2.0/modules/libatk-bridge.so";
+const char kAtkBridgeSymbolName[] = "gnome_accessibility_module_init";
-bool ShouldEnableAccessibility() {
- GConfClient* client = gconf_client_get_default();
- if (!client) {
- LOG(ERROR) << "gconf_client_get_default failed";
+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<GModuleFlags>(0));
+ if (!bridge) {
+ VLOG(1) << "Unable to open module " << atk_bridge_path.value();
return false;
}
- 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);
+ 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;
}
- g_object_unref(client);
- return value;
+ return true;
}
-#else // !defined(USE_GCONF)
+#if defined(USE_GCONF)
-bool ShouldEnableAccessibility() {
- // TODO(k.czech): implement this for non-GNOME desktops.
- return false;
-}
+const char kGnomeAccessibilityEnabledKey[] =
+ "/desktop/gnome/interface/accessibility";
-#endif // defined(USE_GCONF)
+#elif defined(USE_DBUS)
+
+const char kServiceName[] = "org.a11y.Bus";
+const char kObjectPath[] = "/org/a11y/bus";
+const char kInterfaceName[] = "org.a11y.Status";
+const char kPropertyName[] = "IsEnabled";
+
+#endif
} // namespace
@@ -139,44 +154,135 @@ AtkUtilAuraLinux* AtkUtilAuraLinux::GetInstance() {
return Singleton<AtkUtilAuraLinux>::get();
}
+#if defined(USE_GCONF) || defined(USE_DBUS)
+
+AtkUtilAuraLinux::AtkUtilAuraLinux()
+ : is_enabled_(false) {
+}
+
+#else
+
AtkUtilAuraLinux::AtkUtilAuraLinux() {
}
+#endif
+
void AtkUtilAuraLinux::Initialize(
scoped_refptr<base::TaskRunner> init_task_runner) {
- // TODO(k.czech): use |init_task_runner| to post a task to do the
- // initialization rather than doing it on this thread.
- // http://crbug.com/468112
// Register our util class.
g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE));
- if (!ShouldEnableAccessibility()) {
- VLOG(1) << "Will not enable ATK accessibility support.";
- return;
+ init_task_runner->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(
+ &AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread,
+ base::Unretained(this)),
+ base::Bind(
+ &AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread,
+ base::Unretained(this)));
+}
+
+AtkUtilAuraLinux::~AtkUtilAuraLinux() {
+}
+
+void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread() {
+ char* enable_accessibility = getenv(kAccessibilityEnabled);
+ if ((enable_accessibility && atoi(enable_accessibility) == 1) ||
+ CheckPlatformAccessibilitySupportOnFileThread())
+ is_enabled_ = AccessibilityModuleInitOnFileThread();
+}
+
+#if defined(USE_GCONF)
+
+bool AtkUtilAuraLinux::CheckPlatformAccessibilitySupportOnFileThread() {
+ GConfClient* client = gconf_client_get_default();
+ if (!client) {
+ LOG(ERROR) << "gconf_client_get_default failed";
+ return false;
}
- VLOG(1) << "Enabling ATK accessibility support.";
+ GError* error = nullptr;
+ bool is_enabled = gconf_client_get_bool(client,
+ kGnomeAccessibilityEnabledKey,
+ &error);
- // 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();
+ g_object_unref(client);
+
+ if (error) {
+ VLOG(1) << "gconf_client_get_bool failed";
+ g_error_free(error);
+ return false;
+ }
+
+ return is_enabled;
+}
+
+#elif defined(USE_DBUS)
+
+bool AtkUtilAuraLinux::CheckPlatformAccessibilitySupportOnFileThread() {
+ dbus::Bus::Options options;
+ scoped_refptr<dbus::Bus> dbus(new dbus::Bus(options));
+ dbus::ObjectProxy* object_proxy = dbus->GetObjectProxy(
+ kServiceName, dbus::ObjectPath(kObjectPath));
+
+ DCHECK(object_proxy);
+
+ dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get");
+ dbus::MessageWriter message_writer(&method_call);
+ message_writer.AppendString(kInterfaceName);
+ message_writer.AppendString(kPropertyName);
+
+ // TODO(k.czech) replace this with asynchronous call
+ scoped_ptr<dbus::Response> response(
+ object_proxy->CallMethodAndBlock(&method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
+
+ if (!response) {
+ LOG(ERROR) << "AtSpi: failed to get " << kPropertyName;
+ dbus->ShutdownAndBlock();
+ return false;
+ }
+
+ // TODO(k.czech) handle case for at-spi2-core version 2.2.0/2.2.2
+ // org.a11y.Bus.Enabled returns variant struct with a bool instead of bool
+ bool is_enabled = false;
+ dbus::MessageReader reader(response.get());
+ if (!reader.PopVariantOfBool(&is_enabled))
+ LOG(ERROR) << "AtSpi: unexpected response";
+
+ dbus->ShutdownAndBlock();
+
+ return is_enabled;
+}
+
+#else
+
+bool AtkUtilAuraLinux::CheckPlatformAccessibilitySupportOnFileThread() {
+ return false;
+}
+
+#endif
+
+#if defined(USE_GCONF) || defined(USE_DBUS)
+
+void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() {
+ if (!is_enabled_) {
+ VLOG(1) << "Will not enable ATK accessibility support.";
return;
}
+ VLOG(1) << "Enabling ATK accessibility support.";
// 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)();
- }
+ DCHECK(g_accessibility_module_init);
+ g_accessibility_module_init();
}
-AtkUtilAuraLinux::~AtkUtilAuraLinux() {
+#else
+
+void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() {
}
+#endif
+
} // namespace ui
diff --git a/ui/accessibility/platform/atk_util_auralinux.h b/ui/accessibility/platform/atk_util_auralinux.h
index 8ecb166..0895b42 100644
--- a/ui/accessibility/platform/atk_util_auralinux.h
+++ b/ui/accessibility/platform/atk_util_auralinux.h
@@ -29,6 +29,14 @@ class AtkUtilAuraLinux {
private:
friend struct DefaultSingletonTraits<AtkUtilAuraLinux>;
+
+ void CheckIfAccessibilityIsEnabledOnFileThread();
+ bool CheckPlatformAccessibilitySupportOnFileThread();
+ void FinishAccessibilityInitOnUIThread();
+
+#if defined(USE_GCONF) || defined(USE_DBUS)
+ bool is_enabled_;
+#endif
};
} // namespace ui