Changeset 283304 in webkit


Ignore:
Timestamp:
Sep 30, 2021 12:37:58 AM (3 years ago)
Author:
Carlos Garcia Campos
Message:

[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.

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.

Location:
trunk/Source
Files:
25 added
25 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r283301 r283304  
     12021-09-30  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][a11y] Connect UI process a11y tree with the web process when building with ATSPI
     4        https://bugs.webkit.org/show_bug.cgi?id=230255
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        Add AccessibilityAtspi class to connect to the ATSPI DBus service using the address provided. Also add
     9        AccessibilityRootAtspi class that will be the parent object of the accessibility root wrapper, and the children
     10        of the UI process web view. In ATK the AtkSocket and AtkPlug use a private DBus message to send the unique name
     11        of the UI process connection to the web process. That's not possible with GDBus, so we wait for the first
     12        GetState message to be received (which is called right after atk_socket_embed() is called in the UI process) to
     13        get the unique name of the UI process connection. PlatformDisplay has now API to get the DBus address of the
     14        ATSPI service. This is used only in the UI process that sends the address to the web process, so that we don't
     15        need to get it on every web process again.
     16
     17        * PlatformGTK.cmake:
     18        * SourcesGTK.txt:
     19        * accessibility/atspi/AccessibilityAtspi.cpp: Added.
     20        (WebCore::AccessibilityAtspi::AccessibilityAtspi):
     21        (WebCore::AccessibilityAtspi::uniqueName const):
     22        (WebCore::AccessibilityAtspi::nullReference const):
     23        (WebCore::AccessibilityAtspi::registerRoot):
     24        * accessibility/atspi/AccessibilityAtspi.h: Added.
     25        * accessibility/atspi/AccessibilityRootAtspi.cpp: Added.
     26        (WebCore::AccessibilityRootAtspi::create):
     27        (WebCore::AccessibilityRootAtspi::AccessibilityRootAtspi):
     28        (WebCore::AccessibilityRootAtspi::registerObject):
     29        (WebCore::AccessibilityRootAtspi::setPath):
     30        (WebCore::AccessibilityRootAtspi::setParentPath):
     31        (WebCore::AccessibilityRootAtspi::applicationReference const):
     32        (WebCore::AccessibilityRootAtspi::reference const):
     33        * accessibility/atspi/AccessibilityRootAtspi.h: Added.
     34        (WebCore::AccessibilityRootAtspi::atspi const):
     35        * accessibility/atspi/xml/Accessibility.xml: Added.
     36        * accessibility/atspi/xml/Accessible.xml: Added.
     37        * accessibility/atspi/xml/Action.xml: Added.
     38        * accessibility/atspi/xml/Application.xml: Added.
     39        * accessibility/atspi/xml/Cache.xml: Added.
     40        * accessibility/atspi/xml/Collection.xml: Added.
     41        * accessibility/atspi/xml/Component.xml: Added.
     42        * accessibility/atspi/xml/DeviceEventController.xml: Added.
     43        * accessibility/atspi/xml/DeviceEventListener.xml: Added.
     44        * accessibility/atspi/xml/Document.xml: Added.
     45        * accessibility/atspi/xml/EditableText.xml: Added.
     46        * accessibility/atspi/xml/Event.xml: Added.
     47        * accessibility/atspi/xml/Hyperlink.xml: Added.
     48        * accessibility/atspi/xml/Hypertext.xml: Added.
     49        * accessibility/atspi/xml/Image.xml: Added.
     50        * accessibility/atspi/xml/Registry.xml: Added.
     51        * accessibility/atspi/xml/Selection.xml: Added.
     52        * accessibility/atspi/xml/Socket.xml: Added.
     53        * accessibility/atspi/xml/Table.xml: Added.
     54        * accessibility/atspi/xml/TableCell.xml: Added.
     55        * accessibility/atspi/xml/Text.xml: Added.
     56        * accessibility/atspi/xml/Value.xml: Added.
     57        * platform/graphics/PlatformDisplay.cpp:
     58        (WebCore::PlatformDisplay::createPlatformDisplay):
     59        (WebCore::PlatformDisplay::accessibilityBusAddress const):
     60        * platform/graphics/PlatformDisplay.h:
     61        (WebCore::PlatformDisplay::setAccessibilityBusAddress):
     62        (WebCore::PlatformDisplay::plartformAccessibilityBusAddress const):
     63        * platform/graphics/x11/PlatformDisplayX11.cpp:
     64        (WebCore::PlatformDisplayX11::plartformAccessibilityBusAddress const):
     65        * platform/graphics/x11/PlatformDisplayX11.h:
     66
    1672021-09-29  Kimmo Kinnunen  <kkinnunen@apple.com>
    268
  • trunk/Source/WebCore/PlatformGTK.cmake

    r282643 r283304  
    5555
    5656list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
     57    accessibility/atspi/AccessibilityAtspi.h
    5758    accessibility/atspi/AccessibilityObjectAtspi.h
     59    accessibility/atspi/AccessibilityRootAtspi.h
    5860
    5961    platform/adwaita/ScrollbarThemeAdwaita.h
     
    175177    )
    176178endif ()
     179
     180if (USE_ATSPI)
     181    set(WebCore_AtspiInterfaceFiles
     182        ${WEBCORE_DIR}/accessibility/atspi/xml/Accessible.xml
     183        ${WEBCORE_DIR}/accessibility/atspi/xml/Action.xml
     184        ${WEBCORE_DIR}/accessibility/atspi/xml/Application.xml
     185        ${WEBCORE_DIR}/accessibility/atspi/xml/Cache.xml
     186        ${WEBCORE_DIR}/accessibility/atspi/xml/Collection.xml
     187        ${WEBCORE_DIR}/accessibility/atspi/xml/Component.xml
     188        ${WEBCORE_DIR}/accessibility/atspi/xml/DeviceEventController.xml
     189        ${WEBCORE_DIR}/accessibility/atspi/xml/DeviceEventListener.xml
     190        ${WEBCORE_DIR}/accessibility/atspi/xml/Document.xml
     191        ${WEBCORE_DIR}/accessibility/atspi/xml/EditableText.xml
     192        ${WEBCORE_DIR}/accessibility/atspi/xml/Event.xml
     193        ${WEBCORE_DIR}/accessibility/atspi/xml/Hyperlink.xml
     194        ${WEBCORE_DIR}/accessibility/atspi/xml/Hypertext.xml
     195        ${WEBCORE_DIR}/accessibility/atspi/xml/Image.xml
     196        ${WEBCORE_DIR}/accessibility/atspi/xml/Registry.xml
     197        ${WEBCORE_DIR}/accessibility/atspi/xml/Selection.xml
     198        ${WEBCORE_DIR}/accessibility/atspi/xml/Socket.xml
     199        ${WEBCORE_DIR}/accessibility/atspi/xml/TableCell.xml
     200        ${WEBCORE_DIR}/accessibility/atspi/xml/Table.xml
     201        ${WEBCORE_DIR}/accessibility/atspi/xml/Text.xml
     202        ${WEBCORE_DIR}/accessibility/atspi/xml/Value.xml
     203    )
     204
     205    add_custom_command(
     206        OUTPUT ${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.h ${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.c
     207        DEPENDS ${WebCore_AtspiInterfaceFiles}
     208        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}
     209        COMMAND gdbus-codegen --interface-prefix=org.a11y.atspi --c-namespace=webkit --interface-info-body --output=${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.c ${WebCore_AtspiInterfaceFiles}
     210        VERBATIM
     211    )
     212
     213    list(APPEND WebCore_SOURCES
     214        ${WebCore_DERIVED_SOURCES_DIR}/AccessibilityAtspiInterfaces.c
     215    )
     216endif ()
  • trunk/Source/WebCore/SourcesGTK.txt

    r282720 r283304  
    4040accessibility/atk/WebKitAccessibleUtil.cpp
    4141
     42accessibility/atspi/AccessibilityAtspi.cpp
    4243accessibility/atspi/AccessibilityObjectAtspi.cpp
     44accessibility/atspi/AccessibilityRootAtspi.cpp
    4345accessibility/atspi/AXObjectCacheAtspi.cpp
    4446
  • trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h

    r283303 r283304  
    2121
    2222#if ENABLE(ACCESSIBILITY) && USE(ATSPI)
    23 #include <wtf/Atomics.h>
    24 #include <wtf/ThreadSafeRefCounted.h>
     23#include <wtf/CompletionHandler.h>
     24#include <wtf/FastMalloc.h>
     25#include <wtf/HashMap.h>
     26#include <wtf/Vector.h>
     27#include <wtf/WorkQueue.h>
     28#include <wtf/glib/GRefPtr.h>
     29
     30typedef struct _GDBusConnection GDBusConnection;
     31typedef struct _GDBusInterfaceInfo GDBusInterfaceInfo;
     32typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
    2533
    2634namespace WebCore {
    27 class AXCoreObject;
     35class AccessibilityObjectAtspi;
     36class AccessibilityRootAtspi;
    2837
    29 class AccessibilityObjectAtspi: public ThreadSafeRefCounted<AccessibilityObjectAtspi> {
     38class AccessibilityAtspi {
     39    WTF_MAKE_FAST_ALLOCATED;
    3040public:
    31     static Ref<AccessibilityObjectAtspi> create(AXCoreObject*);
    32     ~AccessibilityObjectAtspi() = default;
     41    AccessibilityAtspi(const String&);
     42    ~AccessibilityAtspi() = default;
     43
     44    const char* uniqueName() const;
     45    GVariant* nullReference() const;
     46
     47    void registerRoot(AccessibilityRootAtspi&, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&&, CompletionHandler<void(const String&)>&&);
    3348
    3449private:
    35     explicit AccessibilityObjectAtspi(AXCoreObject*);
     50    Ref<WorkQueue> m_queue;
     51    GRefPtr<GDBusConnection> m_connection;
     52    HashMap<AccessibilityRootAtspi*, Vector<unsigned, 2>> m_rootObjects;
    3653};
    3754
  • trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h

    r282643 r283304  
    2727class AXCoreObject;
    2828
    29 class AccessibilityObjectAtspi: public ThreadSafeRefCounted<AccessibilityObjectAtspi> {
     29class AccessibilityObjectAtspi: final public ThreadSafeRefCounted<AccessibilityObjectAtspi> {
    3030public:
    3131    static Ref<AccessibilityObjectAtspi> create(AXCoreObject*);
  • trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h

    r283303 r283304  
    2121
    2222#if ENABLE(ACCESSIBILITY) && USE(ATSPI)
    23 #include <wtf/Atomics.h>
     23#include "AccessibilityAtspi.h"
     24#include <wtf/FastMalloc.h>
    2425#include <wtf/ThreadSafeRefCounted.h>
     26#include <wtf/WeakPtr.h>
     27
     28typedef struct _GVariant GVariant;
    2529
    2630namespace WebCore {
    27 class AXCoreObject;
     31class AccessibilityObjectAtspi;
     32class Page;
    2833
    29 class AccessibilityObjectAtspi: public ThreadSafeRefCounted<AccessibilityObjectAtspi> {
     34class AccessibilityRootAtspi final : public ThreadSafeRefCounted<AccessibilityRootAtspi> {
     35    WTF_MAKE_FAST_ALLOCATED;
    3036public:
    31     static Ref<AccessibilityObjectAtspi> create(AXCoreObject*);
    32     ~AccessibilityObjectAtspi() = default;
     37    static Ref<AccessibilityRootAtspi> create(const Page&, AccessibilityAtspi&);
     38    ~AccessibilityRootAtspi() = default;
     39
     40    void registerObject(CompletionHandler<void(const String&)>&&);
     41    void setPath(String&&);
     42    void setParentPath(String&&);
     43
     44    GVariant* reference() const;
     45    GVariant* applicationReference() const;
     46    AccessibilityAtspi& atspi() const { return m_atspi; }
    3347
    3448private:
    35     explicit AccessibilityObjectAtspi(AXCoreObject*);
     49    AccessibilityRootAtspi(const Page&, AccessibilityAtspi&);
     50
     51    static GDBusInterfaceVTable s_accessibleFunctions;
     52
     53    AccessibilityAtspi& m_atspi;
     54    WeakPtr<Page> m_page;
     55    String m_path;
     56    String m_parentUniqueName;
     57    String m_parentPath;
    3658};
    3759
  • trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp

    r275463 r283304  
    8585#endif
    8686
     87#if USE(ATSPI)
     88#include <wtf/glib/GUniquePtr.h>
     89#endif
     90
    8791namespace WebCore {
    8892
     
    9397        GdkDisplay* display = gdk_display_manager_get_default_display(gdk_display_manager_get());
    9498#if PLATFORM(X11)
    95         if (GDK_IS_X11_DISPLAY(display))
    96             return PlatformDisplayX11::create(GDK_DISPLAY_XDISPLAY(display));
     99        if (GDK_IS_X11_DISPLAY(display)) {
     100            auto platformDisplay = PlatformDisplayX11::create(GDK_DISPLAY_XDISPLAY(display));
     101#if USE(ATSPI) && USE(GTK4)
     102            if (const char* atspiBusAddress = static_cast<const char*>(g_object_get_data(G_OBJECT(display), "-gtk-atspi-bus-address")))
     103                platformDisplay->m_accessibilityBusAddress = String::fromUTF8(atspiBusAddress);
     104#endif
     105            return platformDisplay;
     106        }
    97107#endif
    98108#if PLATFORM(WAYLAND)
    99         if (GDK_IS_WAYLAND_DISPLAY(display))
    100             return PlatformDisplayWayland::create(gdk_wayland_display_get_wl_display(display));
     109        if (GDK_IS_WAYLAND_DISPLAY(display)) {
     110            auto platformDisplay = PlatformDisplayWayland::create(gdk_wayland_display_get_wl_display(display));
     111#if USE(ATSPI) && USE(GTK4)
     112            if (const char* atspiBusAddress = static_cast<const char*>(g_object_get_data(G_OBJECT(display), "-gtk-atspi-bus-address")))
     113                platformDisplay->m_accessibilityBusAddress = String::fromUTF8(atspiBusAddress);
     114#endif
     115            return platformDisplay;
     116        }
    101117#endif
    102118    }
     
    282298#endif
    283299
     300#if USE(ATSPI)
     301const String& PlatformDisplay::accessibilityBusAddress() const
     302{
     303    if (m_accessibilityBusAddress)
     304        return m_accessibilityBusAddress.value();
     305
     306    const char* address = g_getenv("AT_SPI_BUS_ADDRESS");
     307    if (address && *address) {
     308        m_accessibilityBusAddress = String::fromUTF8(address);
     309        return m_accessibilityBusAddress.value();
     310    }
     311
     312    auto platformAddress = plartformAccessibilityBusAddress();
     313    if (!platformAddress.isEmpty()) {
     314        m_accessibilityBusAddress = platformAddress;
     315        return m_accessibilityBusAddress.value();
     316    }
     317
     318    GRefPtr<GDBusConnection> sessionBus = adoptGRef(g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr));
     319    if (sessionBus.get()) {
     320        GRefPtr<GDBusMessage> message = adoptGRef(g_dbus_message_new_method_call("org.a11y.Bus", "/org/a11y/bus", "org.a11y.Bus", "GetAddress"));
     321        g_dbus_message_set_body(message.get(), g_variant_new("()"));
     322        GRefPtr<GDBusMessage> reply = adoptGRef(g_dbus_connection_send_message_with_reply_sync(sessionBus.get(), message.get(),
     323            G_DBUS_SEND_MESSAGE_FLAGS_NONE, 30000, nullptr, nullptr, nullptr));
     324        if (reply) {
     325            GUniqueOutPtr<GError> error;
     326            if (g_dbus_message_to_gerror(reply.get(), &error.outPtr())) {
     327                if (!g_error_matches(error.get(), G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
     328                    WTFLogAlways("Can't find a11y bus: %s", error->message);
     329            } else {
     330                GUniqueOutPtr<char> a11yAddress;
     331                g_variant_get(g_dbus_message_get_body(reply.get()), "(s)", &a11yAddress.outPtr());
     332                m_accessibilityBusAddress = String::fromUTF8(a11yAddress.get());
     333                return m_accessibilityBusAddress.value();
     334            }
     335        }
     336    }
     337
     338    WTFLogAlways("Could not determine the accessibility bus address");
     339    m_accessibilityBusAddress = String();
     340    return m_accessibilityBusAddress.value();
     341}
     342#endif
     343
    284344} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/PlatformDisplay.h

    r274273 r283304  
    2424 */
    2525
    26 #ifndef PlatformDisplay_h
    27 #define PlatformDisplay_h
     26#pragma once
    2827
    2928#include <wtf/Noncopyable.h>
    3029#include <wtf/TypeCasts.h>
     30#include <wtf/text/WTFString.h>
    3131
    3232#if USE(EGL)
     
    9191#endif
    9292
     93#if USE(ATSPI)
     94    void setAccessibilityBusAddress(String&& address) { m_accessibilityBusAddress = WTFMove(address); }
     95    const String& accessibilityBusAddress() const;
     96#endif
     97
    9398protected:
    9499    enum class NativeDisplayOwned { No, Yes };
     
    111116#if USE(LCMS)
    112117    mutable cmsHPROFILE m_iccProfile { nullptr };
     118#endif
     119
     120#if USE(ATSPI)
     121    virtual String plartformAccessibilityBusAddress() const { return { }; }
     122
     123    mutable std::optional<String> m_accessibilityBusAddress;
    113124#endif
    114125
     
    138149    static bool isType(const WebCore::PlatformDisplay& display) { return display.type() == WebCore::PlatformDisplay::Type::DisplayType; } \
    139150SPECIALIZE_TYPE_TRAITS_END()
    140 
    141 #endif // PltformDisplay_h
  • trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.cpp

    r278458 r283304  
    2828
    2929#include "GLContext.h"
     30#include "XErrorTrapper.h"
    3031
    3132#if PLATFORM(X11)
     
    221222#endif
    222223
     224#if USE(ATSPI)
     225String PlatformDisplayX11::plartformAccessibilityBusAddress() const
     226{
     227    Atom atspiBusAtom = XInternAtom(m_display, "AT_SPI_BUS", False);
     228    Atom type;
     229    int format;
     230    unsigned long itemCount, bytesAfter;
     231    unsigned char* data = nullptr;
     232    XErrorTrapper trapper(m_display, XErrorTrapper::Policy::Ignore);
     233    XGetWindowProperty(m_display, RootWindowOfScreen(DefaultScreenOfDisplay(m_display)), atspiBusAtom, 0L, 8192, False, XA_STRING, &type, &format, &itemCount, &bytesAfter, &data);
     234
     235    String atspiBusAddress = String::fromUTF8(reinterpret_cast<char*>(data));
     236    if (data)
     237        XFree(data);
     238
     239    return atspiBusAddress;
     240}
     241#endif
     242
    223243} // namespace WebCore
    224244
  • trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.h

    r278340 r283304  
    6565#endif
    6666
     67#if USE(ATSPI)
     68    String plartformAccessibilityBusAddress() const override;
     69#endif
     70
    6771    ::Display* m_display { nullptr };
    6872    mutable std::optional<bool> m_supportsXComposite;
  • trunk/Source/WebKit/ChangeLog

    r283297 r283304  
     12021-09-30  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][a11y] Connect UI process a11y tree with the web process when building with ATSPI
     4        https://bugs.webkit.org/show_bug.cgi?id=230255
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        Change BindAccessibilityTree IPC message API to have an async reply. When using ATSPI the UI process replies to
     9        the message including the object path of the AtkSocket, to be used by the web process root object as its parent
     10        property (building the reference with the UI process unique name we get from GetState message).
     11
     12        * Shared/WebProcessCreationParameters.cpp:
     13        (WebKit::WebProcessCreationParameters::encode const): Encode accessibilityBusAddress.
     14        (WebKit::WebProcessCreationParameters::decode): Decode accessibilityBusAddress.
     15        * Shared/WebProcessCreationParameters.h:
     16        * UIProcess/Launcher/glib/BubblewrapLauncher.cpp:
     17        (WebKit::bindA11y): Set the accessibilityBusAddress to the shared PlatformDisplay so that it doesn't need to be
     18        get again.
     19        * UIProcess/ProvisionalPageProxy.cpp:
     20        (WebKit::ProvisionalPageProxy::~ProvisionalPageProxy):
     21        (WebKit::ProvisionalPageProxy::bindAccessibilityTree):
     22        (WebKit::ProvisionalPageProxy::didReceiveMessage):
     23        * UIProcess/ProvisionalPageProxy.h:
     24        (WebKit::ProvisionalPageProxy::CompletionHandler<void):
     25        * UIProcess/WebPageProxy.cpp:
     26        (WebKit::WebPageProxy::swapToProvisionalPage):
     27        * UIProcess/WebPageProxy.h:
     28        * UIProcess/WebPageProxy.messages.in:
     29        * UIProcess/glib/WebProcessPoolGLib.cpp:
     30        (WebKit::WebProcessPool::platformInitializeWebProcess): Set the accessibilityBusAddress parameter.
     31        * UIProcess/gtk/WebPageProxyGtk.cpp:
     32        (WebKit::WebPageProxy::bindAccessibilityTree): Call atk_object_ref_state_set() right after atk_socket_embed() to
     33        make sure that's the first GetState message received by the web process root object. Then build the AtkSocket
     34        path and send the async reply.
     35        * UIProcess/wpe/WebPageProxyWPE.cpp:
     36        (WebKit::WebPageProxy::bindAccessibilityTree):
     37        * WebProcess/WebPage/WebPage.h:
     38        (WebKit::WebPage::accessibilityRootObject const):
     39        * WebProcess/WebPage/gtk/WebPageGtk.cpp:
     40        (WebKit::WebPage::platformInitialize): Create the root object and send BindAccessibilityTree to the UI process,
     41        setting the root object parent path using the socket path received from the UI process.
     42        * WebProcess/WebPage/wpe/WebPageWPE.cpp:
     43        (WebKit::WebPage::platformInitialize):
     44        * WebProcess/WebProcess.h:
     45        (WebKit::WebProcess::accessibilityAtspi const):
     46        * WebProcess/glib/WebProcessGLib.cpp:
     47        (WebKit::WebProcess::platformInitializeWebProcess): Create the AccessibilityAtspi instance for the given address.
     48
    1492021-09-29  Ada Chan  <ada.chan@apple.com>
    250
  • trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp

    r282429 r283304  
    215215    encoder << memoryPressureHandlerConfiguration;
    216216#endif
     217
    217218#if USE(GLIB)
    218219    encoder << applicationID;
    219220    encoder << applicationName;
     221#endif
     222
     223#if USE(ATSPI)
     224    encoder << accessibilityBusAddress;
    220225#endif
    221226}
     
    599604#endif
    600605
     606#if USE(ATSPI)
     607    std::optional<String> accessibilityBusAddress;
     608    decoder >> accessibilityBusAddress;
     609    if (!accessibilityBusAddress)
     610        return false;
     611    parameters.accessibilityBusAddress = WTFMove(*accessibilityBusAddress);
     612#endif
     613
    601614    return true;
    602615}
  • trunk/Source/WebKit/Shared/WebProcessCreationParameters.h

    r282429 r283304  
    266266    String applicationName;
    267267#endif
     268
     269#if USE(ATSPI)
     270    String accessibilityBusAddress;
     271#endif
    268272};
    269273
  • trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp

    r282307 r283304  
    515515                g_variant_get(g_dbus_message_get_body(reply.get()), "(s)", &a11yAddress.outPtr());
    516516                proxy.setAddress(a11yAddress.get(), DBusAddressType::Abstract);
     517#if USE(ATSPI)
     518                PlatformDisplay::sharedDisplay().setAccessibilityBusAddress(makeString("unix:path=", proxy.proxyPath().data()));
     519#endif
    517520            }
    518521        }
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp

    r283179 r283304  
    104104ProvisionalPageProxy::~ProvisionalPageProxy()
    105105{
     106#if PLATFORM(GTK) || PLATFORM(WPE)
     107    if (m_accessibilityBindCompletionHandler)
     108        m_accessibilityBindCompletionHandler({ });
     109#endif
     110
    106111    if (!m_wasCommitted) {
    107112        m_page.inspectorController().willDestroyProvisionalPage(*this);
     
    423428
    424429#if PLATFORM(GTK) || PLATFORM(WPE)
    425 void ProvisionalPageProxy::bindAccessibilityTree(const String& plugID)
     430void ProvisionalPageProxy::bindAccessibilityTree(const String& plugID, CompletionHandler<void(String&&)>&& completionHandler)
    426431{
    427432    m_accessibilityPlugID = plugID;
     433    m_accessibilityBindCompletionHandler = WTFMove(completionHandler);
    428434}
    429435#endif
     
    490496#if PLATFORM(GTK) || PLATFORM(WPE)
    491497    if (decoder.messageName() == Messages::WebPageProxy::BindAccessibilityTree::name()) {
    492         IPC::handleMessage<Messages::WebPageProxy::BindAccessibilityTree>(connection, decoder, this, &ProvisionalPageProxy::bindAccessibilityTree);
     498        IPC::handleMessageAsync<Messages::WebPageProxy::BindAccessibilityTree>(connection, decoder, this, &ProvisionalPageProxy::bindAccessibilityTree);
    493499        return;
    494500    }
  • trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h

    r283179 r283304  
    9797#if PLATFORM(GTK) || PLATFORM(WPE)
    9898    const String& accessibilityPlugID() { return m_accessibilityPlugID; }
     99    CompletionHandler<void(String&&)> takeAccessibilityBindCompletionHandler() { return std::exchange(m_accessibilityBindCompletionHandler, nullptr); }
    99100#endif
    100101#if HAVE(VISIBILITY_PROPAGATION_VIEW)
     
    149150#endif
    150151#if PLATFORM(GTK) || PLATFORM(WPE)
    151     void bindAccessibilityTree(const String&);
     152    void bindAccessibilityTree(const String&, CompletionHandler<void(String&&)>&&);
    152153#endif
    153154#if ENABLE(CONTENT_FILTERING)
     
    179180#if PLATFORM(GTK) || PLATFORM(WPE)
    180181    String m_accessibilityPlugID;
     182    CompletionHandler<void(String&&)> m_accessibilityBindCompletionHandler;
    181183#endif
    182184#if PLATFORM(IOS_FAMILY)
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r283179 r283304  
    975975#endif
    976976#if PLATFORM(GTK) || PLATFORM(WPE)
    977     auto accessibilityPlugID = provisionalPage->accessibilityPlugID();
    978     if (!accessibilityPlugID.isEmpty())
    979         bindAccessibilityTree(accessibilityPlugID);
     977    if (auto completionHandler = provisionalPage->takeAccessibilityBindCompletionHandler())
     978        bindAccessibilityTree(provisionalPage->accessibilityPlugID(), WTFMove(completionHandler));
    980979#endif
    981980}
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r283179 r283304  
    22362236
    22372237#if PLATFORM(GTK) || PLATFORM(WPE)
    2238     void bindAccessibilityTree(const String&);
     2238    void bindAccessibilityTree(const String&, CompletionHandler<void(String&&)>&&);
    22392239#endif
    22402240
  • trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r283179 r283304  
    186186#if PLATFORM(GTK) || PLATFORM(WPE)
    187187    # Support for connecting the Accessibility worlds of the UI and the Web processes
    188     BindAccessibilityTree(String plugID)
     188    BindAccessibilityTree(String plugID) -> (String socketPath) Async
    189189
    190190    SetInputMethodState(std::optional<WebKit::InputMethodState> state);
  • trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp

    r282307 r283304  
    115115        parameters.applicationID = g_application_get_application_id(app);
    116116    parameters.applicationName = g_get_application_name();
     117
     118#if USE(ATSPI)
     119    static const char* accessibilityBusAddress = getenv("WEBKIT_A11Y_BUS_ADDRESS");
     120    parameters.accessibilityBusAddress = accessibilityBusAddress ? String::fromUTF8(accessibilityBusAddress) : WebCore::PlatformDisplay::sharedDisplay().accessibilityBusAddress();
     121#endif
    117122}
    118123
  • trunk/Source/WebKit/UIProcess/gtk/WebPageProxyGtk.cpp

    r280077 r283304  
    5050}
    5151
    52 void WebPageProxy::bindAccessibilityTree(const String& plugID)
     52void WebPageProxy::bindAccessibilityTree(const String& plugID, CompletionHandler<void(String&&)>&& completionHandler)
    5353{
    54 #if !USE(GTK4)
     54#if USE(GTK4)
     55    // FIXME: We need a way to override accessible interface of WebView and send the atspi reference to the web process.
     56    RELEASE_ASSERT_NOT_REACHED();
     57#else
    5558    auto* accessible = gtk_widget_get_accessible(viewWidget());
    5659    atk_socket_embed(ATK_SOCKET(accessible), const_cast<char*>(plugID.utf8().data()));
     60#if USE(ATSPI)
     61    // ATK doesn't have API to get the atspi reference of an object, but we know the id is stored
     62    // as an object user data as "spi-dbus-id". To let the web process know about the unique name, we call
     63    // atk_object_ref_state_set() that sends a GetState message to the web process root object.
     64    g_object_unref(atk_object_ref_state_set(accessible));
     65    completionHandler(makeString("/org/a11y/atspi/accessible/", GPOINTER_TO_INT(g_object_get_data(G_OBJECT(accessible), "spi-dbus-id"))));
     66#else
     67    completionHandler({ });
     68#endif
    5769    atk_object_notify_state_change(accessible, ATK_STATE_TRANSIENT, FALSE);
    5870#endif
  • trunk/Source/WebKit/UIProcess/wpe/WebPageProxyWPE.cpp

    r280074 r283304  
    4646}
    4747
    48 void WebPageProxy::bindAccessibilityTree(const String& plugID)
     48void WebPageProxy::bindAccessibilityTree(const String& plugID, CompletionHandler<void(String&&)>&& completionHandler)
    4949{
    5050#if USE(ATK)
     
    5252    atk_socket_embed(ATK_SOCKET(accessible), const_cast<char*>(plugID.utf8().data()));
    5353    atk_object_notify_state_change(accessible, ATK_STATE_TRANSIENT, FALSE);
     54    completionHandler({ });
    5455#endif
    5556}
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r283179 r283304  
    107107#include <wtf/text/WTFString.h>
    108108
    109 #if ENABLE(ACCESSIBILITY) && USE(ATK)
     109#if ENABLE(ACCESSIBILITY)
     110#if USE(ATK)
    110111typedef struct _AtkObject AtkObject;
    111112#include <wtf/glib/GRefPtr.h>
     113#elif USE(ATSPI)
     114#include <WebCore/AccessibilityRootAtspi.h>
     115#endif
    112116#endif
    113117
     
    14891493    void prepareToRunModalJavaScriptDialog();
    14901494
     1495#if USE(ATSPI)
     1496    const WebCore::AccessibilityRootAtspi& accessibilityRootObject() const { return *m_accessibilityRootObject; }
     1497#endif
     1498
    14911499private:
    14921500    WebPage(WebCore::PageIdentifier, WebPageCreationParameters&&);
     
    20162024#endif
    20172025
    2018 #if ENABLE(ACCESSIBILITY) && USE(ATK)
     2026#if ENABLE(ACCESSIBILITY)
     2027#if USE(ATK)
    20192028    GRefPtr<AtkObject> m_accessibilityObject;
     2029#elif USE(ATSPI)
     2030    RefPtr<WebCore::AccessibilityRootAtspi> m_accessibilityRootObject;
     2031#endif
    20202032#endif
    20212033
  • trunk/Source/WebKit/WebProcess/WebPage/gtk/WebPageGtk.cpp

    r282882 r283304  
    5757void WebPage::platformInitialize()
    5858{
    59 #if ENABLE(ACCESSIBILITY) && USE(ATK)
     59#if ENABLE(ACCESSIBILITY)
    6060    // Create the accessible object (the plug) that will serve as the
    6161    // entry point to the Web process, and send a message to the UI
    6262    // process to connect the two worlds through the accessibility
    6363    // object there specifically placed for that purpose (the socket).
     64#if USE(ATK)
    6465    m_accessibilityObject = adoptGRef(webkitWebPageAccessibilityObjectNew(this));
    6566    GUniquePtr<gchar> plugID(atk_plug_get_id(ATK_PLUG(m_accessibilityObject.get())));
    66     send(Messages::WebPageProxy::BindAccessibilityTree(String(plugID.get())));
     67    sendWithAsyncReply(Messages::WebPageProxy::BindAccessibilityTree(String(plugID.get())), [](String&&) { });
     68#elif USE(ATSPI)
     69#if USE(GTK4)
     70    // FIXME: we need a way to connect DOM and app a11y tree in GTK4.
     71#else
     72    if (auto* page = corePage()) {
     73        m_accessibilityRootObject = AccessibilityRootAtspi::create(*page, WebProcess::singleton().accessibilityAtspi());
     74        m_accessibilityRootObject->registerObject([&](const String& plugID) {
     75            // ATK uses a custom DBus message to send the socket path to the AtkPlug object. GDBus doesn't allow
     76            // to send a message that is not defined in the interface, so we use the WebKit IPC to get the socket
     77            // path from the UI process.
     78            sendWithAsyncReply(Messages::WebPageProxy::BindAccessibilityTree(plugID), [&](String&& socketPath) {
     79                m_accessibilityRootObject->setParentPath(WTFMove(socketPath));
     80            });
     81        });
     82    }
     83#endif
     84#endif
    6785#endif
    6886}
  • trunk/Source/WebKit/WebProcess/WebPage/wpe/WebPageWPE.cpp

    r278253 r283304  
    4646    m_accessibilityObject = adoptGRef(webkitWebPageAccessibilityObjectNew(this));
    4747    GUniquePtr<gchar> plugID(atk_plug_get_id(ATK_PLUG(m_accessibilityObject.get())));
    48     send(Messages::WebPageProxy::BindAccessibilityTree(String::fromUTF8(plugID.get())));
     48    sendWithAsyncReply(Messages::WebPageProxy::BindAccessibilityTree(String(plugID.get())), [](String&&) { });
    4949#endif
    5050}
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r283271 r283304  
    7575#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
    7676#include <WebCore/CaptionUserPreferences.h>
     77#endif
     78
     79#if USE(ATSPI)
     80#include <WebCore/AccessibilityAtspi.h>
    7781#endif
    7882
     
    401405#endif
    402406
     407#if USE(ATSPI)
     408    WebCore::AccessibilityAtspi& accessibilityAtspi() const { return *m_accessibility; }
     409#endif
     410
    403411private:
    404412    WebProcess();
     
    775783    std::unique_ptr<SpeechRecognitionRealtimeMediaSourceManager> m_speechRecognitionRealtimeMediaSourceManager;
    776784#endif
     785
     786#if USE(ATSPI)
     787    std::unique_ptr<WebCore::AccessibilityAtspi> m_accessibility;
     788#endif
    777789};
    778790
  • trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp

    r282307 r283304  
    116116    if (!parameters.applicationName.isEmpty())
    117117        WebCore::setApplicationName(parameters.applicationName);
     118
     119#if USE(ATSPI)
     120    m_accessibility = makeUnique<AccessibilityAtspi>(parameters.accessibilityBusAddress);
     121#endif
    118122}
    119123
Note: See TracChangeset for help on using the changeset viewer.