Changeset 256442 in webkit


Ignore:
Timestamp:
Feb 12, 2020 9:31:03 AM (4 years ago)
Author:
Andres Gonzalez
Message:

Support event notifications in IsolatedTree mode.
https://bugs.webkit.org/show_bug.cgi?id=207581

Reviewed by Chris Fleizach.

  • DOM/Render trees notifications are listened to by AXObjectCache and

the corresponding IsolatedTree is updated.

  • The update is now happening for state, value and children change

notifications.

  • AXObjectCache::updateIsolatedTree re-generates the subtree rooted at

the node receiving the notification.

  • Consolidated creation of AXIsolatedObjects by passing treeID and

parentID to the create method and constructor.

  • Changes to the IsolatedTree are set on the main thread using the

NodeChange structure, and applied to the tree on the AX thread.

  • The updated IsolatedObjects are attached to their corresponding

platform wrappers on the AX thread, so that after creation they are only
accessed on the secondary thread.

  • accessibility/AXObjectCache.cpp:

(WebCore::AXObjectCache::postNotification): Invokes updateIsolatedTree.
(WebCore::createIsolatedTreeHierarchy):
(WebCore::AXObjectCache::generateIsolatedTree):
(WebCore::AXObjectCache::updateIsolatedTree):
(WebCore::AXObjectCache::createIsolatedTreeHierarchy): Became a static helper function.

  • accessibility/AXObjectCache.h:
  • accessibility/AccessibilityObjectInterface.h:
  • accessibility/isolatedtree/AXIsolatedObject.cpp:

(WebCore::AXIsolatedObject::AXIsolatedObject):
(WebCore::AXIsolatedObject::create):
(WebCore::AXIsolatedObject::setProperty):
(WebCore::AXIsolatedObject::setParent):
(WebCore::AXIsolatedObject::detachFromParent):
(WebCore::AXIsolatedObject::setTreeIdentifier): Deleted, the tree identifier is set in the constructor.

  • accessibility/isolatedtree/AXIsolatedObject.h:
  • accessibility/isolatedtree/AXIsolatedTree.cpp:

(WebCore::AXIsolatedTree::NodeChange::NodeChange):
(WebCore::AXIsolatedTree::appendNodeChanges):
(WebCore::AXIsolatedTree::applyPendingChanges):

  • accessibility/isolatedtree/AXIsolatedTree.h:
  • accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm:

(WebCore::AXIsolatedObject::attachPlatformWrapper):

  • accessibility/mac/AXObjectCacheMac.mm:
Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r256437 r256442  
     12020-02-12  Andres Gonzalez  <andresg_22@apple.com>
     2
     3        Support event notifications in IsolatedTree mode.
     4        https://bugs.webkit.org/show_bug.cgi?id=207581
     5
     6        Reviewed by Chris Fleizach.
     7
     8        - DOM/Render trees notifications are listened to by AXObjectCache and
     9        the corresponding IsolatedTree is updated.
     10        - The update is now happening for state, value and children change
     11        notifications.
     12        - AXObjectCache::updateIsolatedTree re-generates the subtree rooted at
     13        the node receiving the notification.
     14        - Consolidated creation of AXIsolatedObjects by passing treeID and
     15        parentID to the create method and constructor.
     16        - Changes to the IsolatedTree are set on the main thread using the
     17        NodeChange structure, and applied to the tree on the AX thread.
     18        - The updated IsolatedObjects are attached to their corresponding
     19        platform wrappers on the AX thread, so that after creation they are only
     20        accessed on the secondary thread.
     21
     22        * accessibility/AXObjectCache.cpp:
     23        (WebCore::AXObjectCache::postNotification): Invokes updateIsolatedTree.
     24        (WebCore::createIsolatedTreeHierarchy):
     25        (WebCore::AXObjectCache::generateIsolatedTree):
     26        (WebCore::AXObjectCache::updateIsolatedTree):
     27        (WebCore::AXObjectCache::createIsolatedTreeHierarchy): Became a static helper function.
     28        * accessibility/AXObjectCache.h:
     29        * accessibility/AccessibilityObjectInterface.h:
     30        * accessibility/isolatedtree/AXIsolatedObject.cpp:
     31        (WebCore::AXIsolatedObject::AXIsolatedObject):
     32        (WebCore::AXIsolatedObject::create):
     33        (WebCore::AXIsolatedObject::setProperty):
     34        (WebCore::AXIsolatedObject::setParent):
     35        (WebCore::AXIsolatedObject::detachFromParent):
     36        (WebCore::AXIsolatedObject::setTreeIdentifier): Deleted, the tree identifier is set in the constructor.
     37        * accessibility/isolatedtree/AXIsolatedObject.h:
     38        * accessibility/isolatedtree/AXIsolatedTree.cpp:
     39        (WebCore::AXIsolatedTree::NodeChange::NodeChange):
     40        (WebCore::AXIsolatedTree::appendNodeChanges):
     41        (WebCore::AXIsolatedTree::applyPendingChanges):
     42        * accessibility/isolatedtree/AXIsolatedTree.h:
     43        * accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm:
     44        (WebCore::AXIsolatedObject::attachPlatformWrapper):
     45        * accessibility/mac/AXObjectCacheMac.mm:
     46
    1472020-02-12  Zalan Bujtas  <zalan@apple.com>
    248
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r255548 r256442  
    11181118    if (!object)
    11191119        return;
     1120
     1121#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
     1122    updateIsolatedTree(object, notification);
     1123#endif
    11201124
    11211125    if (postType == PostAsynchronously) {
     
    30693073   
    30703074#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    3071 Ref<AXIsolatedObject> AXObjectCache::createIsolatedTreeHierarchy(AXCoreObject& object, AXID parentID, AXObjectCache* axObjectCache, AXIsolatedTree& tree, Vector<Ref<AXIsolatedObject>>& nodeChanges, bool isRoot)
    3072 {
    3073     auto isolatedTreeNode = AXIsolatedObject::create(object, isRoot);
    3074     nodeChanges.append(isolatedTreeNode.copyRef());
    3075 
    3076     isolatedTreeNode->setTreeIdentifier(tree.treeIdentifier());
    3077     isolatedTreeNode->setParent(parentID);
    3078     axObjectCache->attachWrapper(&isolatedTreeNode.get(), object.wrapper());
     3075static Ref<AXIsolatedObject> createIsolatedTreeHierarchy(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID, bool attachWrapper, Vector<AXIsolatedTree::NodeChange>& nodeChanges)
     3076{
     3077    auto isolatedObject = AXIsolatedObject::create(object, treeID, parentID);
     3078    nodeChanges.append(AXIsolatedTree::NodeChange(isolatedObject, object.wrapper()));
     3079    if (attachWrapper)
     3080        isolatedObject->attachPlatformWrapper(object.wrapper());
    30793081
    30803082    for (const auto& child : object.children()) {
    3081         auto staticChild = createIsolatedTreeHierarchy(*child, isolatedTreeNode->objectID(), axObjectCache, tree, nodeChanges, false);
    3082         isolatedTreeNode->appendChild(staticChild->objectID());
    3083     }
    3084 
    3085     return isolatedTreeNode;
     3083        auto staticChild = createIsolatedTreeHierarchy(*child, treeID, isolatedObject->objectID(), attachWrapper, nodeChanges);
     3084        isolatedObject->appendChild(staticChild->objectID());
     3085    }
     3086
     3087    return isolatedObject;
    30863088}
    30873089
     
    31013103    auto* axRoot = axObjectCache->getOrCreate(document.view());
    31023104    if (axRoot) {
    3103         Vector<Ref<AXIsolatedObject>> nodeChanges;
    3104         auto isolatedRoot = createIsolatedTreeHierarchy(*axRoot, InvalidAXID, axObjectCache, *tree, nodeChanges, true);
     3105        Vector<AXIsolatedTree::NodeChange> nodeChanges;
     3106        auto isolatedRoot = createIsolatedTreeHierarchy(*axRoot, tree->treeIdentifier(), InvalidAXID, true, nodeChanges);
    31053107        tree->setRootNode(isolatedRoot);
    31063108        tree->appendNodeChanges(nodeChanges);
     
    31123114
    31133115    return makeRef(*tree);
     3116}
     3117
     3118void AXObjectCache::updateIsolatedTree(AXCoreObject* object, AXNotification notification)
     3119{
     3120    if (!m_pageID)
     3121        return;
     3122
     3123    auto tree = AXIsolatedTree::treeForPageID(*m_pageID);
     3124    if (!tree)
     3125        return;
     3126
     3127    switch (notification) {
     3128    case AXCheckedStateChanged:
     3129    case AXChildrenChanged:
     3130    case AXValueChanged: {
     3131        tree->removeNode(object->objectID());
     3132        auto* parent = object->parentObject();
     3133        AXID parentID = parent ? parent->objectID() : InvalidAXID;
     3134        Vector<AXIsolatedTree::NodeChange> nodeChanges;
     3135        auto isolatedObject = createIsolatedTreeHierarchy(*object, tree->treeIdentifier(), parentID, false, nodeChanges);
     3136        tree->appendNodeChanges(nodeChanges);
     3137        break;
     3138    }
     3139    default:
     3140        break;
     3141    }
    31143142}
    31153143#endif
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r255167 r256442  
    2626#pragma once
    2727
     28#include "AXIsolatedTree.h"
    2829#include "AXTextStateChangeIntent.h"
    2930#include "AccessibilityObject.h"
     
    4445namespace WebCore {
    4546
    46 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    47 class AXIsolatedObject;
    48 class AXIsolatedTree;
    49 #endif
    5047class Document;
    5148class HTMLAreaElement;
     
    179176    void cacheAndInitializeWrapper(AccessibilityObject*, DOMObjectVariant = nullptr);
    180177    void attachWrapper(AXCoreObject*);
    181 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    182     void attachWrapper(AXIsolatedObject*, WebAccessibilityObjectWrapper*);
    183 #endif
    184178
    185179public:
     
    200194    void recomputeIsIgnored(RenderObject* renderer);
    201195
    202 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    203     WEBCORE_EXPORT static bool clientSupportsIsolatedTree();
    204 private:
    205     AXCoreObject* isolatedTreeRootObject();
    206     static AXCoreObject* isolatedTreeFocusedObject(Document&);
    207     void setIsolatedTreeFocusedObject(Node*);
    208     static Ref<AXIsolatedTree> generateIsolatedTree(PageIdentifier, Document&);
    209     static Ref<AXIsolatedObject> createIsolatedTreeHierarchy(AXCoreObject&, AXID, AXObjectCache*, AXIsolatedTree&, Vector<Ref<AXIsolatedObject>>&, bool isRoot);
    210 #endif
    211 
    212 public:
    213196    WEBCORE_EXPORT bool canUseSecondaryAXThread();
    214197
     
    368351
    369352    RefPtr<Range> rangeMatchesTextNearRange(RefPtr<Range>, const String&);
    370    
     353
     354#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
     355    WEBCORE_EXPORT static bool clientSupportsIsolatedTree();
     356private:
     357    AXCoreObject* isolatedTreeRootObject();
     358    static AXCoreObject* isolatedTreeFocusedObject(Document&);
     359    void setIsolatedTreeFocusedObject(Node*);
     360    static Ref<AXIsolatedTree> generateIsolatedTree(PageIdentifier, Document&);
     361    void updateIsolatedTree(AXCoreObject*, AXNotification);
     362#endif
    371363
    372364protected:
  • trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h

    r256347 r256442  
    7171typedef unsigned AXID;
    7272extern const AXID InvalidAXID;
    73 typedef unsigned AXIsolatedTreeID;   
    7473
    7574enum class AccessibilityRole {
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp

    r255884 r256442  
    3333namespace WebCore {
    3434
    35 AXIsolatedObject::AXIsolatedObject(AXCoreObject& object, bool isRoot)
    36     : m_id(object.objectID())
     35AXIsolatedObject::AXIsolatedObject(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID)
     36    : m_treeID(treeID)
     37    , m_parentID(parentID)
     38    , m_id(object.objectID())
    3739{
    3840    ASSERT(isMainThread());
    39     initializeAttributeData(object, isRoot);
    40     m_initialized = true;
    41 }
    42 
    43 Ref<AXIsolatedObject> AXIsolatedObject::create(AXCoreObject& object, bool isRoot)
    44 {
    45     return adoptRef(*new AXIsolatedObject(object, isRoot));
     41    if (auto tree = AXIsolatedTree::treeForID(m_treeID))
     42        m_cachedTree = tree;
     43    initializeAttributeData(object, parentID == InvalidAXID);
     44}
     45
     46Ref<AXIsolatedObject> AXIsolatedObject::create(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID)
     47{
     48    return adoptRef(*new AXIsolatedObject(object, treeID, parentID));
    4649}
    4750
     
    387390void AXIsolatedObject::setProperty(AXPropertyName propertyName, AttributeValueVariant&& value, bool shouldRemove)
    388391{
    389     ASSERT(!m_initialized);
    390392    ASSERT(isMainThread());
    391393
     
    405407{
    406408    ASSERT(isMainThread());
    407     m_parent = parent;
     409    m_parentID = parent;
    408410}
    409411
     
    426428void AXIsolatedObject::detachFromParent()
    427429{
    428     m_parent = InvalidAXID;
    429 }
    430 
    431 void AXIsolatedObject::setTreeIdentifier(AXIsolatedTreeID treeIdentifier)
    432 {
    433     m_treeIdentifier = treeIdentifier;
    434     if (auto tree = AXIsolatedTree::treeForID(m_treeIdentifier))
    435         m_cachedTree = tree;
     430    m_parentID = InvalidAXID;
    436431}
    437432
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h

    r255884 r256442  
    4848class AXIsolatedObject final : public AXCoreObject {
    4949public:
    50     static Ref<AXIsolatedObject> create(AXCoreObject&, bool isRoot);
     50    static Ref<AXIsolatedObject> create(AXCoreObject&, AXIsolatedTreeID, AXID parentID);
    5151    ~AXIsolatedObject();
    5252
     
    5555    void init() override { }
    5656
     57    void attachPlatformWrapper(AccessibilityObjectWrapper*);
    5758    bool isDetached() const override;
    5859
    59     void setTreeIdentifier(AXIsolatedTreeID);
    6060    void setParent(AXID);
    6161    void appendChild(AXID);
     
    6565    void detachPlatformWrapper(AccessibilityDetachmentType) override;
    6666
    67     AXID parent() const { return m_parent; }
    68 
    69     AXIsolatedTreeID treeIdentifier() const { return m_treeIdentifier; }
     67    AXID parent() const { return m_parentID; }
     68
     69    AXIsolatedTreeID treeIdentifier() const { return m_treeID; }
    7070    AXIsolatedTree* tree() const { return m_cachedTree.get(); }
    7171
    7272    AXIsolatedObject() = default;
    73     AXIsolatedObject(AXCoreObject&, bool isRoot);
     73    AXIsolatedObject(AXCoreObject&, AXIsolatedTreeID, AXID parentID);
    7474    void initializeAttributeData(AXCoreObject&, bool isRoot);
    7575    AXCoreObject* associatedAXObject() const
     
    822822    void updateBackingStore() override;
    823823
    824     AXID m_parent { InvalidAXID };
     824    AXIsolatedTreeID m_treeID;
     825    RefPtr<AXIsolatedTree> m_cachedTree;
     826    AXID m_parentID { InvalidAXID };
    825827    AXID m_id { InvalidAXID };
    826     bool m_initialized { false };
    827     AXIsolatedTreeID m_treeIdentifier;
    828     RefPtr<AXIsolatedTree> m_cachedTree;
    829828    Vector<AXID> m_childrenIDs;
    830829    Vector<RefPtr<AXCoreObject>> m_children;
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp

    r255311 r256442  
    4343}
    4444
     45AXIsolatedTree::NodeChange::NodeChange(const Ref<AXIsolatedObject>& isolatedObject, AccessibilityObjectWrapper* wrapper)
     46    : m_isolatedObject(isolatedObject.copyRef())
     47    , m_wrapper(wrapper)
     48{
     49}
     50
     51AXIsolatedTree::NodeChange::NodeChange(const NodeChange& other)
     52    : m_isolatedObject(other.m_isolatedObject.copyRef())
     53    , m_wrapper(other.m_wrapper)
     54{
     55}
     56
    4557HashMap<PageIdentifier, Ref<AXIsolatedTree>>& AXIsolatedTree::treePageCache()
    4658{
     
    156168}
    157169
    158 void AXIsolatedTree::appendNodeChanges(Vector<Ref<AXIsolatedObject>>& log)
    159 {
    160     LockHolder locker { m_changeLogLock };
    161     for (auto& node : log)
    162         m_pendingAppends.append(node.copyRef());
     170void AXIsolatedTree::appendNodeChanges(const Vector<NodeChange>& log)
     171{
     172    LockHolder locker { m_changeLogLock };
     173    for (const auto& node : log)
     174        m_pendingAppends.append(node);
    163175}
    164176
     
    168180    LockHolder locker { m_changeLogLock };
    169181
    170     // We don't clear the pending IDs beacause if the next round of updates does not modify them, then they stay the same
    171     // value without extra bookkeeping.
    172182    m_focusedNodeID = m_pendingFocusedNodeID;
    173183
    174     for (auto& item : m_pendingAppends)
    175         m_readerThreadNodeMap.add(item->objectID(), WTFMove(item));
    176     m_pendingAppends.clear();
    177 
    178     for (auto& item : m_pendingRemovals) {
     184    for (const auto& item : m_pendingRemovals) {
    179185        if (auto object = nodeForID(item))
    180186            object->detach(AccessibilityDetachmentType::ElementDestroyed);
     
    182188    }
    183189    m_pendingRemovals.clear();
    184 }
    185    
     190
     191    for (auto& item : m_pendingAppends) {
     192        ASSERT(item.m_wrapper);
     193        item.m_isolatedObject->attachPlatformWrapper(item.m_wrapper);
     194        m_readerThreadNodeMap.add(item.m_isolatedObject->objectID(), item.m_isolatedObject.copyRef());
     195    }
     196    m_pendingAppends.clear();
     197}
     198
    186199} // namespace WebCore
    187200
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h

    r255311 r256442  
    2828#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    2929
     30#include "AccessibilityObjectInterface.h"
    3031#include "PageIdentifier.h"
    3132#include <wtf/HashMap.h>
     
    3536namespace WebCore {
    3637
     38class AXIsolatedObject;
     39class AXObjectCache;
    3740class Page;
     41
     42typedef unsigned AXIsolatedTreeID;
    3843
    3944class AXIsolatedTree : public ThreadSafeRefCounted<AXIsolatedTree> {
     
    5762    static RefPtr<AXIsolatedObject> nodeInTreeForID(AXIsolatedTreeID, AXID);
    5863
     64    struct NodeChange {
     65        Ref<AXIsolatedObject> m_isolatedObject;
     66        AccessibilityObjectWrapper* m_wrapper;
     67        NodeChange(const Ref<AXIsolatedObject>&, AccessibilityObjectWrapper*);
     68        NodeChange(const NodeChange&);
     69    };
     70
    5971    // Call on main thread
    60     void appendNodeChanges(Vector<Ref<AXIsolatedObject>>&);
     72    void appendNodeChanges(const Vector<NodeChange>&);
    6173    void removeNode(AXID);
    6274
     
    8193
    8294    // Written to by main thread under lock, accessed and applied by AX thread.
    83     Vector<Ref<AXIsolatedObject>> m_pendingAppends;
     95    Vector<NodeChange> m_pendingAppends;
    8496    Vector<AXID> m_pendingRemovals;
    8597    AXID m_pendingFocusedNodeID;
  • trunk/Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm

    r255167 r256442  
    3333namespace WebCore {
    3434
     35void AXIsolatedObject::attachPlatformWrapper(AccessibilityObjectWrapper* wrapper)
     36{
     37    [wrapper attachIsolatedObject:this];
     38    setWrapper(wrapper);
     39}
     40
    3541void AXIsolatedObject::detachPlatformWrapper(AccessibilityDetachmentType)
    3642{
  • trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm

    r255167 r256442  
    239239}
    240240
    241 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    242 void AXObjectCache::attachWrapper(AXIsolatedObject* isolatedObject, WebAccessibilityObjectWrapper* wrapper)
    243 {
    244     [wrapper attachIsolatedObject:(AXCoreObject*)isolatedObject];
    245     isolatedObject->setWrapper(wrapper);
    246 }
    247 #endif
    248 
    249241static BOOL axShouldRepostNotificationsForTests = false;
    250242
Note: See TracChangeset for help on using the changeset viewer.