// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/webui/eche_app_ui/accessibility_tree_converter.h"
#include <algorithm>
#include <optional>
#include <vector>
#include "ash/webui/eche_app_ui/proto/accessibility_mojom.pb.h"
#include "base/check.h"
#include "base/containers/flat_map.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "services/accessibility/android/public/mojom/accessibility_helper.mojom.h"
#include "ui/accessibility/ax_enums.mojom-shared.h"
namespace ash::eche_app {
AccessibilityTreeConverter::AccessibilityTreeConverter() = default;
AccessibilityTreeConverter::~AccessibilityTreeConverter() = default;
template <class ProtoType, class MojomType>
void AccessibilityTreeConverter::CopyRepeatedPtrFieldToOptionalVector(
const ::google::protobuf::RepeatedPtrField<ProtoType>& in_data,
std::optional<std::vector<MojomType>>& out_data,
base::RepeatingCallback<MojomType(ProtoType)> transform) {
if (!in_data.empty()) {
auto out = std::vector<MojomType>();
for (const auto& item : in_data) {
MojomType result = transform.Run(item);
out.emplace_back(std::move(result));
}
out_data = std::move(out);
}
}
template <class SharedType>
void AccessibilityTreeConverter::CopyRepeatedPtrFieldToOptionalVector(
const ::google::protobuf::RepeatedPtrField<SharedType>& in_data,
std::optional<std::vector<SharedType>>& out_data) {
CopyRepeatedPtrFieldToOptionalVector(
in_data, out_data, base::BindRepeating([](SharedType in) { return in; }));
}
template <class ProtoPairType, class MojomKeyType, class MojomValueType>
void AccessibilityTreeConverter::ConvertProperties(
const ::google::protobuf::RepeatedPtrField<ProtoPairType>& in_properties,
std::optional<base::flat_map<MojomKeyType, MojomValueType>>&
out_properties) {
if (in_properties.empty()) {
return;
}
out_properties = base::flat_map<MojomKeyType, MojomValueType>();
for (const ProtoPairType& pair : in_properties) {
// There is a ToMojomProperty function for various mojom types.
std::optional<MojomKeyType> key =
AccessibilityTreeConverter::ToMojomProperty(pair.key());
if (!key.has_value()) {
continue;
}
(*out_properties)[*key] = pair.value();
}
}
template <class ProtoPropertyPairType,
class ProtoValueType,
class MojomKeyType,
class MojomValueType>
bool AccessibilityTreeConverter::ConvertListProperties(
const ::google::protobuf::RepeatedPtrField<ProtoPropertyPairType>&
in_properties,
std::optional<base::flat_map<MojomKeyType, std::vector<MojomValueType>>>&
out_properties,
base::RepeatingCallback<bool(ProtoValueType,
std::optional<MojomValueType>&)> transform) {
if (in_properties.empty()) {
return true;
}
out_properties = base::flat_map<MojomKeyType, std::vector<MojomValueType>>();
for (const ProtoPropertyPairType& pair : in_properties) {
std::optional<MojomKeyType> key =
AccessibilityTreeConverter::ToMojomProperty(pair.key());
if (!key.has_value()) {
continue;
}
auto& list = pair.value().values();
(*out_properties)[*key] = std::vector<MojomValueType>();
for (const ProtoValueType& value : list) {
std::optional<MojomValueType> converted;
bool success = transform.Run(value, converted);
if (success && converted.has_value()) {
(*out_properties)[*key].emplace_back(std::move(*converted));
} else {
return false;
}
}
}
return true;
}
template <class ProtoPropertyPairType,
class MojomKeyType,
class SharedValueType>
bool AccessibilityTreeConverter::ConvertListProperties(
const ::google::protobuf::RepeatedPtrField<ProtoPropertyPairType>&
in_properties,
std::optional<base::flat_map<MojomKeyType, std::vector<SharedValueType>>>&
out_properties) {
return ConvertListProperties(
in_properties, out_properties,
base::BindRepeating(
[](SharedValueType in, std::optional<SharedValueType>& out) {
out = std::move(in);
return true;
}));
}
bool AccessibilityTreeConverter::DeserializeProto(
const std::vector<uint8_t>& serialized_proto,
proto::AccessibilityEventData* out_proto) {
CHECK(out_proto);
return out_proto->ParseFromArray(serialized_proto.data(),
serialized_proto.size());
}
mojo::StructPtr<AXEventData>
AccessibilityTreeConverter::ConvertEventDataProtoToMojom(
proto::AccessibilityEventData& in_data) {
auto out_data = AXEventData::New();
// Details
auto mojom_event_type = ToMojomEventType(in_data.event_type());
if (mojom_event_type.has_value()) {
out_data->event_type = *mojom_event_type;
}
out_data->source_id = in_data.source_id();
// Node info data
for (const auto& node_data : in_data.node_data()) {
auto node = ToMojomNodeData(node_data);
// A node was invalid, invalidate the event data and return.
if (!node) {
return nullptr;
}
out_data->node_data.emplace_back(std::move(node));
}
// Window data
out_data->window_id = in_data.window_id();
if (!in_data.window_data().empty()) {
out_data->window_data = std::vector<mojo::StructPtr<AXWindowData>>();
for (const auto& window_data : in_data.window_data()) {
auto converted_window_data = ToMojomWindowData(window_data);
if (!converted_window_data) {
return nullptr;
}
out_data->window_data->emplace_back(std::move(converted_window_data));
}
}
// event_text
CopyRepeatedPtrFieldToOptionalVector(in_data.event_text(),
out_data->event_text);
// Property lists.
ConvertProperties(in_data.int_properties(), out_data->int_properties);
ConvertProperties(in_data.string_properties(), out_data->string_properties);
if (!ConvertListProperties(in_data.int_list_properties(),
out_data->int_list_properties)) {
// Some properties were invalid.
return nullptr;
}
return out_data;
}
std::optional<proto::AccessibilityActionType> ConvertType(
ax::mojom::Action action_type) {
switch (action_type) {
case ax::mojom::Action::kDoDefault:
return proto::AccessibilityActionType::ACTION_CLICK;
case ax::mojom::Action::kFocus:
return proto::AccessibilityActionType::ACTION_ACCESSIBILITY_ACTION_FOCUS;
case ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint:
return proto::AccessibilityActionType::ACTION_ACCESSIBILITY_FOCUS;
case ax::mojom::Action::kScrollToMakeVisible:
return proto::AccessibilityActionType::ACTION_SHOW_ON_SCREEN;
case ax::mojom::Action::kScrollBackward:
return proto::AccessibilityActionType::ACTION_SCROLL_BACKWARD;
case ax::mojom::Action::kScrollForward:
return proto::AccessibilityActionType::ACTION_SCROLL_FORWARD;
case ax::mojom::Action::kScrollUp:
return proto::AccessibilityActionType::ACTION_SCROLL_UP;
case ax::mojom::Action::kScrollDown:
return proto::AccessibilityActionType::ACTION_SCROLL_DOWN;
case ax::mojom::Action::kScrollLeft:
return proto::AccessibilityActionType::ACTION_SCROLL_LEFT;
case ax::mojom::Action::kScrollRight:
return proto::AccessibilityActionType::ACTION_SCROLL_RIGHT;
case ax::mojom::Action::kScrollToPositionAtRowColumn:
return proto::AccessibilityActionType::ACTION_SCROLL_TO_POSITION;
case ax::mojom::Action::kCustomAction:
return proto::AccessibilityActionType::ACTION_CUSTOM_ACTION;
case ax::mojom::Action::kSetAccessibilityFocus:
return proto::AccessibilityActionType::ACTION_ACCESSIBILITY_FOCUS;
case ax::mojom::Action::kClearAccessibilityFocus:
return proto::AccessibilityActionType::ACTION_CLEAR_ACCESSIBILITY_FOCUS;
case ax::mojom::Action::kGetTextLocation:
return proto::AccessibilityActionType::ACTION_GET_TEXT_LOCATION;
case ax::mojom::Action::kShowTooltip:
return proto::AccessibilityActionType::ACTION_SHOW_TOOLTIP;
case ax::mojom::Action::kHideTooltip:
return proto::AccessibilityActionType::ACTION_HIDE_TOOLTIP;
case ax::mojom::Action::kCollapse:
return proto::AccessibilityActionType::ACTION_COLLAPSE;
case ax::mojom::Action::kExpand:
return proto::AccessibilityActionType::ACTION_EXPAND;
case ax::mojom::Action::kLongClick:
return proto::AccessibilityActionType::ACTION_LONG_CLICK;
default:
return std::nullopt;
}
}
void PopulateActionParameters(const ui::AXActionData& chrome_data,
proto::AccessibilityActionData& action_data) {
switch (action_data.action_type()) {
case proto::AccessibilityActionType::ACTION_SCROLL_TO_POSITION: {
const auto [row, column] = chrome_data.row_column;
auto* row_kvp = action_data.add_int_parameters();
row_kvp->set_key(proto::ActionIntArgumentType::TYPE_ROW_INT);
row_kvp->set_value(row);
auto* col_kvp = action_data.add_int_parameters();
col_kvp->set_key(proto::ActionIntArgumentType::TYPE_COLUMN_INT);
col_kvp->set_value(column);
break;
}
case proto::AccessibilityActionType::ACTION_CUSTOM_ACTION:
action_data.set_custom_action_id(chrome_data.custom_action_id);
break;
case proto::AccessibilityActionType::ACTION_NEXT_HTML_ELEMENT:
case proto::AccessibilityActionType::ACTION_PREVIOUS_HTML_ELEMENT:
case proto::AccessibilityActionType::ACTION_ACCESSIBILITY_ACTION_FOCUS:
case proto::AccessibilityActionType::ACTION_CLEAR_FOCUS:
case proto::AccessibilityActionType::ACTION_SELECT:
case proto::AccessibilityActionType::ACTION_CLEAR_SELECTION:
case proto::AccessibilityActionType::ACTION_CLICK:
case proto::AccessibilityActionType::ACTION_LONG_CLICK:
case proto::AccessibilityActionType::ACTION_ACCESSIBILITY_FOCUS:
case proto::AccessibilityActionType::ACTION_CLEAR_ACCESSIBILITY_FOCUS:
case proto::AccessibilityActionType::ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
case proto::AccessibilityActionType::
ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
case proto::AccessibilityActionType::ACTION_SCROLL_FORWARD:
case proto::AccessibilityActionType::ACTION_SCROLL_BACKWARD:
case proto::AccessibilityActionType::ACTION_COPY:
case proto::AccessibilityActionType::ACTION_PASTE:
case proto::AccessibilityActionType::ACTION_CUT:
case proto::AccessibilityActionType::ACTION_SET_SELECTION:
case proto::AccessibilityActionType::ACTION_EXPAND:
case proto::AccessibilityActionType::ACTION_COLLAPSE:
case proto::AccessibilityActionType::ACTION_DISMISS:
case proto::AccessibilityActionType::ACTION_SET_TEXT:
case proto::AccessibilityActionType::ACTION_CONTEXT_CLICK:
case proto::AccessibilityActionType::ACTION_SCROLL_DOWN:
case proto::AccessibilityActionType::ACTION_SCROLL_LEFT:
case proto::AccessibilityActionType::ACTION_SCROLL_RIGHT:
case proto::AccessibilityActionType::ACTION_SCROLL_UP:
case proto::AccessibilityActionType::ACTION_SET_PROGRESS:
case proto::AccessibilityActionType::ACTION_SHOW_ON_SCREEN:
case proto::AccessibilityActionType::ACTION_GET_TEXT_LOCATION:
case proto::AccessibilityActionType::ACTION_SHOW_TOOLTIP:
case proto::AccessibilityActionType::ACTION_HIDE_TOOLTIP:
case proto::AccessibilityActionType::
AccessibilityActionType_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityActionType::
AccessibilityActionType_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
}
std::optional<proto::AccessibilityActionData>
AccessibilityTreeConverter::ConvertActionDataToProto(
const ui::AXActionData& data,
int32_t window_id) {
proto::AccessibilityActionData action_data;
auto action_type = ConvertType(data.action);
if (!action_type.has_value()) {
return std::nullopt;
}
action_data.set_window_id(window_id);
action_data.set_action_type(action_type.value());
action_data.set_node_id(data.target_node_id);
PopulateActionParameters(data, action_data);
if (action_type == proto::AccessibilityActionType::ACTION_GET_TEXT_LOCATION) {
action_data.set_start_index(data.start_index);
action_data.set_end_index(data.end_index);
}
return action_data;
}
// Object converters
mojo::StructPtr<AXWindowData> AccessibilityTreeConverter::ToMojomWindowData(
const proto::AccessibilityWindowInfoData& proto_in) {
// Create object.
auto mojom_out = AXWindowData::New();
// id
mojom_out->window_id = proto_in.window_id();
// Root node id
mojom_out->root_node_id = proto_in.root_node_id();
// Bounds
if (proto_in.has_bounds_in_screen()) {
const auto& proto_bounds = proto_in.bounds_in_screen();
if (proto_bounds.bottom() > proto_bounds.top() &&
proto_bounds.right() > proto_bounds.left()) {
mojom_out->bounds_in_screen.SetByBounds(
proto_bounds.left(), proto_bounds.top(), proto_bounds.right(),
proto_bounds.bottom());
} else {
// Window had invalid data.
return nullptr;
}
}
// Window type
auto mojom_window_type = ToMojomWindowType(proto_in.window_type());
if (mojom_window_type.has_value()) {
mojom_out->window_type = *mojom_window_type;
}
// Properties
ConvertProperties(proto_in.boolean_properties(),
mojom_out->boolean_properties);
ConvertProperties(proto_in.int_properties(), mojom_out->int_properties);
ConvertProperties(proto_in.string_properties(), mojom_out->string_properties);
ConvertListProperties(proto_in.int_list_properties(),
mojom_out->int_list_properties);
return mojom_out;
}
mojo::StructPtr<AXNodeData> AccessibilityTreeConverter::ToMojomNodeData(
const proto::AccessibilityNodeInfoData& proto_in) {
// Create object.
auto mojom_out = AXNodeData::New();
// Bounds
if (proto_in.has_bounds_in_screen()) {
const auto& proto_bounds = proto_in.bounds_in_screen();
if (proto_bounds.bottom() < proto_bounds.top() ||
proto_bounds.right() < proto_bounds.left()) {
return nullptr;
}
mojom_out->bounds_in_screen.SetByBounds(
proto_bounds.left(), proto_bounds.top(), proto_bounds.right(),
proto_bounds.bottom());
}
// Id
mojom_out->id = proto_in.id();
// Properties
ConvertProperties(proto_in.boolean_properties(),
mojom_out->boolean_properties);
ConvertProperties(proto_in.int_properties(), mojom_out->int_properties);
ConvertProperties(proto_in.string_properties(), mojom_out->string_properties);
ConvertListProperties(proto_in.int_list_properties(),
mojom_out->int_list_properties);
bool convert_success = ConvertListProperties(
proto_in.spannable_string_properties(),
mojom_out->spannable_string_properties,
base::BindRepeating(
[](AccessibilityTreeConverter* converter, proto::SpanEntry entry,
std::optional<ax::android::mojom::SpanEntryPtr>& out_entry) {
auto result_ptr = ax::android::mojom::SpanEntry::New();
if (entry.start() >= entry.end()) {
return false;
}
result_ptr->end = entry.end();
result_ptr->start = entry.start();
auto mojom_span_type =
converter->ToMojomSpanType(entry.span_type());
if (mojom_span_type.has_value()) {
result_ptr->span_type = *mojom_span_type;
}
out_entry = std::move(result_ptr);
return true;
},
this));
// Some properties were invalid.
if (!convert_success) {
return nullptr;
}
// Collection Info
if (proto_in.has_collection_info()) {
const auto& proto_collection_info = proto_in.collection_info();
mojom_out->collection_info =
ax::android::mojom::AccessibilityCollectionInfoData::New();
mojom_out->collection_info->column_count =
proto_collection_info.column_count();
mojom_out->collection_info->row_count = proto_collection_info.row_count();
mojom_out->collection_info->is_hierarchical =
proto_collection_info.is_hierarchical();
auto collection_selection_mode =
ToMojomSelectionMode(proto_collection_info.selection_mode());
if (collection_selection_mode.has_value()) {
mojom_out->collection_info->selection_mode = *collection_selection_mode;
}
}
// Collection Item Info
if (proto_in.has_collection_item_info()) {
const auto& proto_collection_item_info = proto_in.collection_item_info();
mojom_out->collection_item_info =
ax::android::mojom::AccessibilityCollectionItemInfoData::New();
mojom_out->collection_item_info->row_index =
proto_collection_item_info.row_index();
mojom_out->collection_item_info->column_index =
proto_collection_item_info.column_index();
mojom_out->collection_item_info->row_span =
proto_collection_item_info.row_span();
mojom_out->collection_item_info->column_span =
proto_collection_item_info.column_span();
mojom_out->collection_item_info->is_heading =
proto_collection_item_info.is_heading();
mojom_out->collection_item_info->is_selected =
proto_collection_item_info.is_selected();
}
// Range info
if (proto_in.has_range_info()) {
if (proto_in.range_info().min() <= proto_in.range_info().max()) {
mojom_out->range_info->min = proto_in.range_info().min();
mojom_out->range_info->max = proto_in.range_info().max();
}
mojom_out->range_info->current = proto_in.range_info().current();
auto mojom_range_type =
ToMojomRangeType(proto_in.range_info().range_type());
if (mojom_range_type.has_value()) {
mojom_out->range_info->range_type = *mojom_range_type;
}
}
// Window Id
mojom_out->window_id = proto_in.window_id();
// Virtual Node
mojom_out->is_virtual_node = proto_in.is_virtual_node();
// Standard Actions
CopyRepeatedPtrFieldToOptionalVector(
proto_in.standard_actions(), mojom_out->standard_actions,
base::BindRepeating([](proto::AccessibilityActionInHost proto_action) {
auto result_ptr =
ax::android::mojom::AccessibilityActionInAndroid::New();
result_ptr->id = proto_action.id();
result_ptr->label = proto_action.label();
return result_ptr;
}));
// Custom Actions
CopyRepeatedPtrFieldToOptionalVector(
proto_in.custom_actions(), mojom_out->custom_actions,
base::BindRepeating([](proto::AccessibilityActionInHost proto_action) {
auto result_ptr =
ax::android::mojom::AccessibilityActionInAndroid::New();
result_ptr->id = proto_action.id();
result_ptr->label = proto_action.label();
return result_ptr;
}));
return mojom_out;
}
// Enum converters
std::optional<AXEventType> AccessibilityTreeConverter::ToMojomEventType(
const proto::AccessibilityEventType& event_type) {
switch (event_type) {
case proto::TYPE_VIEW_FOCUSED:
return AXEventType::VIEW_FOCUSED;
case proto::TYPE_VIEW_CLICKED:
return AXEventType::VIEW_CLICKED;
case proto::TYPE_VIEW_LONG_CLICKED:
return AXEventType::VIEW_LONG_CLICKED;
case proto::TYPE_VIEW_SELECTED:
return AXEventType::VIEW_SELECTED;
case proto::TYPE_VIEW_TEXT_CHANGED:
return AXEventType::VIEW_TEXT_CHANGED;
case proto::TYPE_WINDOW_STATE_CHANGED:
return AXEventType::WINDOW_STATE_CHANGED;
case proto::TYPE_VIEW_HOVER_ENTER:
return AXEventType::VIEW_HOVER_ENTER;
case proto::TYPE_VIEW_HOVER_EXIT:
return AXEventType::VIEW_HOVER_EXIT;
case proto::TYPE_TOUCH_EXPLORATION_GESTURE_START:
return AXEventType::TOUCH_EXPLORATION_GESTURE_START;
case proto::TYPE_TOUCH_EXPLORATION_GESTURE_END:
return AXEventType::TOUCH_EXPLORATION_GESTURE_END;
case proto::TYPE_WINDOW_CONTENT_CHANGED:
return AXEventType::WINDOW_CONTENT_CHANGED;
case proto::TYPE_VIEW_SCROLLED:
return AXEventType::VIEW_SCROLLED;
case proto::TYPE_VIEW_TEXT_SELECTION_CHANGED:
return AXEventType::VIEW_TEXT_SELECTION_CHANGED;
case proto::TYPE_ANNOUNCEMENT:
return AXEventType::ANNOUNCEMENT;
case proto::TYPE_VIEW_ACCESSIBILITY_FOCUSED:
return AXEventType::VIEW_ACCESSIBILITY_FOCUSED;
case proto::TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
return AXEventType::VIEW_ACCESSIBILITY_FOCUS_CLEARED;
case proto::TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
return AXEventType::VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
case proto::TYPE_GESTURE_DETECTION_START:
return AXEventType::GESTURE_DETECTION_START;
case proto::TYPE_GESTURE_DETECTION_END:
return AXEventType::GESTURE_DETECTION_END;
case proto::TYPE_TOUCH_INTERACTION_START:
return AXEventType::TOUCH_INTERACTION_START;
case proto::TYPE_TOUCH_INTERACTION_END:
return AXEventType::TOUCH_INTERACTION_END;
case proto::TYPE_WINDOWS_CHANGED:
return AXEventType::WINDOWS_CHANGED;
case proto::TYPE_VIEW_CONTEXT_CLICKED:
return AXEventType::VIEW_CONTEXT_CLICKED;
case proto::TYPE_ASSIST_READING_CONTEXT:
return AXEventType::ASSIST_READING_CONTEXT;
case proto::TYPE_EVENT_TYPE_UNKNOWN:
case proto::AccessibilityEventType_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityEventType_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXRangeType> AccessibilityTreeConverter::ToMojomRangeType(
const proto::AccessibilityRangeType range_type) {
switch (range_type) {
case proto::TYPE_INT:
return AXRangeType::INT;
case proto::TYPE_FLOAT:
return AXRangeType::FLOAT;
case proto::TYPE_PERCENT:
return AXRangeType::PERCENT;
case proto::AccessibilityRangeType_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityRangeType_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXSelectionMode> AccessibilityTreeConverter::ToMojomSelectionMode(
const proto::AccessibilitySelectionMode& selection_mode) {
switch (selection_mode) {
case proto::MODE_ACCESSIBILITY_SELECTION_MODE_NONE:
return AXSelectionMode::NONE;
case proto::MODE_SINGLE:
return AXSelectionMode::SINGLE;
case proto::MODE_MULTIPLE:
return AXSelectionMode::MULTIPLE;
case proto::AccessibilitySelectionMode_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilitySelectionMode_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXWindowType> AccessibilityTreeConverter::ToMojomWindowType(
const proto::AccessibilityWindowType& window_type) {
switch (window_type) {
case proto::TYPE_ACCESSIBILITY_OVERLAY:
return AXWindowType::TYPE_ACCESSIBILITY_OVERLAY;
case proto::TYPE_APPLICATION:
return AXWindowType::TYPE_APPLICATION;
case proto::TYPE_SPLIT_SCREEN_DIVIDER:
return AXWindowType::TYPE_SPLIT_SCREEN_DIVIDER;
case proto::TYPE_SYSTEM:
return AXWindowType::TYPE_SYSTEM;
case proto::TYPE_WINDOW_TYPE_UNKNOWN:
case proto::AccessibilityWindowType_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityWindowType_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXSpanType> AccessibilityTreeConverter::ToMojomSpanType(
const proto::SpanType& span_type) {
switch (span_type) {
case proto::TYPE_URL:
return AXSpanType::URL;
case proto::TYPE_SPAN_TYPE_CLICKABLE:
return AXSpanType::CLICKABLE;
case proto::SpanType_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::SpanType_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
// Property Converters
std::optional<AXEventIntProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityEventIntProperty& property) {
switch (property) {
case proto::PROPERTY_ACTION:
return AXEventIntProperty::ACTION;
case proto::PROPERTY_FROM_INDEX:
return AXEventIntProperty::FROM_INDEX;
case proto::PROPERTY_TO_INDEX:
return AXEventIntProperty::TO_INDEX;
case proto::PROPERTY_ITEM_COUNT:
return AXEventIntProperty::ITEM_COUNT;
case proto::PROPERTY_CURRENT_ITEM_INDEX:
return AXEventIntProperty::CURRENT_ITEM_INDEX;
case proto::PROPERTY_SCROLL_X:
return AXEventIntProperty::SCROLL_X;
case proto::PROPERTY_SCROLL_Y:
return AXEventIntProperty::SCROLL_Y;
case proto::PROPERTY_MAX_SCROLL_X:
return AXEventIntProperty::MAX_SCROLL_X;
case proto::PROPERTY_MAX_SCROLL_Y:
return AXEventIntProperty::MAX_SCROLL_Y;
case proto::PROPERTY_SCROLL_DELTA_X:
return AXEventIntProperty::SCROLL_DELTA_X;
case proto::PROPERTY_SCROLL_DELTA_Y:
return AXEventIntProperty::SCROLL_DELTA_Y;
case proto::AccessibilityEventIntProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityEventIntProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXEventIntListProperty>
AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityEventIntListProperty& property) {
switch (property) {
case proto::PROPERTY_CONTENT_CHANGE_TYPES:
return AXEventIntListProperty::CONTENT_CHANGE_TYPES;
case proto::AccessibilityEventIntListProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityEventIntListProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXEventStringProperty>
AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityEventStringProperty& property) {
switch (property) {
case proto::PROPERTY_ACCESSIBILITY_EVENT_CLASS_NAME:
return AXEventStringProperty::CLASS_NAME;
case proto::PROPERTY_ACCESSIBILITY_EVENT_PACKAGE_NAME:
return AXEventStringProperty::PACKAGE_NAME;
case proto::PROPERTY_ACCESSIBILITY_EVENT_CONTENT_DESCRIPTION:
return AXEventStringProperty::CONTENT_DESCRIPTION;
case proto::AccessibilityEventStringProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityEventStringProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXIntProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityIntProperty& property) {
switch (property) {
case proto::PROPERTY_LABEL_FOR:
return AXIntProperty::LABEL_FOR;
case proto::PROPERTY_LABELED_BY:
return AXIntProperty::LABELED_BY;
case proto::PROPERTY_TRAVERSAL_BEFORE:
return AXIntProperty::TRAVERSAL_BEFORE;
case proto::PROPERTY_TRAVERSAL_AFTER:
return AXIntProperty::TRAVERSAL_AFTER;
case proto::PROPERTY_MAX_TEXT_LENGTH:
return AXIntProperty::MAX_TEXT_LENGTH;
case proto::PROPERTY_TEXT_SELECTION_START:
return AXIntProperty::TEXT_SELECTION_START;
case proto::PROPERTY_TEXT_SELECTION_END:
return AXIntProperty::TEXT_SELECTION_END;
case proto::PROPERTY_INPUT_TYPE:
return AXIntProperty::INPUT_TYPE;
case proto::PROPERTY_LIVE_REGION:
return AXIntProperty::LIVE_REGION;
case proto::AccessibilityIntProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityIntProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXIntListProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityIntListProperty& property) {
switch (property) {
case proto::PROPERTY_CHILD_NODE_IDS:
return AXIntListProperty::CHILD_NODE_IDS;
case proto::AccessibilityIntListProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityIntListProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXStringProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityStringProperty& property) {
switch (property) {
case proto::PROPERTY_ACCESSIBILITY_PACKAGE_NAME:
return AXStringProperty::PACKAGE_NAME;
case proto::PROPERTY_ACCESSIBILITY_CLASS_NAME:
return AXStringProperty::CLASS_NAME;
case proto::PROPERTY_ACCESSIBILITY_TEXT:
return AXStringProperty::TEXT;
case proto::PROPERTY_ACCESSIBILITY_CONTENT_DESCRIPTION:
return AXStringProperty::CONTENT_DESCRIPTION;
case proto::PROPERTY_VIEW_ID_RESOURCE_NAME:
return AXStringProperty::VIEW_ID_RESOURCE_NAME;
case proto::PROPERTY_CHROME_ROLE:
return AXStringProperty::CHROME_ROLE;
case proto::PROPERTY_ROLE_DESCRIPTION:
return AXStringProperty::ROLE_DESCRIPTION;
case proto::PROPERTY_TOOLTIP:
return AXStringProperty::TOOLTIP;
case proto::PROPERTY_ACCESSIBILITY_PANE_TITLE:
return AXStringProperty::PANE_TITLE;
case proto::PROPERTY_HINT_TEXT:
return AXStringProperty::HINT_TEXT;
case proto::PROPERTY_ACCESSIBILITY_STATE_DESCRIPTION:
return AXStringProperty::STATE_DESCRIPTION;
case proto::AccessibilityStringProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityStringProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXBoolProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityBooleanProperty& property) {
switch (property) {
case proto::PROPERTY_CHECKABLE:
return AXBoolProperty::CHECKABLE;
case proto::PROPERTY_CHECKED:
return AXBoolProperty::CHECKED;
case proto::PROPERTY_FOCUSABLE:
return AXBoolProperty::FOCUSABLE;
case proto::PROPERTY_ACCESSIBILITY_BOOLEAN_PROPERTY_FOCUSED:
return AXBoolProperty::ACCESSIBILITY_FOCUSED;
case proto::PROPERTY_SELECTED:
return AXBoolProperty::SELECTED;
case proto::PROPERTY_ACCESSIBILITY_BOOLEAN_CLICKABLE:
return AXBoolProperty::CLICKABLE;
case proto::PROPERTY_LONG_CLICKABLE:
return AXBoolProperty::LONG_CLICKABLE;
case proto::PROPERTY_ENABLED:
return AXBoolProperty::ENABLED;
case proto::PROPERTY_PASSWORD:
return AXBoolProperty::PASSWORD;
case proto::PROPERTY_SCROLLABLE:
return AXBoolProperty::SCROLLABLE;
case proto::PROPERTY_ACCESSIBILITY_BOOLEAN_FOCUSED:
return AXBoolProperty::FOCUSED;
case proto::PROPERTY_VISIBLE_TO_USER:
return AXBoolProperty::VISIBLE_TO_USER;
case proto::PROPERTY_EDITABLE:
return AXBoolProperty::EDITABLE;
case proto::PROPERTY_OPENS_POPUP:
return AXBoolProperty::OPENS_POPUP;
case proto::PROPERTY_DISMISSABLE:
return AXBoolProperty::DISMISSABLE;
case proto::PROPERTY_MULTI_LINE:
return AXBoolProperty::MULTI_LINE;
case proto::PROPERTY_CONTENT_INVALID:
return AXBoolProperty::CONTENT_INVALID;
case proto::PROPERTY_CONTEXT_CLICKABLE:
return AXBoolProperty::CONTEXT_CLICKABLE;
case proto::PROPERTY_IMPORTANCE:
return AXBoolProperty::IMPORTANCE;
case proto::PROPERTY_SCREEN_READER_FOCUSABLE:
return AXBoolProperty::SCREEN_READER_FOCUSABLE;
case proto::PROPERTY_SHOWING_HINT_TEXT:
return AXBoolProperty::SHOWING_HINT_TEXT;
case proto::PROPERTY_HEADING:
return AXBoolProperty::HEADING;
case proto::PROPERTY_SUPPORTS_TEXT_LOCATION:
return AXBoolProperty::SUPPORTS_TEXT_LOCATION;
case proto::AccessibilityBooleanProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityBooleanProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXWindowIntProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityWindowIntProperty& property) {
switch (property) {
case proto::PROPERTY_ANCHOR_NODE_ID:
return AXWindowIntProperty::ANCHOR_NODE_ID;
case proto::PROPERTY_LAYER_ORDER:
return AXWindowIntProperty::LAYER_ORDER;
case proto::PROPERTY_PARENT_WINDOW_ID:
return AXWindowIntProperty::PARENT_WINDOW_ID;
case proto::AccessibilityWindowIntProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityWindowIntProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXWindowIntListProperty>
AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityWindowIntListProperty& property) {
switch (property) {
case proto::PROPERTY_CHILD_WINDOW_IDS:
return AXWindowIntListProperty::CHILD_WINDOW_IDS;
case proto::AccessibilityWindowIntListProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityWindowIntListProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXWindowStringProperty>
AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityWindowStringProperty& property) {
switch (property) {
case proto::PROPERTY_TITLE:
return AXWindowStringProperty::TITLE;
case proto::AccessibilityWindowStringProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityWindowStringProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
std::optional<AXWindowBoolProperty> AccessibilityTreeConverter::ToMojomProperty(
const proto::AccessibilityWindowBooleanProperty& property) {
switch (property) {
case proto::PROPERTY_ACCESSIBILITY_FOCUSED:
return AXWindowBoolProperty::ACCESSIBILITY_FOCUSED;
case proto::PROPERTY_FOCUSED:
return AXWindowBoolProperty::FOCUSED;
case proto::PROPERTY_IN_PICTURE_IN_PICTURE_MODE:
return AXWindowBoolProperty::IN_PICTURE_IN_PICTURE_MODE;
case proto::PROPERTY_WINDOW_ACTIVE:
return AXWindowBoolProperty::WINDOW_ACTIVE;
case proto::AccessibilityWindowBooleanProperty_INT_MIN_SENTINEL_DO_NOT_USE_:
case proto::AccessibilityWindowBooleanProperty_INT_MAX_SENTINEL_DO_NOT_USE_:
break;
}
return std::nullopt;
}
} // namespace ash::eche_app