chromium/ui/accessibility/ax_tree_serializer.h

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
#define UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_

#include <stddef.h>
#include <stdint.h>

#include <ctime>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <vector>

#include "base/debug/crash_logging.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "ui/accessibility/ax_common.h"
#include "ui/accessibility/ax_error_types.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/ax_tree_data.h"
#include "ui/accessibility/ax_tree_source.h"
#include "ui/accessibility/ax_tree_update.h"

namespace ui {

struct ClientTreeNode;

// AXTreeSerializer is a helper class that serializes incremental
// updates to an AXTreeSource as a AXTreeUpdateType struct.
// These structs can be unserialized by a client object such as an
// AXTree. An AXTreeSerializer keeps track of the tree of node ids that its
// client is aware of so that it will never generate an AXTreeUpdateType that
// results in an invalid tree.
//
// Every node in the source tree must have an id that's a unique positive
// integer, the same node must not appear twice.
//
// Usage:
//
// You must call SerializeChanges() every time a node in the tree changes,
// and send the generated AXTreeUpdateType to the client. Changes to the
// AXTreeData, if any, are also automatically included in the AXTreeUpdateType.
//
// If a node is added, call SerializeChanges on its parent.
// If a node is removed, call SerializeChanges on its parent.
// If a whole new subtree is added, just call SerializeChanges on its root.
// If the root of the tree changes, call SerializeChanges on the new root.
//
// AXTreeSerializer will avoid re-serializing nodes that do not change.
// For example, if node 1 has children 2, 3, 4, 5 and then child 2 is
// removed and a new child 6 is added, the AXTreeSerializer will only
// update nodes 1 and 6 (and any children of node 6 recursively). It will
// assume that nodes 3, 4, and 5 are not modified unless you explicitly
// call SerializeChanges() on them.
//
// As long as the source tree has unique ids for every node and no loops,
// and as long as every update is applied to the client tree, AXTreeSerializer
// will continue to work. If the source tree makes a change but fails to
// call SerializeChanges properly, the trees may get out of sync - but
// because AXTreeSerializer always keeps track of what updates it's sent,
// it will never send an invalid update and the client tree will not break,
// it just may not contain all of the changes.
template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
class AXTreeSerializer {};

// In order to keep track of what nodes the client knows about, we keep a
// representation of the client tree - just IDs and parent/child
// relationships, and a marker indicating whether it's been dirtied.
struct AX_EXPORT ClientTreeNode {};

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
AXTreeSerializer<AXSourceNode,
                 AXSourceNodeVectorType,
                 AXTreeUpdateType,
                 AXTreeDataType,
                 AXNodeDataType>::
    AXTreeSerializer(
        AXTreeSource<AXSourceNode, AXTreeDataType, AXNodeDataType>* tree,
        bool crash_on_error)
    :{}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
AXTreeSerializer<AXSourceNode,
                 AXSourceNodeVectorType,
                 AXTreeUpdateType,
                 AXTreeDataType,
                 AXNodeDataType>::~AXTreeSerializer() {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::Reset() {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::
    ChangeTreeSourceForTesting(
        AXTreeSource<AXSourceNode, AXTreeDataType, AXNodeDataType>* new_tree) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
size_t AXTreeSerializer<AXSourceNode,
                        AXSourceNodeVectorType,
                        AXTreeUpdateType,
                        AXTreeDataType,
                        AXNodeDataType>::ClientTreeNodeCount() const {}

#if DCHECK_IS_ON()
template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
std::vector<AXNodeID> AXTreeSerializer<AXSourceNode,
                                       AXSourceNodeVectorType,
                                       AXTreeUpdateType,
                                       AXTreeDataType,
                                       AXNodeDataType>::ClientTreeNodeIds()
    const {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
AXSourceNode AXTreeSerializer<AXSourceNode,
                              AXSourceNodeVectorType,
                              AXTreeUpdateType,
                              AXTreeDataType,
                              AXNodeDataType>::ParentOf(AXNodeID id) {}
#endif

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
AXSourceNode AXTreeSerializer<
    AXSourceNode,
    AXSourceNodeVectorType,
    AXTreeUpdateType,
    AXTreeDataType,
    AXNodeDataType>::LeastCommonAncestor(AXSourceNode node,
                                         ClientTreeNode* client_node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
AXSourceNode
AXTreeSerializer<AXSourceNode,
                 AXSourceNodeVectorType,
                 AXTreeUpdateType,
                 AXTreeDataType,
                 AXNodeDataType>::LeastCommonAncestor(AXSourceNode node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
bool AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::ComputeReparentingLCA(AXSourceNode*
                                                                 lca) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
bool AXTreeSerializer<
    AXSourceNode,
    AXSourceNodeVectorType,
    AXTreeUpdateType,
    AXTreeDataType,
    AXNodeDataType>::AnyDescendantWasReparented(AXSourceNode node,
                                                AXSourceNode* out_lca) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::CreateClientRoot(AXSourceNode root) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
ClientTreeNode*
AXTreeSerializer<AXSourceNode,
                 AXSourceNodeVectorType,
                 AXTreeUpdateType,
                 AXTreeDataType,
                 AXNodeDataType>::ClientTreeNodeById(AXNodeID id) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
ClientTreeNode*
AXTreeSerializer<AXSourceNode,
                 AXSourceNodeVectorType,
                 AXTreeUpdateType,
                 AXTreeDataType,
                 AXNodeDataType>::GetClientTreeNodeParent(ClientTreeNode* obj) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
bool AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::
    SerializeChanges(AXSourceNode node,
                     AXTreeUpdateType out_update,
                     std::set<AXSerializationErrorFlag>* out_error) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
std::vector<AXNodeID> AXTreeSerializer<AXSourceNode,
                                       AXSourceNodeVectorType,
                                       AXTreeUpdateType,
                                       AXTreeDataType,
                                       AXNodeDataType>::GetIncompleteNodeIds() {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::MarkNodeDirty(AXNodeID id) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::MarkSubtreeDirty(AXNodeID id) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
bool AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::IsInClientTree(AXSourceNode node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::MarkClientSubtreeDirty(ClientTreeNode*
                                                                  client_node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::DeleteClientSubtree(ClientTreeNode*
                                                               client_node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::DeleteDescendants(ClientTreeNode*
                                                             client_node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
void AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::DeleteDescendants(AXSourceNode node) {}

template <typename AXSourceNode,
          typename AXSourceNodeVectorType,
          typename AXTreeUpdateType,
          typename AXTreeDataType,
          typename AXNodeDataType>
bool AXTreeSerializer<AXSourceNode,
                      AXSourceNodeVectorType,
                      AXTreeUpdateType,
                      AXTreeDataType,
                      AXNodeDataType>::
    SerializeChangedNodes(AXSourceNode node,
                          AXTreeUpdateType out_update,
                          std::set<AXSerializationErrorFlag>* out_error) {}

}  // namespace ui

#endif  // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_