#include "ui/accessibility/ax_tree.h"
#include <stddef.h>
#include <numeric>
#include <utility>
#include "base/auto_reset.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/adapters.h"
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/observer_list.h"
#include "base/strings/stringprintf.h"
#include "base/timer/elapsed_timer.h"
#include "components/crash/core/common/crash_key.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_event.h"
#include "ui/accessibility/ax_language_detection.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_node_position.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_selection.h"
#include "ui/accessibility/ax_table_info.h"
#include "ui/accessibility/ax_tree_observer.h"
#include "ui/gfx/geometry/transform.h"
namespace ui {
namespace {
constexpr ax::mojom::IntListAttribute kReverseRelationIntListAttributes[] = …;
constexpr ax::mojom::IntAttribute kReverseRelationIntAttributes[] = …;
std::string TreeToStringHelper(const AXNode* node, int indent, bool verbose) { … }
template <typename K, typename V>
bool KeyValuePairsKeysMatch(std::vector<std::pair<K, V>> pairs1,
std::vector<std::pair<K, V>> pairs2) { … }
template <typename K, typename V>
std::map<K, V> MapFromKeyValuePairs(std::vector<std::pair<K, V>> pairs) { … }
template <typename K, typename V, typename F>
void CallIfAttributeValuesChanged(const std::vector<std::pair<K, V>>& old_pairs,
const std::vector<std::pair<K, V>>& new_pairs,
const V& empty_value,
F callback) { … }
bool IsCollapsed(const AXNode* node) { … }
}
bool AXTree::is_focused_node_always_unignored_ = …;
struct PendingStructureChanges { … };
enum class AXTreePendingStructureStatus { … };
struct AXTreeUpdateState { … };
AXTree::NodeSetSizePosInSetInfo::NodeSetSizePosInSetInfo() = default;
AXTree::NodeSetSizePosInSetInfo::~NodeSetSizePosInSetInfo() = default;
struct AXTree::OrderedSetContent { … };
struct AXTree::OrderedSetItemsMap { … };
void AXTree::SetFocusedNodeShouldNeverBeIgnored() { … }
bool AXTree::ComputeNodeIsIgnored(const AXTreeData* optional_tree_data,
const AXNodeData& node_data) { … }
bool AXTree::ComputeNodeIsIgnoredChanged(
const AXTreeData* optional_old_tree_data,
const AXNodeData& old_node_data,
const AXTreeData* optional_new_tree_data,
const AXNodeData& new_node_data) { … }
AXTree::AXTree() { … }
AXTree::AXTree(const AXTreeUpdate& initial_state) { … }
AXTree::~AXTree() { … }
void AXTree::AddObserver(AXTreeObserver* observer) { … }
bool AXTree::HasObserver(AXTreeObserver* observer) { … }
void AXTree::RemoveObserver(AXTreeObserver* observer) { … }
const AXTreeID& AXTree::GetAXTreeID() const { … }
const AXTreeData& AXTree::data() const { … }
AXNode* AXTree::GetFromId(AXNodeID id) const { … }
void AXTree::Destroy() { … }
void AXTree::UpdateDataForTesting(const AXTreeData& new_data) { … }
gfx::RectF AXTree::RelativeToTreeBoundsInternal(const AXNode* node,
gfx::RectF bounds,
bool* offscreen,
bool clip_bounds,
bool skip_container_offset,
bool allow_recursion) const { … }
gfx::RectF AXTree::RelativeToTreeBounds(const AXNode* node,
gfx::RectF bounds,
bool* offscreen,
bool clip_bounds,
bool skip_container_offset) const { … }
gfx::RectF AXTree::GetTreeBounds(const AXNode* node,
bool* offscreen,
bool clip_bounds) const { … }
std::set<AXNodeID> AXTree::GetReverseRelations(ax::mojom::IntAttribute attr,
AXNodeID dst_id) const { … }
std::set<AXNodeID> AXTree::GetReverseRelations(ax::mojom::IntListAttribute attr,
AXNodeID dst_id) const { … }
std::set<AXNodeID> AXTree::GetNodeIdsForChildTreeId(
AXTreeID child_tree_id) const { … }
const std::set<AXTreeID> AXTree::GetAllChildTreeIds() const { … }
bool AXTree::Unserialize(const AXTreeUpdate& update) { … }
#if DCHECK_IS_ON()
void AXTree::CheckTreeConsistency(const AXTreeUpdate& update) { … }
#endif
AXTableInfo* AXTree::GetTableInfo(const AXNode* const_table_node) const { … }
std::string AXTree::ToString(bool verbose) const { … }
AXNode* AXTree::CreateNode(AXNode* parent,
AXNodeID id,
size_t index_in_parent,
AXTreeUpdateState* update_state) { … }
bool AXTree::ComputePendingChanges(const AXTreeUpdate& update,
AXTreeUpdateState* update_state) { … }
bool AXTree::ComputePendingChangesToNode(const AXNodeData& new_data,
bool is_new_root,
AXTreeUpdateState* update_state) { … }
bool AXTree::UpdateNode(const AXNodeData& src,
bool is_new_root,
AXTreeUpdateState* update_state) { … }
void AXTree::NotifySubtreeWillBeReparentedOrDeleted(
AXNode* node,
const AXTreeUpdateState* update_state) { … }
void AXTree::NotifyNodeWillBeReparentedOrDeleted(
AXNode* node,
const AXTreeUpdateState* update_state) { … }
void AXTree::RecursivelyNotifyNodeDeletedForTreeTeardown(AXNode* node) { … }
void AXTree::NotifyNodeHasBeenDeleted(AXNodeID node_id) { … }
void AXTree::NotifyNodeHasBeenReparentedOrCreated(
AXNode* node,
const AXTreeUpdateState* update_state) { … }
void AXTree::NotifyChildTreeConnectionChanged(AXNode* node,
AXTree* child_tree) { … }
void AXTree::NotifyNodeAttributesWillChange(
AXNode* node,
AXTreeUpdateState& update_state,
const AXTreeData* optional_old_tree_data,
const AXNodeData& old_data,
const AXTreeData* optional_new_tree_data,
const AXNodeData& new_data) { … }
void AXTree::NotifyNodeAttributesHaveBeenChanged(
AXNode* node,
AXTreeUpdateState& update_state,
const AXTreeData* optional_old_tree_data,
const AXNodeData& old_data,
const AXTreeData* optional_new_tree_data,
const AXNodeData& new_data) { … }
void AXTree::UpdateReverseRelations(AXNode* node,
const AXNodeData& new_data,
bool is_new_node) { … }
bool AXTree::ValidatePendingChangesComplete(
const AXTreeUpdateState& update_state) { … }
void AXTree::MarkSubtreeForDestruction(AXNodeID node_id,
AXTreeUpdateState* update_state) { … }
void AXTree::MarkNodesForDestructionRecursive(AXNodeID node_id,
AXTreeUpdateState* update_state) { … }
void AXTree::DestroySubtree(AXNode* node,
AXTreeUpdateState* update_state) { … }
void AXTree::DestroyNodeAndSubtree(AXNode* node,
AXTreeUpdateState* update_state) { … }
void AXTree::DeleteOldChildren(AXNode* node,
const std::vector<AXNodeID>& new_child_ids,
AXTreeUpdateState* update_state) { … }
bool AXTree::CreateNewChildVector(
AXNode* node,
const std::vector<AXNodeID>& new_child_ids,
std::vector<raw_ptr<AXNode, VectorExperimental>>* new_children,
AXTreeUpdateState* update_state) { … }
AXNode* AXTree::GetUnignoredAncestorFromId(AXNodeID node_id) const { … }
AXNodeID AXTree::GetNextNegativeInternalNodeId() { … }
void AXTree::PopulateOrderedSetItemsMap(
const AXNode& original_node,
const AXNode* ordered_set,
OrderedSetItemsMap* items_map_to_be_populated) const { … }
void AXTree::RecursivelyPopulateOrderedSetItemsMap(
const AXNode& original_node,
const AXNode* ordered_set,
const AXNode* local_parent,
std::optional<int> ordered_set_min_level,
std::optional<int> prev_level,
OrderedSetItemsMap* items_map_to_be_populated) const { … }
void AXTree::ComputeSetSizePosInSetAndCache(const AXNode& node,
const AXNode* ordered_set) { … }
void AXTree::ComputeSetSizePosInSetAndCacheHelper(
const OrderedSetContent& ordered_set_content) { … }
std::optional<int> AXTree::GetPosInSet(const AXNode& node) { … }
std::optional<int> AXTree::GetSetSize(const AXNode& node) { … }
AXSelection AXTree::GetSelection() const { … }
AXSelection AXTree::GetUnignoredSelection() const { … }
bool AXTree::GetTreeUpdateInProgressState() const { … }
void AXTree::SetTreeUpdateInProgressState(bool set_tree_update_value) { … }
bool AXTree::HasPaginationSupport() const { … }
void AXTree::NotifyTreeManagerWillBeRemoved(AXTreeID previous_tree_id) { … }
void AXTree::RecordError(const AXTreeUpdateState& update_state,
std::string new_error,
bool is_fatal) { … }
}