Skip to main content

ferroui_android/automation/
node_info.rs

1//! What a node of the accessibility tree of the system says: the values
2//! the access helper and the node info providers set, kept as plain data
3//! and written to the `AccessibilityNodeInfo` of the system in one place
4//! (`ferro_access_helper.rs`). It stands for the compatibility wrapper of
5//! a node the reference fills, and it is what the tests of the crate read.
6//! The constants are those of the Android framework.
7
8/// `AccessibilityNodeInfo.ACTION_FOCUS`.
9pub const ACTION_FOCUS: i32 = 1;
10/// `AccessibilityNodeInfo.ACTION_CLEAR_FOCUS`.
11pub const ACTION_CLEAR_FOCUS: i32 = 2;
12/// `AccessibilityNodeInfo.ACTION_SELECT`.
13pub const ACTION_SELECT: i32 = 4;
14/// `AccessibilityNodeInfo.ACTION_CLICK`.
15pub const ACTION_CLICK: i32 = 16;
16/// `AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS`.
17pub const ACTION_ACCESSIBILITY_FOCUS: i32 = 64;
18/// `AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS`.
19pub const ACTION_CLEAR_ACCESSIBILITY_FOCUS: i32 = 128;
20/// `AccessibilityNodeInfo.ACTION_SCROLL_FORWARD`.
21pub const ACTION_SCROLL_FORWARD: i32 = 4096;
22/// `AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD`.
23pub const ACTION_SCROLL_BACKWARD: i32 = 8192;
24/// `AccessibilityNodeInfo.ACTION_EXPAND`.
25pub const ACTION_EXPAND: i32 = 262144;
26/// `AccessibilityNodeInfo.ACTION_COLLAPSE`.
27pub const ACTION_COLLAPSE: i32 = 524288;
28/// `AccessibilityNodeInfo.ACTION_SET_TEXT`.
29pub const ACTION_SET_TEXT: i32 = 2097152;
30
31/// `AccessibilityNodeInfo.FOCUS_INPUT`.
32pub const FOCUS_INPUT: i32 = 1;
33/// `AccessibilityNodeInfo.FOCUS_ACCESSIBILITY`.
34pub const FOCUS_ACCESSIBILITY: i32 = 2;
35
36/// `AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_FLOAT`.
37pub const RANGE_TYPE_FLOAT: i32 = 1;
38
39/// `AccessibilityNodeInfo.CHECKED_STATE_FALSE`, `_TRUE` and `_PARTIAL`.
40pub const CHECKED_STATE_FALSE: i32 = 0;
41pub const CHECKED_STATE_TRUE: i32 = 1;
42pub const CHECKED_STATE_PARTIAL: i32 = 2;
43
44/// `AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED`, `_SUBTREE`, `_TEXT`
45/// and `_CONTENT_DESCRIPTION`.
46pub const CONTENT_CHANGE_TYPE_UNDEFINED: i32 = 0;
47pub const CONTENT_CHANGE_TYPE_SUBTREE: i32 = 1;
48pub const CONTENT_CHANGE_TYPE_TEXT: i32 = 2;
49pub const CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION: i32 = 4;
50
51/// `View.ACCESSIBILITY_LIVE_REGION_NONE` and `_POLITE`.
52pub const ACCESSIBILITY_LIVE_REGION_NONE: i32 = 0;
53pub const ACCESSIBILITY_LIVE_REGION_POLITE: i32 = 1;
54
55/// The class name of a node nobody gave one.
56pub const DEFAULT_CLASS_NAME: &str = "android.view.View";
57
58/// The range of a node (`AccessibilityNodeInfo.RangeInfo`).
59#[derive(Clone, Copy, Debug, PartialEq)]
60pub struct RangeInfo {
61    pub range_type: i32,
62    pub min: f32,
63    pub max: f32,
64    pub current: f32,
65}
66
67/// The values of a node of a virtual view.
68#[derive(Clone, Debug, PartialEq)]
69pub struct NodeInfo {
70    /// The virtual views that are the children of the node, in order.
71    pub children: Vec<i32>,
72    /// The virtual views that label the node.
73    pub labeled_by: Vec<i32>,
74    pub class_name: Option<String>,
75    pub unique_id: Option<String>,
76    pub view_id_resource_name: Option<String>,
77    pub enabled: bool,
78    pub screen_reader_focusable: bool,
79    pub focusable: bool,
80    pub accessibility_focused: bool,
81    pub focused: bool,
82    /// Left, top, right and bottom on the screen; `None` until set.
83    pub bounds_in_screen: Option<(i32, i32, i32, i32)>,
84    pub text: Option<String>,
85    pub content_description: Option<String>,
86    /// The actions of the node, each once, in the order they were added.
87    pub actions: Vec<i32>,
88    pub clickable: bool,
89    pub checkable: bool,
90    /// One of the checked states.
91    pub checked: i32,
92    pub scrollable: bool,
93    pub selected: bool,
94    pub editable: bool,
95    pub range_info: Option<RangeInfo>,
96    /// The start and the end of the selection of the text.
97    pub text_selection: Option<(i32, i32)>,
98    pub live_region: i32,
99}
100
101impl Default for NodeInfo {
102    fn default() -> Self {
103        Self::new()
104    }
105}
106
107impl NodeInfo {
108    /// A node as the system obtains it: nothing set.
109    pub fn new() -> Self {
110        Self {
111            children: Vec::new(),
112            labeled_by: Vec::new(),
113            class_name: None,
114            unique_id: None,
115            view_id_resource_name: None,
116            enabled: false,
117            screen_reader_focusable: false,
118            focusable: false,
119            accessibility_focused: false,
120            focused: false,
121            bounds_in_screen: None,
122            text: None,
123            content_description: None,
124            actions: Vec::new(),
125            clickable: false,
126            checkable: false,
127            checked: CHECKED_STATE_FALSE,
128            scrollable: false,
129            selected: false,
130            editable: false,
131            range_info: None,
132            text_selection: None,
133            live_region: ACCESSIBILITY_LIVE_REGION_NONE,
134        }
135    }
136
137    /// Adds an action to the node; an action the node has is not added
138    /// again.
139    pub fn add_action(&mut self, action: i32) {
140        if !self.actions.contains(&action) {
141            self.actions.push(action);
142        }
143    }
144
145    /// Whether the node has the action.
146    pub fn has_action(&self, action: i32) -> bool {
147        self.actions.contains(&action)
148    }
149
150    /// The actions of the node as the bit mask the system reports.
151    pub fn action_mask(&self) -> i32 {
152        self.actions.iter().fold(0, |mask, action| mask | action)
153    }
154}