Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[GTK][a11y] Connect UI process a11y tree with the web process when bu…
…ilding with ATSPI

https://bugs.webkit.org/show_bug.cgi?id=230255

Reviewed by Adrian Perez de Castro.

Source/WebCore:

Add AccessibilityAtspi class to connect to the ATSPI DBus service using the address provided. Also add
AccessibilityRootAtspi class that will be the parent object of the accessibility root wrapper, and the children
of the UI process web view. In ATK the AtkSocket and AtkPlug use a private DBus message to send the unique name
of the UI process connection to the web process. That's not possible with GDBus, so we wait for the first
GetState message to be received (which is called right after atk_socket_embed() is called in the UI process) to
get the unique name of the UI process connection. PlatformDisplay has now API to get the DBus address of the
ATSPI service. This is used only in the UI process that sends the address to the web process, so that we don't
need to get it on every web process again.

* PlatformGTK.cmake:
* SourcesGTK.txt:
* accessibility/atspi/AccessibilityAtspi.cpp: Added.
(WebCore::AccessibilityAtspi::AccessibilityAtspi):
(WebCore::AccessibilityAtspi::uniqueName const):
(WebCore::AccessibilityAtspi::nullReference const):
(WebCore::AccessibilityAtspi::registerRoot):
* accessibility/atspi/AccessibilityAtspi.h: Added.
* accessibility/atspi/AccessibilityRootAtspi.cpp: Added.
(WebCore::AccessibilityRootAtspi::create):
(WebCore::AccessibilityRootAtspi::AccessibilityRootAtspi):
(WebCore::AccessibilityRootAtspi::registerObject):
(WebCore::AccessibilityRootAtspi::setPath):
(WebCore::AccessibilityRootAtspi::setParentPath):
(WebCore::AccessibilityRootAtspi::applicationReference const):
(WebCore::AccessibilityRootAtspi::reference const):
* accessibility/atspi/AccessibilityRootAtspi.h: Added.
(WebCore::AccessibilityRootAtspi::atspi const):
* accessibility/atspi/xml/Accessibility.xml: Added.
* accessibility/atspi/xml/Accessible.xml: Added.
* accessibility/atspi/xml/Action.xml: Added.
* accessibility/atspi/xml/Application.xml: Added.
* accessibility/atspi/xml/Cache.xml: Added.
* accessibility/atspi/xml/Collection.xml: Added.
* accessibility/atspi/xml/Component.xml: Added.
* accessibility/atspi/xml/DeviceEventController.xml: Added.
* accessibility/atspi/xml/DeviceEventListener.xml: Added.
* accessibility/atspi/xml/Document.xml: Added.
* accessibility/atspi/xml/EditableText.xml: Added.
* accessibility/atspi/xml/Event.xml: Added.
* accessibility/atspi/xml/Hyperlink.xml: Added.
* accessibility/atspi/xml/Hypertext.xml: Added.
* accessibility/atspi/xml/Image.xml: Added.
* accessibility/atspi/xml/Registry.xml: Added.
* accessibility/atspi/xml/Selection.xml: Added.
* accessibility/atspi/xml/Socket.xml: Added.
* accessibility/atspi/xml/Table.xml: Added.
* accessibility/atspi/xml/TableCell.xml: Added.
* accessibility/atspi/xml/Text.xml: Added.
* accessibility/atspi/xml/Value.xml: Added.
* platform/graphics/PlatformDisplay.cpp:
(WebCore::PlatformDisplay::createPlatformDisplay):
(WebCore::PlatformDisplay::accessibilityBusAddress const):
* platform/graphics/PlatformDisplay.h:
(WebCore::PlatformDisplay::setAccessibilityBusAddress):
(WebCore::PlatformDisplay::plartformAccessibilityBusAddress const):
* platform/graphics/x11/PlatformDisplayX11.cpp:
(WebCore::PlatformDisplayX11::plartformAccessibilityBusAddress const):
* platform/graphics/x11/PlatformDisplayX11.h:

Source/WebKit:

Change BindAccessibilityTree IPC message API to have an async reply. When using ATSPI the UI process replies to
the message including the object path of the AtkSocket, to be used by the web process root object as its parent
property (building the reference with the UI process unique name we get from GetState message).

* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const): Encode accessibilityBusAddress.
(WebKit::WebProcessCreationParameters::decode): Decode accessibilityBusAddress.
* Shared/WebProcessCreationParameters.h:
* UIProcess/Launcher/glib/BubblewrapLauncher.cpp:
(WebKit::bindA11y): Set the accessibilityBusAddress to the shared PlatformDisplay so that it doesn't need to be
get again.
* UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::~ProvisionalPageProxy):
(WebKit::ProvisionalPageProxy::bindAccessibilityTree):
(WebKit::ProvisionalPageProxy::didReceiveMessage):
* UIProcess/ProvisionalPageProxy.h:
(WebKit::ProvisionalPageProxy::CompletionHandler<void):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::swapToProvisionalPage):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/glib/WebProcessPoolGLib.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess): Set the accessibilityBusAddress parameter.
* UIProcess/gtk/WebPageProxyGtk.cpp:
(WebKit::WebPageProxy::bindAccessibilityTree): Call atk_object_ref_state_set() right after atk_socket_embed() to
make sure that's the first GetState message received by the web process root object. Then build the AtkSocket
path and send the async reply.
* UIProcess/wpe/WebPageProxyWPE.cpp:
(WebKit::WebPageProxy::bindAccessibilityTree):
* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::accessibilityRootObject const):
* WebProcess/WebPage/gtk/WebPageGtk.cpp:
(WebKit::WebPage::platformInitialize): Create the root object and send BindAccessibilityTree to the UI process,
setting the root object parent path using the socket path received from the UI process.
* WebProcess/WebPage/wpe/WebPageWPE.cpp:
(WebKit::WebPage::platformInitialize):
* WebProcess/WebProcess.h:
(WebKit::WebProcess::accessibilityAtspi const):
* WebProcess/glib/WebProcessGLib.cpp:
(WebKit::WebProcess::platformInitializeWebProcess): Create the AccessibilityAtspi instance for the given address.

Canonical link: https://commits.webkit.org/242329@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283304 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
carlosgcampos committed Sep 30, 2021
1 parent f609366 commit e3254ab
Show file tree
Hide file tree
Showing 51 changed files with 1,897 additions and 25 deletions.
66 changes: 66 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,69 @@
2021-09-30 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK][a11y] Connect UI process a11y tree with the web process when building with ATSPI
https://bugs.webkit.org/show_bug.cgi?id=230255

Reviewed by Adrian Perez de Castro.

Add AccessibilityAtspi class to connect to the ATSPI DBus service using the address provided. Also add
AccessibilityRootAtspi class that will be the parent object of the accessibility root wrapper, and the children
of the UI process web view. In ATK the AtkSocket and AtkPlug use a private DBus message to send the unique name
of the UI process connection to the web process. That's not possible with GDBus, so we wait for the first
GetState message to be received (which is called right after atk_socket_embed() is called in the UI process) to
get the unique name of the UI process connection. PlatformDisplay has now API to get the DBus address of the
ATSPI service. This is used only in the UI process that sends the address to the web process, so that we don't
need to get it on every web process again.

* PlatformGTK.cmake:
* SourcesGTK.txt:
* accessibility/atspi/AccessibilityAtspi.cpp: Added.
(WebCore::AccessibilityAtspi::AccessibilityAtspi):
(WebCore::AccessibilityAtspi::uniqueName const):
(WebCore::AccessibilityAtspi::nullReference const):
(WebCore::AccessibilityAtspi::registerRoot):
* accessibility/atspi/AccessibilityAtspi.h: Added.
* accessibility/atspi/AccessibilityRootAtspi.cpp: Added.
(WebCore::AccessibilityRootAtspi::create):
(WebCore::AccessibilityRootAtspi::AccessibilityRootAtspi):
(WebCore::AccessibilityRootAtspi::registerObject):
(WebCore::AccessibilityRootAtspi::setPath):
(WebCore::AccessibilityRootAtspi::setParentPath):
(WebCore::AccessibilityRootAtspi::applicationReference const):
(WebCore::AccessibilityRootAtspi::reference const):
* accessibility/atspi/AccessibilityRootAtspi.h: Added.
(WebCore::AccessibilityRootAtspi::atspi const):
* accessibility/atspi/xml/Accessibility.xml: Added.
* accessibility/atspi/xml/Accessible.xml: Added.
* accessibility/atspi/xml/Action.xml: Added.
* accessibility/atspi/xml/Application.xml: Added.
* accessibility/atspi/xml/Cache.xml: Added.
* accessibility/atspi/xml/Collection.xml: Added.
* accessibility/atspi/xml/Component.xml: Added.
* accessibility/atspi/xml/DeviceEventController.xml: Added.
* accessibility/atspi/xml/DeviceEventListener.xml: Added.
* accessibility/atspi/xml/Document.xml: Added.
* accessibility/atspi/xml/EditableText.xml: Added.
* accessibility/atspi/xml/Event.xml: Added.
* accessibility/atspi/xml/Hyperlink.xml: Added.
* accessibility/atspi/xml/Hypertext.xml: Added.
* accessibility/atspi/xml/Image.xml: Added.
* accessibility/atspi/xml/Registry.xml: Added.
* accessibility/atspi/xml/Selection.xml: Added.
* accessibility/atspi/xml/Socket.xml: Added.
* accessibility/atspi/xml/Table.xml: Added.
* accessibility/atspi/xml/TableCell.xml: Added.
* accessibility/atspi/xml/Text.xml: Added.
* accessibility/atspi/xml/Value.xml: Added.
* platform/graphics/PlatformDisplay.cpp:
(WebCore::PlatformDisplay::createPlatformDisplay):
(WebCore::PlatformDisplay::accessibilityBusAddress const):
* platform/graphics/PlatformDisplay.h:
(WebCore::PlatformDisplay::setAccessibilityBusAddress):
(WebCore::PlatformDisplay::plartformAccessibilityBusAddress const):
* platform/graphics/x11/PlatformDisplayX11.cpp:
(WebCore::PlatformDisplayX11::plartformAccessibilityBusAddress const):
* platform/graphics/x11/PlatformDisplayX11.h:

2021-09-29 Kimmo Kinnunen <kkinnunen@apple.com>

GPUP Cocoa GraphicsContextGLOpenGL should check for ANGLE presence
Expand Down
40 changes: 40 additions & 0 deletions Source/WebCore/PlatformGTK.cmake
Expand Up @@ -54,7 +54,9 @@ if (USE_WPE_RENDERER)
endif ()

list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
accessibility/atspi/AccessibilityAtspi.h
accessibility/atspi/AccessibilityObjectAtspi.h
accessibility/atspi/AccessibilityRootAtspi.h

platform/adwaita/ScrollbarThemeAdwaita.h

Expand Down Expand Up @@ -174,3 +176,41 @@ if (ENABLE_SMOOTH_SCROLLING)
platform/ScrollAnimationSmooth.cpp
)
endif ()

if (USE_ATSPI)
set(WebCore_AtspiInterfaceFiles
${WEBCORE_DIR}/accessibility/atspi/xml/Accessible.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Action.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Application.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Cache.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Collection.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Component.xml
${WEBCORE_DIR}/accessibility/atspi/xml/DeviceEventController.xml
${WEBCORE_DIR}/accessibility/atspi/xml/DeviceEventListener.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Document.xml
${WEBCORE_DIR}/accessibility/atspi/xml/EditableText.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Event.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Hyperlink.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Hypertext.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Image.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Registry.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Selection.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Socket.xml
${WEBCORE_DIR}/accessibility/atspi/xml/TableCell.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Table.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Text.xml
${WEBCORE_DIR}/accessibility/atspi/xml/Value.xml
)

add_custom_command(
OUTPUT ${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.h ${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.c
DEPENDS ${WebCore_AtspiInterfaceFiles}
COMMAND gdbus-codegen --interface-prefix=org.a11y.atspi --c-namespace=webkit --pragma-once --interface-info-header --output=${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.h ${WebCore_AtspiInterfaceFiles}
COMMAND gdbus-codegen --interface-prefix=org.a11y.atspi --c-namespace=webkit --interface-info-body --output=${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.c ${WebCore_AtspiInterfaceFiles}
VERBATIM
)

list(APPEND WebCore_SOURCES
${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.c
)
endif ()
2 changes: 2 additions & 0 deletions Source/WebCore/SourcesGTK.txt
Expand Up @@ -39,7 +39,9 @@ accessibility/atk/WebKitAccessibleInterfaceText.cpp
accessibility/atk/WebKitAccessibleInterfaceValue.cpp
accessibility/atk/WebKitAccessibleUtil.cpp

accessibility/atspi/AccessibilityAtspi.cpp
accessibility/atspi/AccessibilityObjectAtspi.cpp
accessibility/atspi/AccessibilityRootAtspi.cpp
accessibility/atspi/AXObjectCacheAtspi.cpp

accessibility/isolatedtree/atspi/AXIsolatedObjectAtspi.cpp
Expand Down
87 changes: 87 additions & 0 deletions Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2021 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "AccessibilityAtspi.h"

#if ENABLE(ACCESSIBILITY) && USE(ATSPI)
#include "AccessibilityAtspiInterfaces.h"
#include "AccessibilityRootAtspi.h"
#include <gio/gio.h>
#include <glib/gi18n-lib.h>
#include <wtf/MainThread.h>
#include <wtf/UUID.h>
#include <wtf/glib/GUniquePtr.h>

namespace WebCore {

AccessibilityAtspi::AccessibilityAtspi(const String& busAddress)
: m_queue(WorkQueue::create("org.webkit.a11y"))
{
RELEASE_ASSERT(isMainThread());
if (busAddress.isEmpty())
return;
m_queue->dispatch([this, busAddress = busAddress.isolatedCopy()] {
GUniqueOutPtr<GError> error;
m_connection = adoptGRef(g_dbus_connection_new_for_address_sync(busAddress.utf8().data(),
static_cast<GDBusConnectionFlags>(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
nullptr, nullptr, &error.outPtr()));
if (!m_connection)
g_warning("Can't connect to a11y bus: %s", error->message);
});
}

const char* AccessibilityAtspi::uniqueName() const
{
RELEASE_ASSERT(!isMainThread());
return m_connection ? g_dbus_connection_get_unique_name(m_connection.get()) : nullptr;
}

GVariant* AccessibilityAtspi::nullReference() const
{
RELEASE_ASSERT(!isMainThread());
return g_variant_new("(so)", uniqueName(), "/org/a11y/atspi/null");
}

void AccessibilityAtspi::registerRoot(AccessibilityRootAtspi& rootObject, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&& interfaces, CompletionHandler<void(const String&)>&& completionHandler)
{
RELEASE_ASSERT(isMainThread());
m_queue->dispatch([this, rootObject = makeRef(rootObject), interfaces = WTFMove(interfaces), completionHandler = WTFMove(completionHandler)]() mutable {
String reference;
if (m_connection) {
String path = makeString("/org/a11y/webkit/accessible/", createCanonicalUUIDString().replace('-', '_'));
Vector<unsigned, 2> registeredObjects;
registeredObjects.reserveInitialCapacity(interfaces.size());
for (const auto& interface : interfaces) {
auto id = g_dbus_connection_register_object(m_connection.get(), path.utf8().data(), interface.first, interface.second, rootObject.ptr(), nullptr, nullptr);
registeredObjects.uncheckedAppend(id);
}
m_rootObjects.add(rootObject.ptr(), WTFMove(registeredObjects));
reference = makeString(uniqueName(), ':', path);
rootObject->setPath(WTFMove(path));
}
RunLoop::main().dispatch([reference = reference.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
completionHandler(reference);
});
});
}

} // namespace WebCore

#endif // ENABLE(ACCESSIBILITY) && USE(ATSPI)
57 changes: 57 additions & 0 deletions Source/WebCore/accessibility/atspi/AccessibilityAtspi.h
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#pragma once

#if ENABLE(ACCESSIBILITY) && USE(ATSPI)
#include <wtf/CompletionHandler.h>
#include <wtf/FastMalloc.h>
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
#include <wtf/WorkQueue.h>
#include <wtf/glib/GRefPtr.h>

typedef struct _GDBusConnection GDBusConnection;
typedef struct _GDBusInterfaceInfo GDBusInterfaceInfo;
typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;

namespace WebCore {
class AccessibilityObjectAtspi;
class AccessibilityRootAtspi;

class AccessibilityAtspi {
WTF_MAKE_FAST_ALLOCATED;
public:
AccessibilityAtspi(const String&);
~AccessibilityAtspi() = default;

const char* uniqueName() const;
GVariant* nullReference() const;

void registerRoot(AccessibilityRootAtspi&, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&&, CompletionHandler<void(const String&)>&&);

private:
Ref<WorkQueue> m_queue;
GRefPtr<GDBusConnection> m_connection;
HashMap<AccessibilityRootAtspi*, Vector<unsigned, 2>> m_rootObjects;
};

} // namespace WebCore

#endif // ENABLE(ACCESSIBILITY) && USE(ATSPI)
Expand Up @@ -26,7 +26,7 @@
namespace WebCore {
class AXCoreObject;

class AccessibilityObjectAtspi: public ThreadSafeRefCounted<AccessibilityObjectAtspi> {
class AccessibilityObjectAtspi: final public ThreadSafeRefCounted<AccessibilityObjectAtspi> {
public:
static Ref<AccessibilityObjectAtspi> create(AXCoreObject*);
~AccessibilityObjectAtspi() = default;
Expand Down

0 comments on commit e3254ab

Please sign in to comment.