blob: 3f73562467aecdd7637d613518b2289795ae956e [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h"
#include "chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.h"
#include "base/optional.h"
#include "components/arc/mojom/accessibility_helper.mojom.h"
#include "ui/accessibility/ax_enums.mojom.h"
namespace arc {
using AXActionType = mojom::AccessibilityActionType;
using AXBooleanProperty = mojom::AccessibilityBooleanProperty;
using AXIntListProperty = mojom::AccessibilityIntListProperty;
using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
using AXStringProperty = mojom::AccessibilityStringProperty;
base::Optional<ax::mojom::Event> FromContentChangeTypesToAXEvent(
const std::vector<int32_t>& arc_content_change_types,
const AccessibilityInfoDataWrapper& source_node) {
if (!base::Contains(
arc_content_change_types,
static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION))) {
return base::nullopt;
}
const AXNodeInfoData* node_ptr = source_node.GetNode();
if (node_ptr && node_ptr->range_info) {
return ax::mojom::Event::kValueChanged;
} else {
return ax::mojom::Event::kAriaAttributeChanged;
}
}
ax::mojom::Event ToAXEvent(
mojom::AccessibilityEventType arc_event_type,
const base::Optional<std::vector<int>>& arc_content_change_types,
AccessibilityInfoDataWrapper* source_node,
AccessibilityInfoDataWrapper* focused_node) {
switch (arc_event_type) {
case mojom::AccessibilityEventType::VIEW_FOCUSED:
case mojom::AccessibilityEventType::VIEW_ACCESSIBILITY_FOCUSED:
return ax::mojom::Event::kFocus;
case mojom::AccessibilityEventType::VIEW_CLICKED:
case mojom::AccessibilityEventType::VIEW_LONG_CLICKED:
return ax::mojom::Event::kClicked;
case mojom::AccessibilityEventType::VIEW_TEXT_CHANGED:
return ax::mojom::Event::kTextChanged;
case mojom::AccessibilityEventType::VIEW_TEXT_SELECTION_CHANGED:
return ax::mojom::Event::kTextSelectionChanged;
case mojom::AccessibilityEventType::WINDOW_STATE_CHANGED: {
if (source_node && arc_content_change_types.has_value()) {
const base::Optional<ax::mojom::Event> event_or_null =
FromContentChangeTypesToAXEvent(arc_content_change_types.value(),
*source_node);
if (event_or_null.has_value()) {
return event_or_null.value();
}
}
if (focused_node)
return ax::mojom::Event::kFocus;
else
return ax::mojom::Event::kLayoutComplete;
}
case mojom::AccessibilityEventType::NOTIFICATION_STATE_CHANGED:
return ax::mojom::Event::kLayoutComplete;
case mojom::AccessibilityEventType::WINDOW_CONTENT_CHANGED:
if (source_node && arc_content_change_types.has_value()) {
const base::Optional<ax::mojom::Event> event_or_null =
FromContentChangeTypesToAXEvent(arc_content_change_types.value(),
*source_node);
if (event_or_null.has_value()) {
return event_or_null.value();
}
}
return ax::mojom::Event::kLayoutComplete;
case mojom::AccessibilityEventType::WINDOWS_CHANGED:
return ax::mojom::Event::kLayoutComplete;
case mojom::AccessibilityEventType::VIEW_HOVER_ENTER:
return ax::mojom::Event::kHover;
case mojom::AccessibilityEventType::ANNOUNCEMENT: {
// NOTE: Announcement event is handled in
// ArcAccessibilityHelperBridge::OnAccessibilityEvent.
NOTREACHED();
break;
}
case mojom::AccessibilityEventType::VIEW_SCROLLED:
return ax::mojom::Event::kScrollPositionChanged;
case mojom::AccessibilityEventType::VIEW_SELECTED: {
// VIEW_SELECTED event is not selection event in Chrome.
// See the comment on AXTreeSourceArc::NotifyAccessibilityEvent.
if (source_node && source_node->IsNode() &&
source_node->GetNode()->range_info) {
return ax::mojom::Event::kValueChanged;
} else {
return ax::mojom::Event::kFocus;
}
}
case mojom::AccessibilityEventType::VIEW_HOVER_EXIT:
case mojom::AccessibilityEventType::TOUCH_EXPLORATION_GESTURE_START:
case mojom::AccessibilityEventType::TOUCH_EXPLORATION_GESTURE_END:
case mojom::AccessibilityEventType::
VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
case mojom::AccessibilityEventType::GESTURE_DETECTION_START:
case mojom::AccessibilityEventType::GESTURE_DETECTION_END:
case mojom::AccessibilityEventType::TOUCH_INTERACTION_START:
case mojom::AccessibilityEventType::TOUCH_INTERACTION_END:
case mojom::AccessibilityEventType::VIEW_CONTEXT_CLICKED:
case mojom::AccessibilityEventType::ASSIST_READING_CONTEXT:
return ax::mojom::Event::kChildrenChanged;
default:
return ax::mojom::Event::kChildrenChanged;
}
return ax::mojom::Event::kChildrenChanged;
}
base::Optional<mojom::AccessibilityActionType> ConvertToAndroidAction(
ax::mojom::Action action) {
switch (action) {
case ax::mojom::Action::kDoDefault:
return arc::mojom::AccessibilityActionType::CLICK;
case ax::mojom::Action::kFocus:
// Fallthrough
case ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint:
return arc::mojom::AccessibilityActionType::ACCESSIBILITY_FOCUS;
case ax::mojom::Action::kScrollToMakeVisible:
return arc::mojom::AccessibilityActionType::SHOW_ON_SCREEN;
case ax::mojom::Action::kScrollBackward:
return arc::mojom::AccessibilityActionType::SCROLL_BACKWARD;
case ax::mojom::Action::kScrollForward:
return arc::mojom::AccessibilityActionType::SCROLL_FORWARD;
case ax::mojom::Action::kScrollUp:
return arc::mojom::AccessibilityActionType::SCROLL_UP;
case ax::mojom::Action::kScrollDown:
return arc::mojom::AccessibilityActionType::SCROLL_DOWN;
case ax::mojom::Action::kScrollLeft:
return arc::mojom::AccessibilityActionType::SCROLL_LEFT;
case ax::mojom::Action::kScrollRight:
return arc::mojom::AccessibilityActionType::SCROLL_RIGHT;
case ax::mojom::Action::kCustomAction:
return arc::mojom::AccessibilityActionType::CUSTOM_ACTION;
case ax::mojom::Action::kSetAccessibilityFocus:
return arc::mojom::AccessibilityActionType::ACCESSIBILITY_FOCUS;
case ax::mojom::Action::kClearAccessibilityFocus:
return arc::mojom::AccessibilityActionType::CLEAR_ACCESSIBILITY_FOCUS;
case ax::mojom::Action::kGetTextLocation:
return arc::mojom::AccessibilityActionType::GET_TEXT_LOCATION;
case ax::mojom::Action::kShowTooltip:
return arc::mojom::AccessibilityActionType::SHOW_TOOLTIP;
case ax::mojom::Action::kHideTooltip:
return arc::mojom::AccessibilityActionType::HIDE_TOOLTIP;
case ax::mojom::Action::kCollapse:
return arc::mojom::AccessibilityActionType::COLLAPSE;
case ax::mojom::Action::kExpand:
return arc::mojom::AccessibilityActionType::EXPAND;
default:
return base::nullopt;
}
}
std::string ToLiveStatusString(mojom::AccessibilityLiveRegionType type) {
switch (type) {
case mojom::AccessibilityLiveRegionType::NONE:
return "none";
case mojom::AccessibilityLiveRegionType::POLITE:
return "polite";
case mojom::AccessibilityLiveRegionType::ASSERTIVE:
return "assertive";
default:
NOTREACHED();
}
return std::string(); // Placeholder.
}
} // namespace arc