1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "js_accessibility_manager.h"
17
18 #include "accessibility_system_ability_client.h"
19 #include "js_third_provider_interaction_operation.h"
20 #include "perf_monitor_adapter.h"
21
22 #include "adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h"
23 #include "adapter/ohos/entrance/ace_container.h"
24 #include "base/log/event_report.h"
25 #include "core/components_ng/pattern/scrollable/scrollable_utils.h"
26 #include "core/components_ng/base/frame_node.h"
27 #include "frameworks/core/accessibility/hidumper/accessibility_hidumper.h"
28 #include "frameworks/core/accessibility/utils/accessibility_action_function_utils.h"
29 #include "frameworks/core/components_ng/pattern/ui_extension/platform_container_handler.h"
30 #include "frameworks/core/components_ng/pattern/overlay/accessibility_focus_paint_node_pattern.h"
31 #include "frameworks/core/components_ng/pattern/web/transitional_node_info.h"
32 #include "frameworks/core/components_ng/pattern/web/web_pattern.h"
33
34 using namespace OHOS::Accessibility;
35 using namespace OHOS::AccessibilityConfig;
36
37 namespace OHOS::Ace::Framework {
38 namespace {
39 const char DUMP_ORDER[] = "-accessibility";
40 const char DUMP_INSPECTOR[] = "-inspector";
41 const char ACCESSIBILITY_FOCUSED_EVENT[] = "accessibilityfocus";
42 const char ACCESSIBILITY_CLEAR_FOCUS_EVENT[] = "accessibilityclearfocus";
43 const char TEXT_CHANGE_EVENT[] = "textchange";
44 const char PAGE_CHANGE_EVENT[] = "pagechange";
45 const char SCROLL_END_EVENT[] = "scrollend";
46 const char SCROLL_START_EVENT[] = "scrollstart";
47 const char MOUSE_HOVER_ENTER[] = "mousehoverenter";
48 const char MOUSE_HOVER_EXIT[] = "mousehoverexit";
49 const char LIST_TAG[] = "List";
50 const char SIDEBARCONTAINER_TAG[] = "SideBarContainer";
51 const char STRING_DIR_FORWARD[] = "forward";
52 const char STRING_DIR_BACKWARD[] = "backward";
53 constexpr int32_t INVALID_PARENT_ID = -2100000;
54 constexpr int32_t DEFAULT_PARENT_ID = 2100000;
55 constexpr int32_t ROOT_STACK_BASE = 1100000;
56 constexpr int32_t ROOT_DECOR_BASE = 3100000;
57 constexpr int32_t CARD_NODE_ID_RATION = 10000;
58 constexpr int32_t CARD_ROOT_NODE_ID_RATION = 1000;
59 constexpr int32_t CARD_BASE = 100000;
60 constexpr int32_t DELAY_SEND_EVENT_MILLISECOND = 20;
61 constexpr uint32_t SUB_TREE_OFFSET_IN_PAGE_ID = 16;
62 constexpr int32_t MAX_PAGE_ID_WITH_SUB_TREE = (1 << SUB_TREE_OFFSET_IN_PAGE_ID);
63 constexpr int32_t MIN_NUM = 2;
64 constexpr size_t MIN_PARAMS_SIZE = 2;
65 constexpr int64_t INVALID_NODE_ID = -1;
66
67 const std::string ACTION_ARGU_SCROLL_STUB = "scrolltype"; // wait for change
68 const std::string ACTION_DEFAULT_PARAM = "ACCESSIBILITY_ACTION_INVALID";
69
70 const std::set<std::string> TAGS_EMBED_COMPONENT = {
71 "embeddedObject",
72 };
73
74 const std::map<Accessibility::ActionType, std::function<bool(const AccessibilityActionParam& param)>> ACTIONS = {
75 { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD,
__anoncb62e46e0202() 76 [](const AccessibilityActionParam& param) {
77 return param.accessibilityProperty->ActActionScrollForward(param.scrollType);
78 } },
79 { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD,
__anoncb62e46e0302() 80 [](const AccessibilityActionParam& param) {
81 return param.accessibilityProperty->ActActionScrollBackward(param.scrollType);
82 } },
83 { ActionType::ACCESSIBILITY_ACTION_SET_TEXT,
__anoncb62e46e0402() 84 [](const AccessibilityActionParam& param) {
85 return param.accessibilityProperty->ActActionSetText(param.setTextArgument);
86 } },
87 { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION,
__anoncb62e46e0502() 88 [](const AccessibilityActionParam& param) {
89 return param.accessibilityProperty->ActActionSetSelection(param.setSelectionStart,
90 param.setSelectionEnd, param.setSelectionDir);
91 } },
92 { ActionType::ACCESSIBILITY_ACTION_COPY,
__anoncb62e46e0602() 93 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionCopy(); } },
94 { ActionType::ACCESSIBILITY_ACTION_CUT,
__anoncb62e46e0702() 95 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionCut(); } },
96 { ActionType::ACCESSIBILITY_ACTION_PASTE,
__anoncb62e46e0802() 97 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionPaste(); } },
98 { ActionType::ACCESSIBILITY_ACTION_CLICK,
__anoncb62e46e0902() 99 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionClick(); } },
100 { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK,
__anoncb62e46e0a02() 101 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionLongClick(); } },
102 { ActionType::ACCESSIBILITY_ACTION_SELECT,
__anoncb62e46e0b02() 103 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionSelect(); } },
104 { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION,
__anoncb62e46e0c02() 105 [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionClearSelection(); } },
106 { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT,
__anoncb62e46e0d02() 107 [](const AccessibilityActionParam& param) {
108 return param.accessibilityProperty->ActActionMoveText(static_cast<int32_t>(param.moveUnit), true);
109 } },
110 { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT,
__anoncb62e46e0e02() 111 [](const AccessibilityActionParam& param) {
112 return param.accessibilityProperty->ActActionMoveText(static_cast<int32_t>(param.moveUnit), false);
113 } },
114 { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION,
__anoncb62e46e0f02() 115 [](const AccessibilityActionParam& param) {
116 return param.accessibilityProperty->ActActionSetIndex(static_cast<int32_t>(param.setCursorIndex));
117 } },
118 { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK,
__anoncb62e46e1002() 119 [](const AccessibilityActionParam& param) {
120 return param.accessibilityProperty->ActActionExecSubComponent(static_cast<int32_t>(param.spanId));
121 } },
122 };
123
IsDynamicComponent(const RefPtr<NG::UINode> & node)124 bool IsDynamicComponent(const RefPtr<NG::UINode>& node)
125 {
126 return node && (node->GetTag() == V2::DYNAMIC_COMPONENT_ETS_TAG);
127 }
128
IsExtensionComponent(const RefPtr<NG::UINode> & node)129 bool IsExtensionComponent(const RefPtr<NG::UINode>& node)
130 {
131 return node && (node->GetTag() == V2::UI_EXTENSION_COMPONENT_ETS_TAG
132 || node->GetTag() == V2::EMBEDDED_COMPONENT_ETS_TAG
133 || node->GetTag() == V2::ISOLATED_COMPONENT_ETS_TAG);
134 }
135
IsIsolatedComponent(const RefPtr<NG::UINode> & node)136 bool IsIsolatedComponent(const RefPtr<NG::UINode>& node)
137 {
138 return node && (node->GetTag() == V2::ISOLATED_COMPONENT_ETS_TAG);
139 }
140
IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode> & node)141 bool IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode>& node)
142 {
143 CHECK_NULL_RETURN(node, true);
144 if (node->GetTag() == V2::ISOLATED_COMPONENT_ETS_TAG) {
145 return false;
146 }
147 #ifdef WINDOW_SCENE_SUPPORTED
148 auto pipeline = node->GetContextRefPtr();
149 CHECK_NULL_RETURN(pipeline, true);
150 auto manager = pipeline->GetUIExtensionManager();
151 CHECK_NULL_RETURN(manager, true);
152 return manager->IsShowPlaceholder(node->GetId());
153 #endif
154 return true;
155 }
156
NeedUpdateChildrenOfAccessibilityElementInfo(const RefPtr<NG::UINode> & node)157 bool NeedUpdateChildrenOfAccessibilityElementInfo(const RefPtr<NG::UINode>& node)
158 {
159 return !IsDynamicComponent(node);
160 }
161
CheckChildIsAccessibilityFocus(const RefPtr<NG::UINode> & uiNode,RefPtr<NG::FrameNode> & focusFrameNode)162 bool CheckChildIsAccessibilityFocus(const RefPtr<NG::UINode> &uiNode, RefPtr<NG::FrameNode> &focusFrameNode)
163 {
164 CHECK_NULL_RETURN(uiNode, false);
165 auto nowFrameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
166 if (nowFrameNode) {
167 auto accessibilityProperty = nowFrameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
168 if (accessibilityProperty) {
169 auto isFocus = accessibilityProperty->GetAccessibilityFocusState();
170 if (isFocus) {
171 focusFrameNode = nowFrameNode;
172 return true;
173 }
174 }
175 }
176 auto children = uiNode->GetChildren(true);
177 for (const auto& child : children) {
178 if (CheckChildIsAccessibilityFocus(child, focusFrameNode)) {
179 return true;
180 }
181 }
182 return false;
183 }
184
UpdatePaintNodeRender(const RefPtr<NG::FrameNode> & focusNode)185 void UpdatePaintNodeRender(const RefPtr<NG::FrameNode>& focusNode)
186 {
187 CHECK_NULL_VOID(focusNode);
188 ACE_SCOPED_TRACE("Node[%s] UpdatePaintNodeRender", focusNode->GetTag().c_str());
189 auto paintNode = focusNode->GetPaintNode();
190 CHECK_NULL_VOID(paintNode);
191 auto pattern = paintNode->GetPattern<NG::AccessibilityFocusPaintNodePattern>();
192 CHECK_NULL_VOID(pattern);
193 pattern->UpdateRenderWithFocusNode();
194 auto renderContext = paintNode->GetRenderContext();
195 CHECK_NULL_VOID(renderContext);
196 auto accessibilityProperty = focusNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
197 CHECK_NULL_VOID(accessibilityProperty);
198
199 if (accessibilityProperty->IsMatchAccessibilityResponseRegion(false)) {
200 auto rectInt = accessibilityProperty->GetAccessibilityResponseRegionRect(false);
201 renderContext->UpdateAccessibilityFocusRect(rectInt);
202 } else {
203 renderContext->UpdateAccessibilityRoundRect();
204 }
205 }
206
ConvertStrToEventType(const std::string & type)207 Accessibility::EventType ConvertStrToEventType(const std::string& type)
208 {
209 // static linear map must be sorted by key.
210 static const LinearMapNode<Accessibility::EventType> eventTypeMap[] = {
211 { ACCESSIBILITY_CLEAR_FOCUS_EVENT, Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT },
212 { ACCESSIBILITY_FOCUSED_EVENT, Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUSED_EVENT },
213 { DOM_CLICK, Accessibility::EventType::TYPE_VIEW_CLICKED_EVENT },
214 { DOM_FOCUS, Accessibility::EventType::TYPE_VIEW_FOCUSED_EVENT },
215 { DOM_LONG_PRESS, Accessibility::EventType::TYPE_VIEW_LONG_CLICKED_EVENT },
216 { MOUSE_HOVER_ENTER, Accessibility::EventType::TYPE_VIEW_HOVER_ENTER_EVENT },
217 { MOUSE_HOVER_EXIT, Accessibility::EventType::TYPE_VIEW_HOVER_EXIT_EVENT },
218 { PAGE_CHANGE_EVENT, Accessibility::EventType::TYPE_PAGE_STATE_UPDATE },
219 { SCROLL_END_EVENT, Accessibility::EventType::TYPE_VIEW_SCROLLED_EVENT },
220 { SCROLL_START_EVENT, Accessibility::EventType::TYPE_VIEW_SCROLLED_START },
221 { DOM_SELECTED, Accessibility::EventType::TYPE_VIEW_SELECTED_EVENT },
222 { TEXT_CHANGE_EVENT, Accessibility::EventType::TYPE_VIEW_TEXT_UPDATE_EVENT },
223 { DOM_TOUCH_END, Accessibility::EventType::TYPE_TOUCH_END },
224 { DOM_TOUCH_START, Accessibility::EventType::TYPE_TOUCH_BEGIN },
225 };
226 Accessibility::EventType eventType = Accessibility::EventType::TYPE_VIEW_INVALID;
227 int64_t idx = BinarySearchFindIndex(eventTypeMap, ArraySize(eventTypeMap), type.c_str());
228 if (idx >= 0) {
229 eventType = eventTypeMap[idx].value;
230 }
231 return eventType;
232 }
233
ConvertAceEventType(AccessibilityEventType type)234 Accessibility::EventType ConvertAceEventType(AccessibilityEventType type)
235 {
236 static const LinearEnumMapNode<AccessibilityEventType, Accessibility::EventType> eventTypeMap[] = {
237 { AccessibilityEventType::CLICK, Accessibility::EventType::TYPE_VIEW_CLICKED_EVENT },
238 { AccessibilityEventType::LONG_PRESS, Accessibility::EventType::TYPE_VIEW_LONG_CLICKED_EVENT },
239 { AccessibilityEventType::SELECTED, Accessibility::EventType::TYPE_VIEW_SELECTED_EVENT },
240 { AccessibilityEventType::FOCUS, Accessibility::EventType::TYPE_VIEW_FOCUSED_EVENT },
241 { AccessibilityEventType::TEXT_CHANGE, Accessibility::EventType::TYPE_VIEW_TEXT_UPDATE_EVENT },
242 { AccessibilityEventType::HOVER_ENTER_EVENT, Accessibility::EventType::TYPE_VIEW_HOVER_ENTER_EVENT },
243 { AccessibilityEventType::PAGE_CHANGE, Accessibility::EventType::TYPE_PAGE_STATE_UPDATE },
244 { AccessibilityEventType::HOVER_EXIT_EVENT, Accessibility::EventType::TYPE_VIEW_HOVER_EXIT_EVENT },
245 { AccessibilityEventType::CHANGE, Accessibility::EventType::TYPE_PAGE_CONTENT_UPDATE },
246 { AccessibilityEventType::COMPONENT_CHANGE, Accessibility::EventType::TYPE_VIEW_TEXT_UPDATE_EVENT },
247 { AccessibilityEventType::SCROLL_END, Accessibility::EventType::TYPE_VIEW_SCROLLED_EVENT },
248 { AccessibilityEventType::TEXT_SELECTION_UPDATE,
249 Accessibility::EventType::TYPE_VIEW_TEXT_SELECTION_UPDATE_EVENT },
250 { AccessibilityEventType::ACCESSIBILITY_FOCUSED,
251 Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUSED_EVENT },
252 { AccessibilityEventType::ACCESSIBILITY_FOCUS_CLEARED,
253 Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT },
254 { AccessibilityEventType::TEXT_MOVE_UNIT, Accessibility::EventType::TYPE_VIEW_TEXT_MOVE_UNIT_EVENT },
255 { AccessibilityEventType::REQUEST_FOCUS, Accessibility::EventType::TYPE_VIEW_REQUEST_FOCUS_FOR_ACCESSIBILITY },
256 { AccessibilityEventType::SCROLL_START, Accessibility::EventType::TYPE_VIEW_SCROLLED_START },
257 { AccessibilityEventType::PAGE_CLOSE, Accessibility::EventType::TYPE_PAGE_CLOSE },
258 { AccessibilityEventType::ANNOUNCE_FOR_ACCESSIBILITY,
259 Accessibility::EventType::TYPE_VIEW_ANNOUNCE_FOR_ACCESSIBILITY },
260 { AccessibilityEventType::PAGE_OPEN, Accessibility::EventType::TYPE_PAGE_OPEN },
261 { AccessibilityEventType::ELEMENT_INFO_CHANGE, Accessibility::EventType::TYPE_ELEMENT_INFO_CHANGE },
262 { AccessibilityEventType::ANNOUNCE_FOR_ACCESSIBILITY_NOT_INTERRUPT,
263 Accessibility::EventType::TYPE_VIEW_ANNOUNCE_FOR_ACCESSIBILITY_NOT_INTERRUPT },
264 { AccessibilityEventType::SCROLLING_EVENT, Accessibility::EventType::TYPE_VIEW_SCROLLING_EVENT },
265 };
266 Accessibility::EventType eventType = Accessibility::EventType::TYPE_VIEW_INVALID;
267 int64_t idx = BinarySearchFindIndex(eventTypeMap, ArraySize(eventTypeMap), type);
268 if (idx >= 0) {
269 eventType = eventTypeMap[idx].value;
270 }
271 return eventType;
272 }
273
ConvertAceAction(AceAction aceAction)274 ActionType ConvertAceAction(AceAction aceAction)
275 {
276 static const ActionTable actionTable[] = {
277 { AceAction::ACTION_CLICK, ActionType::ACCESSIBILITY_ACTION_CLICK },
278 { AceAction::ACTION_LONG_CLICK, ActionType::ACCESSIBILITY_ACTION_LONG_CLICK },
279 { AceAction::ACTION_SCROLL_FORWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD },
280 { AceAction::ACTION_SCROLL_BACKWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD },
281 { AceAction::ACTION_FOCUS, ActionType::ACCESSIBILITY_ACTION_FOCUS },
282 { AceAction::ACTION_CLEAR_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS },
283 { AceAction::ACTION_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS },
284 { AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS },
285 { AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT },
286 { AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT },
287 { AceAction::ACTION_SET_TEXT, ActionType::ACCESSIBILITY_ACTION_SET_TEXT },
288 { AceAction::ACTION_COPY, ActionType::ACCESSIBILITY_ACTION_COPY },
289 { AceAction::ACTION_PASTE, ActionType::ACCESSIBILITY_ACTION_PASTE },
290 { AceAction::ACTION_CUT, ActionType::ACCESSIBILITY_ACTION_CUT },
291 { AceAction::ACTION_SELECT, ActionType::ACCESSIBILITY_ACTION_SELECT },
292 { AceAction::ACTION_CLEAR_SELECTION, ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION },
293 { AceAction::ACTION_SET_SELECTION, ActionType::ACCESSIBILITY_ACTION_SET_SELECTION },
294 { AceAction::ACTION_SET_CURSOR_POSITION, ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION },
295 { AceAction::ACTION_EXEC_SUB_COMPONENT, ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK },
296 { AceAction::ACTION_NEXT_HTML_ITEM, ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM },
297 { AceAction::ACTION_PREVIOUS_HTML_ITEM, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM },
298 };
299 for (const auto& item : actionTable) {
300 if (aceAction == item.aceAction) {
301 return item.action;
302 }
303 }
304 return ActionType::ACCESSIBILITY_ACTION_INVALID;
305 }
306
ConvertAccessibilityValue(const AccessibilityValue & value)307 inline RangeInfo ConvertAccessibilityValue(const AccessibilityValue& value)
308 {
309 return RangeInfo(value.min, value.max, value.current);
310 }
311
ConvertToCardAccessibilityId(int64_t nodeId,int64_t cardId,int64_t rootNodeId)312 int64_t ConvertToCardAccessibilityId(int64_t nodeId, int64_t cardId, int64_t rootNodeId)
313 {
314 // result is integer total ten digits, top five for agp virtualViewId, end five for ace nodeId,
315 // for example agp virtualViewId is 32, ace nodeId is 1000001, convert to result is 00032 10001.
316 int64_t result = 0;
317 if (nodeId == rootNodeId + ROOT_STACK_BASE) {
318 // for example agp virtualViewId is 32 root node is 2100000, convert to result is 00032 21000.
319 result = cardId * CARD_BASE + (static_cast<int64_t>(nodeId / CARD_BASE)) * CARD_ROOT_NODE_ID_RATION +
320 nodeId % CARD_BASE;
321 } else {
322 result = cardId * CARD_BASE + (static_cast<int64_t>(nodeId / DOM_ROOT_NODE_ID_BASE)) * CARD_NODE_ID_RATION +
323 nodeId % DOM_ROOT_NODE_ID_BASE;
324 }
325 return result;
326 }
CheckInvalidNodeParentID(const RefPtr<AccessibilityNode> & node,AccessibilityElementInfo & nodeInfo,const RefPtr<JsAccessibilityManager> & manager,int & leftTopX,int & leftTopY,int & rightBottomX,int & rightBottomY)327 void CheckInvalidNodeParentID(const RefPtr<AccessibilityNode>& node, AccessibilityElementInfo& nodeInfo,
328 const RefPtr<JsAccessibilityManager>& manager, int& leftTopX, int& leftTopY, int& rightBottomX, int& rightBottomY)
329 {
330 if (node->GetParentId() == -1) {
331 const auto& children = node->GetChildList();
332 if (!children.empty()) {
333 auto lastChildNode = manager->GetAccessibilityNodeById(children.back()->GetNodeId());
334 if (lastChildNode) {
335 rightBottomX = leftTopX + static_cast<int>(lastChildNode->GetWidth());
336 rightBottomY = leftTopY + static_cast<int>(lastChildNode->GetHeight());
337 Accessibility::Rect bounds(leftTopX, leftTopY, rightBottomX, rightBottomY);
338 nodeInfo.SetRectInScreen(bounds);
339 }
340 }
341 nodeInfo.SetParent(INVALID_PARENT_ID);
342 }
343 if (node->GetNodeId() == 0) {
344 nodeInfo.SetParent(INVALID_PARENT_ID);
345 }
346 }
UpdateAccessibilityNodeInfo(const RefPtr<AccessibilityNode> & node,AccessibilityElementInfo & nodeInfo,const RefPtr<JsAccessibilityManager> & manager,int windowId)347 void UpdateAccessibilityNodeInfo(const RefPtr<AccessibilityNode>& node, AccessibilityElementInfo& nodeInfo,
348 const RefPtr<JsAccessibilityManager>& manager, int windowId)
349 {
350 int leftTopX = static_cast<int>(node->GetLeft()) + manager->GetWindowLeft(node->GetWindowId());
351 int leftTopY = static_cast<int>(node->GetTop()) + manager->GetWindowTop(node->GetWindowId());
352 int rightBottomX = leftTopX + static_cast<int>(node->GetWidth());
353 int rightBottomY = leftTopY + static_cast<int>(node->GetHeight());
354 if (manager->isOhosHostCard()) {
355 int64_t id = ConvertToCardAccessibilityId(node->GetNodeId(), manager->GetCardId(), manager->GetRootNodeId());
356 nodeInfo.SetAccessibilityId(id);
357 if (node->GetParentId() == -1) {
358 nodeInfo.SetParent(-1);
359 } else {
360 nodeInfo.SetParent(
361 ConvertToCardAccessibilityId(node->GetParentId(), manager->GetCardId(), manager->GetRootNodeId()));
362 }
363 leftTopX = static_cast<int>(node->GetLeft() + manager->GetCardOffset().GetX());
364 leftTopY = static_cast<int>(node->GetTop() + manager->GetCardOffset().GetY());
365 rightBottomX = leftTopX + static_cast<int>(node->GetWidth());
366 rightBottomY = leftTopY + static_cast<int>(node->GetHeight());
367 Accessibility::Rect bounds(leftTopX, leftTopY, rightBottomX, rightBottomY);
368 nodeInfo.SetRectInScreen(bounds);
369 } else {
370 if (node->GetTag() == SIDEBARCONTAINER_TAG) {
371 Rect sideBarRect = node->GetRect();
372 for (const auto& childNode : node->GetChildList()) {
373 sideBarRect = sideBarRect.CombineRect(childNode->GetRect());
374 }
375 leftTopX = static_cast<int>(sideBarRect.Left()) + manager->GetWindowLeft(node->GetWindowId());
376 leftTopY = static_cast<int>(sideBarRect.Top()) + manager->GetWindowTop(node->GetWindowId());
377 rightBottomX = static_cast<int>(sideBarRect.Right()) + manager->GetWindowLeft(node->GetWindowId());
378 rightBottomY = static_cast<int>(sideBarRect.Bottom()) + manager->GetWindowTop(node->GetWindowId());
379 }
380 Accessibility::Rect bounds(leftTopX, leftTopY, rightBottomX, rightBottomY);
381 nodeInfo.SetRectInScreen(bounds);
382 nodeInfo.SetComponentId(static_cast<int64_t>(node->GetNodeId()));
383 nodeInfo.SetParent(static_cast<int64_t>(node->GetParentId()));
384 }
385 CheckInvalidNodeParentID(node, nodeInfo, manager, leftTopX, leftTopY, rightBottomX, rightBottomY);
386 nodeInfo.SetPagePath(manager->GetPagePath());
387 nodeInfo.SetWindowId(windowId);
388 nodeInfo.SetChecked(node->GetCheckedState());
389 nodeInfo.SetEnabled(node->GetEnabledState());
390 nodeInfo.SetFocused(node->GetFocusedState());
391 nodeInfo.SetSelected(node->GetSelectedState());
392 nodeInfo.SetCheckable(node->GetCheckableState());
393 nodeInfo.SetClickable(node->GetClickableState());
394 nodeInfo.SetFocusable(node->GetFocusableState());
395 nodeInfo.SetScrollable(node->GetScrollableState());
396 nodeInfo.SetLongClickable(node->GetLongClickableState());
397 nodeInfo.SetEditable(node->GetEditable());
398 nodeInfo.SetPluraLineSupported(node->GetIsMultiLine());
399 nodeInfo.SetPassword(node->GetIsPassword());
400 nodeInfo.SetTextLengthLimit(node->GetMaxTextLength());
401 nodeInfo.SetSelectedBegin(node->GetTextSelectionStart());
402 nodeInfo.SetSelectedEnd(node->GetTextSelectionEnd());
403 nodeInfo.SetVisible(node->GetShown() && node->GetVisible());
404 nodeInfo.SetHint(node->GetHintText());
405 std::string accessibilityLabel = node->GetAccessibilityLabel();
406 nodeInfo.SetLabeled(atol(accessibilityLabel.c_str()));
407 nodeInfo.SetError(node->GetErrorText());
408 nodeInfo.SetComponentResourceId(node->GetJsComponentId());
409 nodeInfo.SetInspectorKey(node->GetJsComponentId());
410 RangeInfo rangeInfo = ConvertAccessibilityValue(node->GetAccessibilityValue());
411 nodeInfo.SetRange(rangeInfo);
412 nodeInfo.SetInputType(static_cast<int>(node->GetTextInputType()));
413 nodeInfo.SetComponentType(node->GetTag());
414 GridInfo gridInfo(
415 node->GetCollectionInfo().rows, node->GetCollectionInfo().columns, (nodeInfo.IsPluraLineSupported() ? 0 : 1));
416 nodeInfo.SetGrid(gridInfo);
417 nodeInfo.SetAccessibilityFocus(node->GetAccessibilityFocusedState());
418 nodeInfo.SetPageId(node->GetPageId());
419
420 int32_t row = node->GetCollectionItemInfo().row;
421 int32_t column = node->GetCollectionItemInfo().column;
422 GridItemInfo gridItemInfo(row, row, column, column, false, nodeInfo.IsSelected());
423 nodeInfo.SetGridItem(gridItemInfo);
424 nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
425
426 if (node->GetTag() == LIST_TAG) {
427 nodeInfo.SetItemCounts(node->GetListItemCounts());
428 nodeInfo.SetBeginIndex(node->GetListBeginIndex());
429 nodeInfo.SetEndIndex(node->GetListEndIndex());
430 }
431 if (node->GetIsPassword()) {
432 std::string strStar(node->GetText().size(), '*');
433 nodeInfo.SetContent(strStar);
434 } else {
435 nodeInfo.SetContent(node->GetText());
436 }
437
438 auto supportAceActions = node->GetSupportAction();
439 std::vector<ActionType> actions(supportAceActions.size());
440
441 for (auto it = supportAceActions.begin(); it != supportAceActions.end(); ++it) {
442 AccessibleAction action(ConvertAceAction(*it), "ace");
443 nodeInfo.AddAction(action);
444 }
445
446 if (node->GetImportantForAccessibility() == NG::AccessibilityProperty::Level::YES_STR) {
447 actions.emplace_back(ActionType::ACCESSIBILITY_ACTION_FOCUS);
448 nodeInfo.SetCheckable(true);
449 } else if (node->GetImportantForAccessibility() == NG::AccessibilityProperty::Level::NO_STR ||
450 node->GetImportantForAccessibility() == NG::AccessibilityProperty::Level::NO_HIDE_DESCENDANTS) {
451 nodeInfo.SetVisible(false);
452 }
453 manager->UpdateNodeChildIds(node);
454 for (const auto& child : node->GetChildIds()) {
455 nodeInfo.AddChild(child);
456 }
457
458 #ifdef ACE_DEBUG
459 std::string actionForLog;
460 for (const auto& action : supportAceActions) {
461 if (!actionForLog.empty()) {
462 actionForLog.append(",");
463 }
464 actionForLog.append(std::to_string(static_cast<int32_t>(action)));
465 }
466 #endif
467 }
468
UpdateCacheInfo(std::list<AccessibilityElementInfo> & infos,uint32_t mode,const RefPtr<AccessibilityNode> & node,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,int windowId)469 void UpdateCacheInfo(std::list<AccessibilityElementInfo>& infos, uint32_t mode, const RefPtr<AccessibilityNode>& node,
470 const RefPtr<JsAccessibilityManager>& jsAccessibilityManager, int windowId)
471 {
472 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}d, mode: %{public}d", node->GetNodeId(), mode);
473 // parent
474 uint32_t umode = mode;
475 if (umode & static_cast<uint32_t>(PREFETCH_PREDECESSORS)) {
476 if (node->GetParentId() != -1 && node->GetParentId() != DEFAULT_PARENT_ID) {
477 AccessibilityElementInfo parentNodeInfo;
478 UpdateAccessibilityNodeInfo(node->GetParentNode(), parentNodeInfo, jsAccessibilityManager, windowId);
479 infos.emplace_back(parentNodeInfo);
480 }
481 }
482 // sister/brothers
483 if (umode & static_cast<uint32_t>(PREFETCH_SIBLINGS)) {
484 if (node->GetParentId() != -1 && node->GetParentId() != DEFAULT_PARENT_ID) {
485 for (const auto& item : node->GetParentNode()->GetChildList()) {
486 if (node->GetNodeId() != item->GetNodeId()) {
487 AccessibilityElementInfo siblingNodeInfo;
488 UpdateAccessibilityNodeInfo(item, siblingNodeInfo, jsAccessibilityManager, windowId);
489 infos.emplace_back(siblingNodeInfo);
490 }
491 }
492 }
493 }
494 // children
495 if (umode & static_cast<uint32_t>(PREFETCH_CHILDREN)) {
496 for (const auto& item : node->GetChildList()) {
497 AccessibilityElementInfo childNodeInfo;
498 UpdateAccessibilityNodeInfo(item, childNodeInfo, jsAccessibilityManager, windowId);
499 infos.emplace_back(childNodeInfo);
500 }
501 }
502
503 // get all children
504 if (umode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN)) {
505 std::list<RefPtr<AccessibilityNode>> children;
506 for (const auto& item : node->GetChildList()) {
507 children.emplace_back(item);
508 }
509
510 while (!children.empty()) {
511 auto parent = children.front();
512 children.pop_front();
513 AccessibilityElementInfo childNodeInfo;
514 UpdateAccessibilityNodeInfo(parent, childNodeInfo, jsAccessibilityManager, windowId);
515 infos.push_back(childNodeInfo);
516 for (const auto& item : parent->GetChildList()) {
517 children.emplace_back(item);
518 }
519 }
520 }
521 }
522
SortAccessibilityInfosByBreadth(std::list<AccessibilityElementInfo> & infos,std::list<int64_t> & accessibilityIdQueue,std::list<AccessibilityElementInfo> & output)523 void SortAccessibilityInfosByBreadth(std::list<AccessibilityElementInfo>& infos,
524 std::list<int64_t>& accessibilityIdQueue, std::list<AccessibilityElementInfo>& output)
525 {
526 while (!accessibilityIdQueue.empty()) {
527 auto accessibilityId = accessibilityIdQueue.front();
528 accessibilityIdQueue.pop_front();
529 for (std::list<AccessibilityElementInfo>::iterator info = infos.begin(); info != infos.end(); ++info) {
530 if (accessibilityId != info->GetAccessibilityId()) {
531 continue;
532 }
533 for (auto& child : info->GetChildIds()) {
534 accessibilityIdQueue.emplace_back(child);
535 }
536 output.emplace_back(*info);
537 infos.erase(info);
538 break;
539 }
540 SortAccessibilityInfosByBreadth(infos, accessibilityIdQueue, output);
541 }
542 }
543
SortExtensionAccessibilityInfo(std::list<AccessibilityElementInfo> & infos,int64_t rootAccessibilityId)544 void SortExtensionAccessibilityInfo(std::list<AccessibilityElementInfo>& infos, int64_t rootAccessibilityId)
545 {
546 auto input = infos;
547 infos.clear();
548 std::list<int64_t> accessibilityIdQueue;
549 accessibilityIdQueue.emplace_back(rootAccessibilityId);
550 SortAccessibilityInfosByBreadth(input, accessibilityIdQueue, infos);
551 }
552
ConvertExtensionAccessibilityId(AccessibilityElementInfo & info,const RefPtr<NG::FrameNode> & extensionNode,int64_t uiExtensionOffset,AccessibilityElementInfo & parentInfo)553 void ConvertExtensionAccessibilityId(AccessibilityElementInfo& info, const RefPtr<NG::FrameNode>& extensionNode,
554 int64_t uiExtensionOffset, AccessibilityElementInfo& parentInfo)
555 {
556 auto extensionAbilityId =
557 extensionNode->WrapExtensionAbilityId(uiExtensionOffset, info.GetAccessibilityId());
558 info.SetAccessibilityId(extensionAbilityId);
559 auto parentNodeId =
560 extensionNode->WrapExtensionAbilityId(uiExtensionOffset, info.GetParentNodeId());
561 info.SetParent(parentNodeId);
562 auto childIds = info.GetChildIds();
563 for (auto& child : childIds) {
564 info.RemoveChild(child);
565 info.AddChild(extensionNode->WrapExtensionAbilityId(uiExtensionOffset, child));
566 }
567 if (V2::ROOT_ETS_TAG == info.GetComponentType()) {
568 for (auto& child : info.GetChildIds()) {
569 parentInfo.AddChild(child);
570 }
571 }
572 }
573
ConvertExtensionAccessibilityNodeId(std::list<AccessibilityElementInfo> & infos,const RefPtr<NG::FrameNode> & extensionNode,int64_t uiExtensionOffset,AccessibilityElementInfo & parentInfo)574 void ConvertExtensionAccessibilityNodeId(std::list<AccessibilityElementInfo>& infos,
575 const RefPtr<NG::FrameNode>& extensionNode, int64_t uiExtensionOffset,
576 AccessibilityElementInfo& parentInfo)
577 {
578 CHECK_NULL_VOID(extensionNode);
579 for (auto& accessibilityElementInfo : infos) {
580 ConvertExtensionAccessibilityId(accessibilityElementInfo, extensionNode, uiExtensionOffset, parentInfo);
581 }
582 for (auto& accessibilityElementInfo : infos) {
583 if (std::find(parentInfo.GetChildIds().begin(), parentInfo.GetChildIds().end(),
584 accessibilityElementInfo.GetAccessibilityId()) != parentInfo.GetChildIds().end()) {
585 accessibilityElementInfo.SetParent(extensionNode->GetAccessibilityId());
586 }
587 }
588 }
589
BoolToString(bool tag)590 inline std::string BoolToString(bool tag)
591 {
592 return tag ? "true" : "false";
593 }
594
ConvertInputTypeToString(AceTextCategory type)595 std::string ConvertInputTypeToString(AceTextCategory type)
596 {
597 switch (type) {
598 case AceTextCategory::INPUT_TYPE_DEFAULT:
599 return "INPUT_TYPE_DEFAULT";
600 case AceTextCategory::INPUT_TYPE_TEXT:
601 return "INPUT_TYPE_TEXT";
602 case AceTextCategory::INPUT_TYPE_EMAIL:
603 return "INPUT_TYPE_EMAIL";
604 case AceTextCategory::INPUT_TYPE_DATE:
605 return "INPUT_TYPE_DATE";
606 case AceTextCategory::INPUT_TYPE_TIME:
607 return "INPUT_TYPE_TIME";
608 case AceTextCategory::INPUT_TYPE_NUMBER:
609 return "INPUT_TYPE_NUMBER";
610 case AceTextCategory::INPUT_TYPE_PASSWORD:
611 return "INPUT_TYPE_PASSWORD";
612 case AceTextCategory::INPUT_TYPE_PHONENUMBER:
613 return "INPUT_TYPE_PHONENUMBER";
614 case AceTextCategory::INPUT_TYPE_USER_NAME:
615 return "INPUT_TYPE_USER_NAME";
616 case AceTextCategory::INPUT_TYPE_NEW_PASSWORD:
617 return "INPUT_TYPE_NEW_PASSWORD";
618 default:
619 return "illegal input type";
620 }
621 }
622
FindAccessibilityFocus(const RefPtr<AccessibilityNode> & node,RefPtr<AccessibilityNode> & resultNode)623 bool FindAccessibilityFocus(const RefPtr<AccessibilityNode>& node, RefPtr<AccessibilityNode>& resultNode)
624 {
625 CHECK_NULL_RETURN(node, false);
626 if (node->GetAccessibilityFocusedState()) {
627 resultNode = node;
628 return true;
629 }
630 if (!node->GetChildList().empty()) {
631 for (const auto& item : node->GetChildList()) {
632 if (resultNode != nullptr) {
633 return true;
634 }
635 if (FindAccessibilityFocus(item, resultNode)) {
636 return true;
637 }
638 }
639 }
640
641 return false;
642 }
643
FindFocusedExtensionElementInfoNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,Accessibility::AccessibilityElementInfo & info)644 void FindFocusedExtensionElementInfoNG(const SearchParameter& searchParam,
645 const RefPtr<NG::FrameNode>& node, Accessibility::AccessibilityElementInfo& info)
646 {
647 if (NG::UI_EXTENSION_OFFSET_MIN < (searchParam.uiExtensionOffset + 1)) {
648 node->FindFocusedExtensionElementInfoNG(searchParam.nodeId, searchParam.mode,
649 searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR, info);
650 } else {
651 info.SetValidElement(false);
652 }
653 }
654
SetUiExtensionAbilityParentIdForFocus(const RefPtr<NG::UINode> & uiExtensionNode,const int64_t uiExtensionOffset,Accessibility::AccessibilityElementInfo & info)655 void SetUiExtensionAbilityParentIdForFocus(const RefPtr<NG::UINode>& uiExtensionNode,
656 const int64_t uiExtensionOffset, Accessibility::AccessibilityElementInfo& info)
657 {
658 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiExtensionNode);
659 if (frameNode) {
660 auto parentId = info.GetParentNodeId();
661 AccessibilityElementInfo parentInfo;
662 ConvertExtensionAccessibilityId(info, frameNode, uiExtensionOffset, parentInfo);
663 if (parentId == NG::UI_EXTENSION_ROOT_ID) {
664 info.SetParent(frameNode->GetAccessibilityId());
665 }
666 }
667 }
668
669 RefPtr<NG::FrameNode> GetFramenodeByAccessibilityId(const RefPtr<NG::FrameNode>& root, int64_t id);
670
FindAccessibilityFocus(const RefPtr<NG::UINode> & node,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const int64_t uiExtensionOffset,const RefPtr<PipelineBase> & context,int64_t currentFocusNodeId)671 RefPtr<NG::FrameNode> FindAccessibilityFocus(const RefPtr<NG::UINode>& node,
672 int32_t focusType, Accessibility::AccessibilityElementInfo& info,
673 const int64_t uiExtensionOffset, const RefPtr<PipelineBase>& context, int64_t currentFocusNodeId)
674 {
675 CHECK_NULL_RETURN(node, nullptr);
676 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
677 if (frameNode) {
678 if (frameNode->GetRenderContext()->GetAccessibilityFocus().value_or(false)) {
679 auto node = GetFramenodeByAccessibilityId(frameNode, currentFocusNodeId);
680 std::string finalNodeId = node ? std::to_string(node->GetAccessibilityId()) : "nullptr";
681 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
682 "currentFocusNodeId: %{public}" PRId64 ", result accessiblityId: %s",
683 currentFocusNodeId, finalNodeId.c_str());
684 return node;
685 }
686 }
687 if (node->GetChildren(true).empty()) {
688 return nullptr;
689 }
690 for (const auto& child : node->GetChildren(true)) {
691 auto extensionNode = AceType::DynamicCast<NG::FrameNode>(child);
692 if (IsIsolatedComponent(child) && extensionNode &&
693 !IsUIExtensionShowPlaceholder(extensionNode) &&
694 (extensionNode->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
695 (((extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX) &&
696 (NG::UI_EXTENSION_OFFSET_MAX == uiExtensionOffset)) ||
697 (extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_OTHER_MAX))) {
698 SearchParameter transferSearchParam {NG::UI_EXTENSION_ROOT_ID, "", focusType, uiExtensionOffset};
699 OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(
700 transferSearchParam, extensionNode, info);
701 if (info.GetAccessibilityId() < 0) {
702 continue;
703 }
704 SetUiExtensionAbilityParentIdForFocus(extensionNode, uiExtensionOffset, info);
705 return extensionNode;
706 }
707 auto result = FindAccessibilityFocus(child, focusType, info, uiExtensionOffset, context, currentFocusNodeId);
708 if (result) {
709 return result;
710 }
711 }
712 return nullptr;
713 }
714
FindInputFocus(const RefPtr<AccessibilityNode> & node,RefPtr<AccessibilityNode> & resultNode)715 bool FindInputFocus(const RefPtr<AccessibilityNode>& node, RefPtr<AccessibilityNode>& resultNode)
716 {
717 CHECK_NULL_RETURN(node, false);
718 if (!node->GetFocusedState() && (node->GetParentId() != -1)) {
719 return false;
720 }
721 if (node->GetFocusedState()) {
722 resultNode = node;
723 }
724 if (!node->GetChildList().empty()) {
725 for (const auto& item : node->GetChildList()) {
726 if (FindInputFocus(item, resultNode)) {
727 return true;
728 }
729 }
730 }
731 return node->GetFocusedState();
732 }
733
FindInputFocus(const RefPtr<NG::UINode> & node,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const int64_t uiExtensionOffset,const RefPtr<PipelineBase> & context)734 RefPtr<NG::FrameNode> FindInputFocus(const RefPtr<NG::UINode>& node, int32_t focusType,
735 Accessibility::AccessibilityElementInfo& info, const int64_t uiExtensionOffset,
736 const RefPtr<PipelineBase>& context)
737 {
738 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
739 CHECK_NULL_RETURN(frameNode, nullptr);
740 if (!(frameNode->GetFocusHub() ? frameNode->GetFocusHub()->IsCurrentFocus() : false)) {
741 return nullptr;
742 }
743 if (frameNode->GetFocusHub()->IsChild()) {
744 if (frameNode->IsInternal()) {
745 return frameNode->GetFocusParent();
746 }
747 return frameNode;
748 }
749 auto focusHub = frameNode->GetFocusHub();
750 RefPtr<NG::FrameNode> target;
751 focusHub->AnyChildFocusHub([&target, &info, context, focusType, uiExtensionOffset](
752 const RefPtr<NG::FocusHub>& focusChild) {
753 auto extensionNode = focusChild->GetFrameNode();
754 if ((extensionNode && IsIsolatedComponent(extensionNode)) &&
755 !IsUIExtensionShowPlaceholder(extensionNode) &&
756 (extensionNode->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
757 (((extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX) &&
758 (NG::UI_EXTENSION_OFFSET_MAX == uiExtensionOffset)) ||
759 (extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_OTHER_MAX))) {
760 SearchParameter transferSearchParam {NG::UI_EXTENSION_ROOT_ID, "", focusType, uiExtensionOffset};
761 OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(
762 transferSearchParam, extensionNode, info);
763 if (info.GetAccessibilityId() < 0) {
764 return false;
765 }
766 SetUiExtensionAbilityParentIdForFocus(extensionNode, uiExtensionOffset, info);
767 target = extensionNode;
768 return true;
769 }
770 target = FindInputFocus(focusChild->GetFrameNode(), focusType, info, uiExtensionOffset, context);
771 return target ? true : false;
772 });
773 return target;
774 }
775
FindText(const RefPtr<AccessibilityNode> & node,const std::string & text,std::list<RefPtr<AccessibilityNode>> & nodeList)776 void FindText(
777 const RefPtr<AccessibilityNode>& node, const std::string& text, std::list<RefPtr<AccessibilityNode>>& nodeList)
778 {
779 CHECK_NULL_VOID(node);
780 if (node->GetText().find(text) != std::string::npos) {
781 nodeList.push_back(node);
782 }
783 if (!node->GetChildList().empty()) {
784 for (const auto& child : node->GetChildList()) {
785 FindText(child, text, nodeList);
786 }
787 }
788 }
789
FindText(const RefPtr<NG::UINode> & node,const std::string & text,std::list<RefPtr<NG::FrameNode>> & nodeList)790 void FindText(const RefPtr<NG::UINode>& node, const std::string& text, std::list<RefPtr<NG::FrameNode>>& nodeList)
791 {
792 CHECK_NULL_VOID(node);
793
794 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
795 if (frameNode && !frameNode->IsInternal()) {
796 if (frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetGroupText().find(text) !=
797 std::string::npos) {
798 nodeList.push_back(frameNode);
799 }
800 }
801
802 if (!node->GetChildren(true).empty()) {
803 for (const auto& child : node->GetChildren(true)) {
804 FindText(child, text, nodeList);
805 }
806 }
807 }
808
FindFrameNodeByAccessibilityId(int64_t id,const std::list<RefPtr<NG::UINode>> & children,std::queue<RefPtr<NG::UINode>> & nodes,RefPtr<NG::FrameNode> & result)809 bool FindFrameNodeByAccessibilityId(int64_t id, const std::list<RefPtr<NG::UINode>>& children,
810 std::queue<RefPtr<NG::UINode>>& nodes, RefPtr<NG::FrameNode>& result)
811 {
812 for (const auto& child : children) {
813 auto frameNode = AceType::DynamicCast<NG::FrameNode>(child);
814 if (frameNode != nullptr && !frameNode->CheckAccessibilityLevelNo()) {
815 if (frameNode->GetAccessibilityId() == id) {
816 result = AceType::DynamicCast<NG::FrameNode>(child);
817 return true;
818 }
819 }
820 nodes.push(child);
821 }
822 return false;
823 }
824
GetFramenodeByAccessibilityId(const RefPtr<NG::FrameNode> & root,int64_t id)825 RefPtr<NG::FrameNode> GetFramenodeByAccessibilityId(const RefPtr<NG::FrameNode>& root, int64_t id)
826 {
827 CHECK_NULL_RETURN(root, nullptr);
828 if (root->GetAccessibilityId() == id) {
829 return root;
830 }
831 std::queue<RefPtr<NG::UINode>> nodes;
832 nodes.push(root);
833 RefPtr<NG::FrameNode> frameNodeResult = nullptr;
834
835 while (!nodes.empty()) {
836 auto current = nodes.front();
837 nodes.pop();
838 if (current->HasVirtualNodeAccessibilityProperty()) {
839 auto fnode = AceType::DynamicCast<NG::FrameNode>(current);
840 auto property = fnode->GetAccessibilityProperty<NG::AccessibilityProperty>();
841 const auto& children = std::list<RefPtr<NG::UINode>> { property->GetAccessibilityVirtualNode() };
842 if (FindFrameNodeByAccessibilityId(id, children, nodes, frameNodeResult)) {
843 return frameNodeResult;
844 }
845 } else {
846 const auto& children = current->GetChildren(true);
847 if (FindFrameNodeByAccessibilityId(id, children, nodes, frameNodeResult)) {
848 return frameNodeResult;
849 }
850 }
851 auto frameNode = AceType::DynamicCast<NG::FrameNode>(current);
852 if (!frameNode) {
853 continue;
854 }
855 auto overlayNode = frameNode->GetOverlayNode();
856 if (overlayNode) {
857 const auto& children = std::list<RefPtr<NG::UINode>> { overlayNode };
858 if (FindFrameNodeByAccessibilityId(id, children, nodes, frameNodeResult)) {
859 return frameNodeResult;
860 }
861 }
862 }
863 return nullptr;
864 }
865
866 using FindCondition = std::function<bool(const RefPtr<NG::FrameNode>&)>;
867
FindFrameNodeByCondition(const std::list<RefPtr<NG::UINode>> & children,std::queue<RefPtr<NG::UINode>> & nodes,RefPtr<NG::FrameNode> & result,FindCondition condition)868 bool FindFrameNodeByCondition(const std::list<RefPtr<NG::UINode>>& children,
869 std::queue<RefPtr<NG::UINode>>& nodes, RefPtr<NG::FrameNode>& result, FindCondition condition)
870 {
871 for (const auto& child : children) {
872 auto frameNode = AceType::DynamicCast<NG::FrameNode>(child);
873 if (frameNode != nullptr && !frameNode->CheckAccessibilityLevelNo()) {
874 if (condition(frameNode)) {
875 result = frameNode;
876 return true;
877 }
878 }
879 nodes.push(child);
880 }
881 return false;
882 }
883
GetFramenodeByCondition(const RefPtr<NG::FrameNode> & root,FindCondition condition)884 RefPtr<NG::FrameNode> GetFramenodeByCondition(const RefPtr<NG::FrameNode>& root, FindCondition condition)
885 {
886 CHECK_NULL_RETURN(root, nullptr);
887
888 std::queue<RefPtr<NG::UINode>> nodes;
889 nodes.push(root);
890 RefPtr<NG::FrameNode> frameNodeResult = nullptr;
891
892 while (!nodes.empty()) {
893 auto current = nodes.front();
894 nodes.pop();
895 if (current->HasVirtualNodeAccessibilityProperty()) {
896 auto fnode = AceType::DynamicCast<NG::FrameNode>(current);
897 auto property = fnode->GetAccessibilityProperty<NG::AccessibilityProperty>();
898 const auto& children = std::list<RefPtr<NG::UINode>> { property->GetAccessibilityVirtualNode() };
899 if (FindFrameNodeByCondition(children, nodes, frameNodeResult, condition)) {
900 return frameNodeResult;
901 }
902 } else {
903 const auto& children = current->GetChildren(true);
904 if (FindFrameNodeByCondition(children, nodes, frameNodeResult, condition)) {
905 return frameNodeResult;
906 }
907 }
908 auto frameNode = AceType::DynamicCast<NG::FrameNode>(current);
909 if (!frameNode) {
910 continue;
911 }
912 auto overlayNode = frameNode->GetOverlayNode();
913 if (overlayNode) {
914 const auto& children = std::list<RefPtr<NG::UINode>> { overlayNode };
915 if (FindFrameNodeByCondition(children, nodes, frameNodeResult, condition)) {
916 return frameNodeResult;
917 }
918 }
919 }
920 return nullptr;
921 }
922
GetFrameNodeParent(const RefPtr<NG::UINode> & uiNode,RefPtr<NG::FrameNode> & parent)923 void GetFrameNodeParent(const RefPtr<NG::UINode>& uiNode, RefPtr<NG::FrameNode>& parent)
924 {
925 if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
926 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
927 if (!frameNode->IsInternal()) {
928 parent = frameNode;
929 return;
930 }
931 }
932 CHECK_NULL_VOID(uiNode);
933 auto parentNode = uiNode->GetParent();
934 GetFrameNodeParent(parentNode, parent);
935 }
936
NeedChangeTreeId(int64_t elementId,int32_t targetTreeId)937 bool NeedChangeTreeId(int64_t elementId, int32_t targetTreeId)
938 {
939 if (elementId == INVALID_PARENT_ID) {
940 return true;
941 }
942 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
943 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
944 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
945 if (splitTreeId != 0 &&
946 splitTreeId != AccessibilityElementInfo::UNDEFINED_TREE_ID &&
947 splitTreeId != targetTreeId) {
948 return false;
949 }
950 return true;
951 }
952
GetSurfaceIdByEmbedNode(const RefPtr<NG::FrameNode> & node)953 std::string GetSurfaceIdByEmbedNode(const RefPtr<NG::FrameNode>& node)
954 {
955 auto surfaceId = ElementRegister::GetInstance()->GetSurfaceIdByEmbedNode(AceType::RawPtr(node));
956 return std::to_string(surfaceId);
957 }
958
GetEmbedNodeBySurfaceId(const std::string & surfaceId)959 WeakPtr<NG::FrameNode> GetEmbedNodeBySurfaceId(const std::string& surfaceId)
960 {
961 std::stringstream ss(surfaceId);
962 uint64_t id;
963 if (ss >> id) {
964 return ElementRegister::GetInstance()->GetEmbedNodeBySurfaceId(id);
965 }
966 return nullptr;
967 }
968
CheckFrameNodeByAccessibilityLevel(const RefPtr<NG::FrameNode> & frameNode,bool isParent)969 bool CheckFrameNodeByAccessibilityLevel(const RefPtr<NG::FrameNode>& frameNode, bool isParent)
970 {
971 return true;
972 }
973
IsInPageNodes(int32_t pageId,const std::vector<RefPtr<NG::FrameNode>> & pageNodes)974 bool IsInPageNodes(int32_t pageId, const std::vector<RefPtr<NG::FrameNode>>& pageNodes)
975 {
976 for (const auto& page : pageNodes) {
977 CHECK_NULL_CONTINUE(page);
978 if (pageId == page->GetPageId()) {
979 return true;
980 }
981 }
982 return false;
983 }
984
CheckAndSetAccessibilityVisible(const RefPtr<NG::FrameNode> & node,bool isReduceMode=false)985 bool CheckAndSetAccessibilityVisible(const RefPtr<NG::FrameNode>& node, bool isReduceMode = false)
986 {
987 if (!isReduceMode) {
988 return true;
989 }
990 auto parentNode = node->GetParentFrameNode();
991 if (!parentNode) {
992 if (node->GetTag() != V2::PAGE_ETS_TAG) {
993 node->SetAccessibilityVisible(node->IsActive() && node->IsVisible());
994 }
995 } else {
996 if (node->GetTag() == V2::PAGE_ETS_TAG) {
997 return node->GetAccessibilityVisible();
998 }
999 auto nodeAccessibilityVisible = node->IsActive() && node->IsVisible() && parentNode->GetAccessibilityVisible();
1000 node->SetAccessibilityVisible(nodeAccessibilityVisible);
1001 }
1002 return node->GetAccessibilityVisible();
1003 }
1004
IsValidEmbedTarget(const RefPtr<NG::FrameNode> & frameNode,const CommonProperty & commonProperty)1005 bool IsValidEmbedTarget(const RefPtr<NG::FrameNode>& frameNode, const CommonProperty& commonProperty)
1006 {
1007 return commonProperty.checkEmbedNode &&
1008 frameNode && commonProperty.checkGetFunc &&
1009 (commonProperty.checkGetFunc(frameNode) != INVALID_NODE_ID);
1010 }
1011
GetFrameNodeChildren(const RefPtr<NG::UINode> & uiNode,std::vector<std::pair<int64_t,int32_t>> & childrenIdInfo,const CommonProperty & commonProperty)1012 void GetFrameNodeChildren(
1013 const RefPtr<NG::UINode>& uiNode,
1014 std::vector<std::pair<int64_t, int32_t>>& childrenIdInfo,
1015 const CommonProperty& commonProperty)
1016 {
1017 CHECK_NULL_VOID(uiNode);
1018 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
1019 if (IsValidEmbedTarget(frameNode, commonProperty)) {
1020 return;
1021 }
1022
1023 if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
1024 if (!frameNode->IsFirstVirtualNode()) {
1025 CHECK_NULL_VOID(frameNode->IsActive());
1026 }
1027 if (uiNode->GetTag() == "stage") {
1028 } else if (uiNode->GetTag() == "page") {
1029 if (!IsInPageNodes(uiNode->GetPageId(), commonProperty.pageNodes)) {
1030 return;
1031 }
1032 } else if (!frameNode->IsInternal() || frameNode->IsFirstVirtualNode()) {
1033 if (CheckFrameNodeByAccessibilityLevel(frameNode, false) &&
1034 CheckAndSetAccessibilityVisible(frameNode, commonProperty.isReduceMode)) {
1035 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1036 childrenIdInfo.emplace_back(
1037 std::make_pair(frameNode->GetAccessibilityId(),
1038 accessibilityProperty ? accessibilityProperty->GetAccessibilityZIndex() : -1));
1039 return;
1040 }
1041 }
1042 }
1043
1044 if (frameNode) {
1045 auto overlayNode = frameNode->GetOverlayNode();
1046 if (overlayNode) {
1047 GetFrameNodeChildren(overlayNode, childrenIdInfo, commonProperty);
1048 }
1049 }
1050
1051 if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
1052 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
1053 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1054 auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
1055 if (uiVirtualNode != nullptr) {
1056 auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
1057 if (virtualNode != nullptr) {
1058 GetFrameNodeChildren(virtualNode, childrenIdInfo, commonProperty);
1059 return;
1060 }
1061 }
1062 }
1063
1064 for (const auto& frameChild : uiNode->GetChildren(true)) {
1065 GetFrameNodeChildren(frameChild, childrenIdInfo, commonProperty);
1066 }
1067 }
1068
GetFrameNodeChildren(const RefPtr<NG::UINode> & uiNode,std::list<RefPtr<NG::FrameNode>> & children,const CommonProperty & commonProperty)1069 void GetFrameNodeChildren(
1070 const RefPtr<NG::UINode>& uiNode,
1071 std::list<RefPtr<NG::FrameNode>>& children,
1072 const CommonProperty& commonProperty)
1073 {
1074 CHECK_NULL_VOID(uiNode);
1075 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
1076 if (IsValidEmbedTarget(frameNode, commonProperty)) {
1077 return;
1078 }
1079
1080 if (frameNode) {
1081 CHECK_NULL_VOID(frameNode->IsActive());
1082 if (uiNode->GetTag() == "page") {
1083 if (!commonProperty.pageNodes.empty() && !IsInPageNodes(uiNode->GetPageId(), commonProperty.pageNodes)) {
1084 return;
1085 }
1086 } else if (!frameNode->IsInternal() && uiNode->GetTag() != "stage") {
1087 if (CheckFrameNodeByAccessibilityLevel(frameNode, false) &&
1088 CheckAndSetAccessibilityVisible(frameNode, commonProperty.isReduceMode)) {
1089 children.emplace_back(frameNode);
1090 return;
1091 }
1092 }
1093
1094 auto overlayNode = frameNode->GetOverlayNode();
1095 if (overlayNode) {
1096 GetFrameNodeChildren(overlayNode, children, commonProperty);
1097 }
1098
1099 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1100 auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
1101 if (uiVirtualNode != nullptr) {
1102 auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
1103 if (virtualNode != nullptr) {
1104 GetFrameNodeChildren(virtualNode, children, commonProperty);
1105 return;
1106 }
1107 }
1108 }
1109
1110 for (const auto& frameChild : uiNode->GetChildren(true)) {
1111 GetFrameNodeChildren(frameChild, children, commonProperty);
1112 }
1113 }
1114
GetNodeAccessibilityVisible(const RefPtr<NG::FrameNode> & frameNode,bool isAllAncestorAccessibilityVisible,bool clipVisible)1115 bool GetNodeAccessibilityVisible(const RefPtr<NG::FrameNode>& frameNode, bool isAllAncestorAccessibilityVisible,
1116 bool clipVisible)
1117 {
1118 if (frameNode->IsFirstVirtualNode()) {
1119 return frameNode->IsVisible() && isAllAncestorAccessibilityVisible && clipVisible;
1120 } else {
1121 return frameNode->IsActive() && frameNode->IsVisible() && isAllAncestorAccessibilityVisible && clipVisible;
1122 }
1123 }
1124
ProcessParentFrameNode(const RefPtr<NG::UINode> & parent,std::string & parentPath,bool & isAllAncestorAccessibilityVisible)1125 bool ProcessParentFrameNode(
1126 const RefPtr<NG::UINode>& parent, std::string& parentPath, bool& isAllAncestorAccessibilityVisible)
1127 {
1128 auto parentFrameNode = AceType::DynamicCast<NG::FrameNode>(parent);
1129 if (parentFrameNode->CheckAccessibilityLevelNo()) {
1130 return false;
1131 }
1132
1133 parentPath += "Parent ID: " + std::to_string(parent->GetAccessibilityId()) +
1134 " IsActive: " + std::to_string(parentFrameNode->IsActive()) +
1135 " IsVisible: " + std::to_string(parentFrameNode->IsVisible()) +
1136 " AccessibilityVisible: " + std::to_string(parentFrameNode->GetAccessibilityVisible()) +
1137 " Parent Tag: " + parent->GetTag() + " | ";
1138
1139 if (parent->GetTag() == V2::PAGE_ETS_TAG) {
1140 isAllAncestorAccessibilityVisible = parentFrameNode->GetAccessibilityVisible();
1141 } else if (parentFrameNode->IsFirstVirtualNode()) {
1142 isAllAncestorAccessibilityVisible = parentFrameNode->IsVisible();
1143 } else {
1144 isAllAncestorAccessibilityVisible = parentFrameNode->IsActive() && parentFrameNode->IsVisible();
1145 }
1146
1147 return !isAllAncestorAccessibilityVisible;
1148 }
1149
GetInitialParent(const RefPtr<NG::UINode> & uiNode)1150 RefPtr<NG::UINode> GetInitialParent(const RefPtr<NG::UINode>& uiNode)
1151 {
1152 if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
1153 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
1154 if (frameNode->IsFirstVirtualNode()) {
1155 auto weakNode = frameNode->GetVirtualNodeParent();
1156 return weakNode.Upgrade();
1157 } else {
1158 return uiNode->GetParent();
1159 }
1160 }
1161 return nullptr;
1162 }
1163
UpdateAccessibilityVisibleToRoot(const RefPtr<NG::UINode> & uiNode)1164 void UpdateAccessibilityVisibleToRoot(const RefPtr<NG::UINode>& uiNode)
1165 {
1166 RefPtr<NG::UINode> parent = GetInitialParent(uiNode);
1167 bool isAllAncestorAccessibilityVisible = true;
1168 bool clipVisible = true;
1169 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
1170 CHECK_NULL_VOID(frameNode);
1171 OHOS::Ace::NG::RectF frameRect;
1172 OHOS::Ace::NG::RectF visibleInnerRect;
1173 OHOS::Ace::NG::RectF visibleRect;
1174 frameNode->SetIsCalculateInnerVisibleRectClip(true);
1175 frameNode->GetVisibleRectWithClip(visibleRect, visibleInnerRect, frameRect);
1176 bool isClipCheckSkip = NearEqual(visibleRect.Width(), 0.0) && NearEqual(visibleRect.Height(), 0.0) &&
1177 NearEqual(visibleInnerRect.Width(), 0.0) && NearEqual(visibleInnerRect.Height(), 0.0);
1178 clipVisible = (GreatNotEqual(visibleInnerRect.Width(), 0.0) && GreatNotEqual(visibleInnerRect.Height(), 0.0)) ||
1179 isClipCheckSkip;
1180 auto renderContext = frameNode->GetRenderContext();
1181 CHECK_NULL_VOID(renderContext);
1182 auto rect = renderContext->GetPaintRectWithoutTransform();
1183 if (NearEqual(rect.Width(), 0.0) && NearEqual(rect.Height(), 0.0)) {
1184 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Component %{public}s is not visible: width and height are both zero.",
1185 std::to_string(frameNode->GetAccessibilityId()).c_str());
1186 clipVisible = false;
1187 }
1188 std::string parentPath;
1189 while (parent) {
1190 if (AceType::InstanceOf<NG::FrameNode>(parent)) {
1191 if (ProcessParentFrameNode(parent, parentPath, isAllAncestorAccessibilityVisible)) {
1192 break;
1193 }
1194 }
1195 parent = parent->GetParent();
1196 }
1197 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Complete parent path:current id %{public}" PRId64 " %{public}s",
1198 frameNode->GetAccessibilityId(), parentPath.c_str());
1199
1200 bool nodeAccessibilityVisible =
1201 GetNodeAccessibilityVisible(frameNode, isAllAncestorAccessibilityVisible, clipVisible);
1202 if (!nodeAccessibilityVisible) {
1203 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
1204 "Element %{public}" PRId64 " is invisible. isActive %{public}d, isVisible %{public}d"
1205 " isAllAncestorAccessibilityVisible:%{public}d clipVisible:%{public}d",
1206 frameNode->GetAccessibilityId(), frameNode->IsActive(), frameNode->IsVisible(),
1207 isAllAncestorAccessibilityVisible, clipVisible);
1208 }
1209
1210 if (frameNode->GetTag() != V2::PAGE_ETS_TAG) {
1211 frameNode->SetAccessibilityVisible(nodeAccessibilityVisible);
1212 }
1213 }
1214
SetRootAccessibilityVisible(const RefPtr<NG::UINode> & uiNode,AccessibilityElementInfo & nodeInfo)1215 void SetRootAccessibilityVisible(const RefPtr<NG::UINode>& uiNode, AccessibilityElementInfo& nodeInfo)
1216 {
1217 UpdateAccessibilityVisibleToRoot(uiNode);
1218 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
1219 CHECK_NULL_VOID(frameNode);
1220 nodeInfo.SetAccessibilityVisible(frameNode->GetAccessibilityVisible());
1221 }
1222
SetRootAccessibilityNextFocusId(const RefPtr<NG::UINode> & currentNode,const RefPtr<NG::FrameNode> & rootNode,AccessibilityElementInfo & nodeInfo)1223 void SetRootAccessibilityNextFocusId(const RefPtr<NG::UINode>& currentNode, const RefPtr<NG::FrameNode>& rootNode,
1224 AccessibilityElementInfo& nodeInfo)
1225 {
1226 auto currentFrameNode = AceType::DynamicCast<NG::FrameNode>(currentNode);
1227 CHECK_NULL_VOID(currentFrameNode);
1228 auto accessibilityProperty = currentFrameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1229 CHECK_NULL_VOID(accessibilityProperty);
1230 if (accessibilityProperty->GetAccessibilityNextFocusInspectorKey() == "") {
1231 return;
1232 }
1233
1234 FindCondition condition = [accessibilityProperty](const RefPtr<NG::FrameNode>& node) {
1235 return node->GetInspectorId() == accessibilityProperty->GetAccessibilityNextFocusInspectorKey();
1236 };
1237 auto nextNode = GetFramenodeByCondition(rootNode, condition);
1238 CHECK_NULL_VOID(nextNode);
1239 auto elementId = nextNode->GetAccessibilityId();
1240 if (nodeInfo.GetBelongTreeId() > 0) {
1241 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(nodeInfo.GetBelongTreeId(), elementId);
1242 }
1243 nodeInfo.SetAccessibilityNextFocusId(elementId);
1244 }
1245
SetRootAccessibilityPreFocusId(const RefPtr<NG::UINode> & currentNode,const RefPtr<NG::FrameNode> & rootNode,AccessibilityElementInfo & nodeInfo,const std::map<std::string,int64_t> & nextFocusIdMap)1246 void SetRootAccessibilityPreFocusId(const RefPtr<NG::UINode>& currentNode, const RefPtr<NG::FrameNode>& rootNode,
1247 AccessibilityElementInfo& nodeInfo,
1248 const std::map<std::string, int64_t>& nextFocusIdMap)
1249 {
1250 auto currentFrameNode = AceType::DynamicCast<NG::FrameNode>(currentNode);
1251 CHECK_NULL_VOID(currentFrameNode);
1252
1253 auto currentInspectorId = currentFrameNode->GetInspectorId().value_or("");
1254 if (currentInspectorId == "") {
1255 return;
1256 }
1257 auto it = nextFocusIdMap.find(currentInspectorId);
1258 if (it != nextFocusIdMap.end()) {
1259 int64_t preAccessibilityId = it->second;
1260 nodeInfo.SetAccessibilityPreviousFocusId(preAccessibilityId);
1261 }
1262 }
1263
RemoveEntriesWithPreAccessibilityId(std::map<std::string,int64_t> & nextFocusMap,int64_t preAccessibilityId)1264 void RemoveEntriesWithPreAccessibilityId(std::map<std::string, int64_t>& nextFocusMap, int64_t preAccessibilityId)
1265 {
1266 for (auto mapIt = nextFocusMap.begin(); mapIt != nextFocusMap.end();) {
1267 if (mapIt->second == preAccessibilityId) {
1268 mapIt = nextFocusMap.erase(mapIt);
1269 } else {
1270 ++mapIt;
1271 }
1272 }
1273 }
1274
HandleExistingContext(std::map<int32_t,std::map<std::string,int64_t>>::iterator & it,const std::string & nextFocusInspectorKey,int64_t preAccessibilityId)1275 void HandleExistingContext(std::map<int32_t, std::map<std::string, int64_t>>::iterator& it,
1276 const std::string& nextFocusInspectorKey, int64_t preAccessibilityId)
1277 {
1278 if (nextFocusInspectorKey.empty()) {
1279 RemoveEntriesWithPreAccessibilityId(it->second, preAccessibilityId);
1280 } else {
1281 auto nextFocusMap = it->second;
1282 it->second[nextFocusInspectorKey] = preAccessibilityId;
1283 }
1284 }
1285
GetParentId(const RefPtr<NG::UINode> & uiNode)1286 int64_t GetParentId(const RefPtr<NG::UINode>& uiNode)
1287 {
1288 if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
1289 if (AceType::DynamicCast<NG::FrameNode>(uiNode)->IsFirstVirtualNode()) {
1290 auto weakNode = AceType::DynamicCast<NG::FrameNode>(uiNode)->GetVirtualNodeParent();
1291 auto refNode = weakNode.Upgrade();
1292 return refNode == nullptr ? INVALID_PARENT_ID : refNode->GetAccessibilityId();
1293 }
1294 }
1295 auto parent = uiNode->GetParent();
1296 while (parent) {
1297 if (AceType::InstanceOf<NG::FrameNode>(parent)) {
1298 if ((parent->GetTag() == V2::PAGE_ETS_TAG) || (parent->GetTag() == V2::STAGE_ETS_TAG) ||
1299 AceType::DynamicCast<NG::FrameNode>(parent)->CheckAccessibilityLevelNo()) {
1300 parent = parent->GetParent();
1301 continue;
1302 }
1303 return parent->GetAccessibilityId();
1304 }
1305 parent = parent->GetParent();
1306 }
1307 return INVALID_PARENT_ID;
1308 }
1309
FillElementInfo(int64_t elementId,AccessibilityElementInfo & elementInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param)1310 void FillElementInfo(int64_t elementId, AccessibilityElementInfo& elementInfo, const RefPtr<PipelineBase>& context,
1311 const RefPtr<JsAccessibilityManager>& jsAccessibilityManager, const FillEventInfoParam& param)
1312 {
1313 int64_t elementIdUnwrap = elementId;
1314 int64_t uiextensionId = 0;
1315 std::list<AccessibilityElementInfo> elementInfos;
1316 int32_t mode = 0;
1317 CHECK_NULL_VOID(jsAccessibilityManager);
1318 #ifdef WINDOW_SCENE_SUPPORTED
1319 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
1320 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
1321 CHECK_NULL_VOID(uiExtensionManager);
1322 if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
1323 auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(
1324 NG::UI_EXTENSION_OFFSET_MAX, elementIdUnwrap);
1325 elementIdUnwrap = unWrapIdPair.second;
1326 uiextensionId = unWrapIdPair.first;
1327 }
1328 #endif
1329 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
1330 "start to search elementId: %{public}" PRId64, elementIdUnwrap);
1331 jsAccessibilityManager->SearchElementInfoByAccessibilityIdNG(
1332 elementIdUnwrap, mode, elementInfos, context, NG::UI_EXTENSION_OFFSET_MAX);
1333 if (elementInfos.empty()) {
1334 LOGE("Element infos is empty. Find element infos failed.");
1335 return;
1336 }
1337 elementInfo = elementInfos.front();
1338 if (uiextensionId > 0) {
1339 elementIdUnwrap = (uiextensionId * NG::UI_EXTENSION_OFFSET_MAX) + elementInfo.GetAccessibilityId();
1340 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "elementIdUnwrap: %{public}" PRId64, elementIdUnwrap);
1341 }
1342 elementInfo.SetAccessibilityId(elementIdUnwrap);
1343 elementInfo.SetWindowId(param.windowId);
1344 jsAccessibilityManager->UpdateElementInfoInnerWindowId(elementInfo, elementId);
1345 }
1346
FillEventInfo(const RefPtr<NG::FrameNode> & node,AccessibilityEventInfo & eventInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param)1347 void FillEventInfo(const RefPtr<NG::FrameNode>& node,
1348 AccessibilityEventInfo& eventInfo,
1349 const RefPtr<PipelineBase>& context,
1350 const RefPtr<JsAccessibilityManager>& jsAccessibilityManager,
1351 const FillEventInfoParam& param)
1352 {
1353 CHECK_NULL_VOID(node);
1354 eventInfo.SetComponentType(node->GetTag());
1355 eventInfo.SetPageId(node->GetPageId());
1356 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1357 CHECK_NULL_VOID(accessibilityProperty);
1358 eventInfo.SetItemCounts(accessibilityProperty->GetCollectionItemCounts());
1359 eventInfo.SetBeginIndex(accessibilityProperty->GetBeginIndex());
1360 eventInfo.SetEndIndex(accessibilityProperty->GetEndIndex());
1361 AccessibilityElementInfo elementInfo;
1362 FillElementInfo(param.elementId, elementInfo, context, jsAccessibilityManager, param);
1363 if (param.stackNodeId != -1) {
1364 int64_t stackNodeId = param.stackNodeId;
1365 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(elementInfo.GetBelongTreeId(), stackNodeId);
1366 elementInfo.SetNavDestinationId(stackNodeId);
1367 }
1368 eventInfo.AddContent(elementInfo.GetContent());
1369 eventInfo.SetElementInfo(elementInfo);
1370 }
1371 #ifdef WEB_SUPPORTED
1372
FillWebElementInfo(int64_t elementId,AccessibilityElementInfo & elementInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param,const RefPtr<NG::WebPattern> & webPattern)1373 void FillWebElementInfo(int64_t elementId, AccessibilityElementInfo& elementInfo,
1374 const RefPtr<PipelineBase>& context,
1375 const RefPtr<JsAccessibilityManager>& jsAccessibilityManager,
1376 const FillEventInfoParam& param,
1377 const RefPtr<NG::WebPattern>& webPattern)
1378 {
1379 std::list<AccessibilityElementInfo> elementInfos;
1380 int32_t mode = 0;
1381 CHECK_NULL_VOID(jsAccessibilityManager);
1382 jsAccessibilityManager->SearchWebElementInfoByAccessibilityIdNG(
1383 elementId, mode, elementInfos, context, webPattern);
1384 if (elementInfos.empty()) {
1385 LOGE("Element infos is empty. Find element infos failed.");
1386 return;
1387 }
1388 elementInfo = elementInfos.front();
1389 elementInfo.SetWindowId(param.windowId);
1390 }
1391
FillWebEventInfo(AccessibilityEventInfo & eventInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param,const RefPtr<NG::WebPattern> & webPattern)1392 void FillWebEventInfo(AccessibilityEventInfo& eventInfo,
1393 const RefPtr<PipelineBase>& context,
1394 const RefPtr<JsAccessibilityManager>& jsAccessibilityManager,
1395 const FillEventInfoParam& param,
1396 const RefPtr<NG::WebPattern>& webPattern)
1397 {
1398 CHECK_NULL_VOID(webPattern);
1399 auto webNode = webPattern->GetHost();
1400 CHECK_NULL_VOID(webNode);
1401 eventInfo.SetPageId(webNode->GetPageId());
1402 AccessibilityElementInfo elementInfo;
1403 FillWebElementInfo(param.elementId, elementInfo, context, jsAccessibilityManager, param, webPattern);
1404 eventInfo.SetComponentType(elementInfo.GetComponentType());
1405 eventInfo.AddContent(elementInfo.GetContent());
1406 eventInfo.SetItemCounts(elementInfo.GetItemCounts());
1407 eventInfo.SetBeginIndex(elementInfo.GetBeginIndex());
1408 eventInfo.SetEndIndex(elementInfo.GetEndIndex());
1409 elementInfo.SetNavDestinationId(param.stackNodeId);
1410 eventInfo.SetElementInfo(elementInfo);
1411 }
1412 #endif
1413
FillEventInfo(const RefPtr<AccessibilityNode> & node,AccessibilityEventInfo & eventInfo)1414 void FillEventInfo(const RefPtr<AccessibilityNode>& node, AccessibilityEventInfo& eventInfo)
1415 {
1416 eventInfo.SetComponentType(node->GetTag());
1417 if (node->GetTag() == LIST_TAG) {
1418 eventInfo.SetItemCounts(node->GetListItemCounts());
1419 eventInfo.SetBeginIndex(node->GetListBeginIndex());
1420 eventInfo.SetEndIndex(node->GetListEndIndex());
1421 }
1422 eventInfo.SetPageId(node->GetPageId());
1423 eventInfo.AddContent(node->GetText());
1424 eventInfo.SetLatestContent(node->GetText());
1425 }
1426
IsPopupSupported(const RefPtr<NG::PipelineContext> & pipeline,int64_t nodeId)1427 inline bool IsPopupSupported(const RefPtr<NG::PipelineContext>& pipeline, int64_t nodeId)
1428 {
1429 CHECK_NULL_RETURN(pipeline, false);
1430 auto overlayManager = pipeline->GetOverlayManager();
1431 if (overlayManager) {
1432 return overlayManager->HasPopupInfo(nodeId);
1433 }
1434 return false;
1435 }
1436
SetAccessibilityFocusAction(AccessibilityElementInfo & nodeInfo,const char * tag)1437 void SetAccessibilityFocusAction(AccessibilityElementInfo& nodeInfo, const char* tag)
1438 {
1439 if (nodeInfo.HasAccessibilityFocus()) {
1440 AccessibleAction action(ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, tag);
1441 nodeInfo.AddAction(action);
1442 } else {
1443 AccessibleAction action(ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, tag);
1444 nodeInfo.AddAction(action);
1445 }
1446 }
1447
UpdateSupportAction(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo)1448 void UpdateSupportAction(const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo)
1449 {
1450 CHECK_NULL_VOID(node);
1451 if (nodeInfo.IsFocusable()) {
1452 if (nodeInfo.IsFocused()) {
1453 AccessibleAction action(ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ace");
1454 nodeInfo.AddAction(action);
1455 } else {
1456 AccessibleAction action(ACCESSIBILITY_ACTION_FOCUS, "ace");
1457 nodeInfo.AddAction(action);
1458 }
1459 }
1460
1461 auto eventHub = node->GetOrCreateEventHub<NG::EventHub>();
1462 CHECK_NULL_VOID(eventHub);
1463 auto gestureEventHub = eventHub->GetGestureEventHub();
1464 CHECK_NULL_VOID(gestureEventHub);
1465 nodeInfo.SetClickable(gestureEventHub->IsAccessibilityClickable());
1466 if (gestureEventHub->IsAccessibilityClickable()) {
1467 AccessibleAction action(ACCESSIBILITY_ACTION_CLICK, "ace");
1468 nodeInfo.AddAction(action);
1469 }
1470 nodeInfo.SetLongClickable(gestureEventHub->IsAccessibilityLongClickable());
1471 if (gestureEventHub->IsAccessibilityLongClickable()) {
1472 AccessibleAction action(ACCESSIBILITY_ACTION_LONG_CLICK, "ace");
1473 nodeInfo.AddAction(action);
1474 }
1475 }
1476
UpdateUserAccessibilityElementInfo(const RefPtr<NG::AccessibilityProperty> & accessibilityProperty,AccessibilityElementInfo & nodeInfo)1477 void UpdateUserAccessibilityElementInfo(
1478 const RefPtr<NG::AccessibilityProperty>& accessibilityProperty, AccessibilityElementInfo& nodeInfo)
1479 {
1480 CHECK_NULL_VOID(accessibilityProperty);
1481 if (accessibilityProperty->HasUserDisabled()) {
1482 nodeInfo.SetEnabled(!accessibilityProperty->IsUserDisabled());
1483 }
1484 if (accessibilityProperty->HasUserCheckedType()) {
1485 nodeInfo.SetChecked(accessibilityProperty->GetUserCheckedType());
1486 } else {
1487 nodeInfo.SetChecked(accessibilityProperty->IsChecked());
1488 }
1489 if (accessibilityProperty->HasUserSelected()) {
1490 nodeInfo.SetSelected(accessibilityProperty->IsUserSelected());
1491 } else {
1492 nodeInfo.SetSelected(accessibilityProperty->IsSelected());
1493 }
1494
1495 if (nodeInfo.IsEnabled()) {
1496 if (accessibilityProperty->HasUserCheckable()) {
1497 nodeInfo.SetCheckable(accessibilityProperty->IsUserCheckable());
1498 } else {
1499 nodeInfo.SetCheckable(accessibilityProperty->IsCheckable());
1500 }
1501 }
1502 }
1503
IsUserCheckedOrSelected(const RefPtr<NG::FrameNode> frameNode)1504 bool IsUserCheckedOrSelected(const RefPtr<NG::FrameNode> frameNode)
1505 {
1506 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1507 CHECK_NULL_RETURN(accessibilityProperty, false);
1508 if (accessibilityProperty->HasUserCheckedType() || accessibilityProperty->HasUserSelected()) {
1509 return true;
1510 }
1511 return false;
1512 }
1513
UpdateAccessibilityTextValueInfo(RefPtr<NG::AccessibilityProperty> & accessibilityProperty,AccessibilityElementInfo & nodeInfo)1514 void UpdateAccessibilityTextValueInfo(
1515 RefPtr<NG::AccessibilityProperty>& accessibilityProperty, AccessibilityElementInfo& nodeInfo)
1516 {
1517 if (accessibilityProperty->HasUserTextValue()) {
1518 nodeInfo.SetContent(accessibilityProperty->GetUserTextValue());
1519 } else {
1520 nodeInfo.SetContent(accessibilityProperty->GetGroupText());
1521 }
1522
1523 if (!accessibilityProperty->HasUserTextValue() && accessibilityProperty->GetAccessibilityText().empty() &&
1524 accessibilityProperty->IsAccessibilityGroup() && accessibilityProperty->IsAccessibilityTextPreferred()) {
1525 nodeInfo.SetAccessibilityText(accessibilityProperty->GetGroupPreferAccessibilityText());
1526 } else {
1527 nodeInfo.SetAccessibilityText(accessibilityProperty->GetAccessibilityText());
1528 }
1529 nodeInfo.SetOriginalText(accessibilityProperty->GetText());
1530 }
1531
UpdateElementInfoPageIdWithTreeId(Accessibility::AccessibilityElementInfo & info,int32_t treeId)1532 void UpdateElementInfoPageIdWithTreeId(Accessibility::AccessibilityElementInfo& info, int32_t treeId)
1533 {
1534 int32_t pageId = info.GetPageId();
1535 if ((pageId >= MAX_PAGE_ID_WITH_SUB_TREE) || (pageId < 0)) {
1536 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "pageId %{public}d cannot set tree id", pageId);
1537 } else {
1538 uint32_t unsignedPageId = static_cast<uint32_t>(pageId);
1539 uint32_t unsignedTreeId = static_cast<uint32_t>(treeId);
1540 info.SetPageId((unsignedTreeId << SUB_TREE_OFFSET_IN_PAGE_ID) | unsignedPageId);
1541 }
1542 }
1543
ScrollByOffsetToParent(const RefPtr<NG::FrameNode> & curFrameNode,const RefPtr<NG::FrameNode> & parentFrameNode)1544 bool ScrollByOffsetToParent(const RefPtr<NG::FrameNode>& curFrameNode, const RefPtr<NG::FrameNode>& parentFrameNode)
1545 {
1546 CHECK_NULL_RETURN(curFrameNode, false);
1547 CHECK_NULL_RETURN(parentFrameNode, false);
1548 auto parentPattern = parentFrameNode->GetPattern<NG::ScrollablePattern>();
1549 CHECK_NULL_RETURN(parentPattern, false);
1550
1551 auto scrollAbility = parentPattern->GetScrollOffsetAbility();
1552 auto scrollFunc = scrollAbility.scrollFunc;
1553 auto scrollAxis = scrollAbility.axis;
1554 if (!scrollFunc || scrollAxis == Axis::NONE) {
1555 return false;
1556 }
1557 if (parentFrameNode->GetTag() == V2::SCROLL_ETS_TAG) {
1558 return false;
1559 }
1560 NG::MoveOffsetParam param {
1561 scrollAxis == Axis::VERTICAL,
1562 scrollAbility.contentStartOffset,
1563 scrollAbility.contentEndOffset,
1564 true
1565 };
1566 auto moveOffset = NG::ScrollableUtils::GetMoveOffset(parentFrameNode, curFrameNode, param);
1567 if (!NearZero(moveOffset)) {
1568 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Scroll offset: %{public}f on %{public}s/%{public}d, axis: %{public}d",
1569 moveOffset, parentFrameNode->GetTag().c_str(), parentFrameNode->GetId(), scrollAxis);
1570 auto ret = scrollFunc(parentPattern->IsReverse() ? -moveOffset : moveOffset);
1571 auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
1572 if (pipeline) {
1573 pipeline->FlushUITasks();
1574 }
1575 return ret;
1576 }
1577 return false;
1578 }
1579
ScrollByOffset(const RefPtr<NG::FrameNode> & curFrameNode)1580 bool ScrollByOffset(const RefPtr<NG::FrameNode>& curFrameNode)
1581 {
1582 CHECK_NULL_RETURN(curFrameNode, false);
1583 bool ret = false;
1584 auto parentFrameNode = curFrameNode->GetParentFrameNode();
1585
1586 while (parentFrameNode) {
1587 auto accessibilityProperty = parentFrameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1588 if (accessibilityProperty && !accessibilityProperty->IsUserScrollTriggerable()) {
1589 return false;
1590 }
1591 if (ScrollByOffsetToParent(curFrameNode, parentFrameNode)) {
1592 ret = true;
1593 }
1594 parentFrameNode = parentFrameNode->GetParentFrameNode();
1595 }
1596 return ret;
1597 }
1598
ProcessFocusScroll(const RefPtr<NG::FrameNode> & curFrameNode,RefPtr<NG::PipelineContext> & context)1599 void ProcessFocusScroll(const RefPtr<NG::FrameNode>& curFrameNode, RefPtr<NG::PipelineContext>& context)
1600 {
1601 CHECK_NULL_VOID(context);
1602 context->GetTaskExecutor()->PostTask(
1603 [node = AceType::WeakClaim(AceType::RawPtr(curFrameNode))] {
1604 auto focusNode = node.Upgrade();
1605 CHECK_NULL_VOID(focusNode);
1606 auto accessibilityProperty = focusNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1607 CHECK_NULL_VOID(accessibilityProperty);
1608 if (accessibilityProperty->GetAccessibilityFocusState()) {
1609 ScrollByOffset(focusNode);
1610 }
1611 },
1612 TaskExecutor::TaskType::UI, "ArkUIAccessibilityProcessFocusScroll");
1613 }
1614
GetLastPageId(const RefPtr<NG::PipelineContext> & ngPipeline)1615 int32_t GetLastPageId(const RefPtr<NG::PipelineContext>& ngPipeline)
1616 {
1617 CHECK_NULL_RETURN(ngPipeline, -1);
1618 auto stageManager = ngPipeline->GetStageManager();
1619 CHECK_NULL_RETURN(stageManager, -1);
1620 auto page = stageManager->GetLastPageWithTransition();
1621 CHECK_NULL_RETURN(page, -1);
1622 return page->GetPageId();
1623 }
1624
AddHasRegisteredHover(const RefPtr<NG::FrameNode> & node,ExtraElementInfo & extraElementInfo)1625 void AddHasRegisteredHover(const RefPtr<NG::FrameNode>& node, ExtraElementInfo& extraElementInfo)
1626 {
1627 CHECK_NULL_VOID(node);
1628 auto eventHub = node->GetOrCreateEventHub<NG::EventHub>();
1629 CHECK_NULL_VOID(eventHub);
1630 auto inputEventHub = eventHub->GetInputEventHub();
1631 CHECK_NULL_VOID(inputEventHub);
1632 if (inputEventHub->HasAccessibilityHoverEvent()) {
1633 extraElementInfo.SetExtraElementInfo("hasRegisteredHover", true);
1634 }
1635 }
1636
UpdateWebEmbedParent(std::list<AccessibilityElementInfo> & infos,const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty)1637 void UpdateWebEmbedParent(std::list<AccessibilityElementInfo>& infos,
1638 const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty)
1639 {
1640 if (infos.empty() || !commonProperty.checkGetFunc) {
1641 return;
1642 }
1643 auto webEmbedNodeId = commonProperty.checkGetFunc(node);
1644 CHECK_EQUAL_VOID(webEmbedNodeId, INVALID_NODE_ID);
1645 auto& frontElementInfo = infos.front();
1646 frontElementInfo.SetParent(webEmbedNodeId);
1647 }
1648 } // namespace
1649
IsTagInEmbedComponent(const std::string & tag)1650 bool JsAccessibilityManager::IsTagInEmbedComponent(const std::string& tag)
1651 {
1652 return TAGS_EMBED_COMPONENT.find(tag) != TAGS_EMBED_COMPONENT.end();
1653 }
1654
UpdateAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo)1655 void JsAccessibilityManager::UpdateAccessibilityElementInfo(
1656 const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo)
1657 {
1658 CHECK_NULL_VOID(node);
1659 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1660 CHECK_NULL_VOID(accessibilityProperty);
1661 if (accessibilityProperty->HasAccessibilityRole()) {
1662 nodeInfo.SetComponentType(accessibilityProperty->GetAccessibilityRole());
1663 }
1664 if (accessibilityProperty->HasAccessibilityCustomRole()) {
1665 nodeInfo.SetCustomComponentType(accessibilityProperty->GetAccessibilityCustomRole());
1666 }
1667
1668 UpdateAccessibilityTextValueInfo(accessibilityProperty, nodeInfo);
1669
1670 RangeInfo rangeInfo = ConvertAccessibilityValue(accessibilityProperty->GetAccessibilityValue());
1671 if (accessibilityProperty->HasUserRangeCurrentValue()) {
1672 rangeInfo.SetCurrent(accessibilityProperty->GetUserRangeCurrentValue());
1673 }
1674 if (accessibilityProperty->HasUserRangeMinValue()) {
1675 rangeInfo.SetMin(accessibilityProperty->GetUserRangeMinValue());
1676 }
1677 if (accessibilityProperty->HasUserRangeMaxValue()) {
1678 rangeInfo.SetMax(accessibilityProperty->GetUserRangeMaxValue());
1679 }
1680 nodeInfo.SetRange(rangeInfo);
1681 if (accessibilityProperty->HasSubComponent()) {
1682 std::vector<SubComponentInfo> subComponentInfos;
1683 accessibilityProperty->GetSubComponentInfo(subComponentInfos);
1684 for (const auto& subComponent : subComponentInfos) {
1685 nodeInfo.AddSpan(SpanInfo(subComponent.spanId, subComponent.spanText,
1686 subComponent.accessibilityText, subComponent.accessibilityDescription,
1687 subComponent.accessibilityLevel));
1688 }
1689 }
1690 nodeInfo.SetAccessibilityNextFocusInspectorKey(accessibilityProperty->GetAccessibilityNextFocusInspectorKey());
1691 nodeInfo.SetAccessibilityScrollable(accessibilityProperty->IsUserScrollTriggerable());
1692 nodeInfo.SetHint(accessibilityProperty->GetHintText());
1693 nodeInfo.SetAccessibilityGroup(accessibilityProperty->IsAccessibilityGroup());
1694 nodeInfo.SetAccessibilityLevel(accessibilityProperty->GetAccessibilityLevel());
1695 nodeInfo.SetTextType(accessibilityProperty->GetTextType());
1696 nodeInfo.SetTextLengthLimit(accessibilityProperty->GetTextLengthLimit());
1697 nodeInfo.SetOffset(accessibilityProperty->GetScrollOffSet());
1698 auto context = node->GetRenderContext();
1699 if (context != nullptr) {
1700 nodeInfo.SetZIndex(context->GetZIndex().value_or(0));
1701 nodeInfo.SetOpacity(context->GetOpacity().value_or(1));
1702 nodeInfo.SetBackgroundColor(context->GetBackgroundColor().value_or(Color::TRANSPARENT).ToString());
1703 nodeInfo.SetBackgroundImage(context->GetBackgroundImage().value_or(ImageSourceInfo("")).ToString());
1704 if (context->GetForeground() != nullptr) {
1705 nodeInfo.SetBlur(context->GetForeground()->propBlurRadius.value_or(Dimension(0)).ToString());
1706 }
1707 }
1708 auto eventHub = node->GetOrCreateEventHub<NG::EventHub>();
1709 if (eventHub != nullptr) {
1710 nodeInfo.SetHitTestBehavior(NG::GestureEventHub::GetHitTestModeStr(eventHub->GetGestureEventHub()));
1711 }
1712
1713 UpdateUserAccessibilityElementInfo(accessibilityProperty, nodeInfo);
1714
1715 nodeInfo.SetPassword(accessibilityProperty->IsPassword());
1716 nodeInfo.SetPluraLineSupported(accessibilityProperty->IsMultiLine());
1717 nodeInfo.SetHinting(accessibilityProperty->IsHint());
1718 nodeInfo.SetDescriptionInfo(accessibilityProperty->GetAccessibilityDescription());
1719 if (accessibilityProperty->HasUserCurrentValue()) {
1720 nodeInfo.SetCurrentIndex(accessibilityProperty->GetUserCurrentValue());
1721 } else {
1722 nodeInfo.SetCurrentIndex(accessibilityProperty->GetCurrentIndex());
1723 }
1724 if (accessibilityProperty->HasUserMinValue()) {
1725 nodeInfo.SetBeginIndex(accessibilityProperty->GetUserMinValue());
1726 } else {
1727 nodeInfo.SetBeginIndex(accessibilityProperty->GetBeginIndex());
1728 }
1729 if (accessibilityProperty->HasUserMaxValue()) {
1730 nodeInfo.SetEndIndex(accessibilityProperty->GetUserMaxValue());
1731 } else {
1732 nodeInfo.SetEndIndex(accessibilityProperty->GetEndIndex());
1733 }
1734 auto tag = node->GetTag();
1735 if (tag == V2::TOAST_ETS_TAG || tag == V2::POPUP_ETS_TAG || tag == V2::DIALOG_ETS_TAG ||
1736 tag == V2::ACTION_SHEET_DIALOG_ETS_TAG || tag == V2::ALERT_DIALOG_ETS_TAG || tag == V2::MENU_ETS_TAG ||
1737 tag == "SelectMenu") {
1738 nodeInfo.SetLiveRegion(1);
1739 }
1740 nodeInfo.SetContentInvalid(accessibilityProperty->GetContentInvalid());
1741 nodeInfo.SetError(accessibilityProperty->GetErrorText());
1742 nodeInfo.SetSelectedBegin(accessibilityProperty->GetTextSelectionStart());
1743 nodeInfo.SetSelectedEnd(accessibilityProperty->GetTextSelectionEnd());
1744 nodeInfo.SetInputType(static_cast<int>(accessibilityProperty->GetTextInputType()));
1745 nodeInfo.SetItemCounts(accessibilityProperty->GetCollectionItemCounts());
1746 nodeInfo.SetChildTreeIdAndWinId(
1747 accessibilityProperty->GetChildTreeId(), accessibilityProperty->GetChildWindowId());
1748 if (nodeInfo.GetComponentType() == "FormComponent") {
1749 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", Set: %{public}d %{public}d",
1750 nodeInfo.GetAccessibilityId(), accessibilityProperty->GetChildTreeId(),
1751 accessibilityProperty->GetChildWindowId());
1752 }
1753 if (nodeInfo.GetWindowId() == static_cast<int32_t>(windowId_)) {
1754 nodeInfo.SetBelongTreeId(treeId_);
1755 nodeInfo.SetParentWindowId(parentWindowId_);
1756 } else {
1757 nodeInfo.SetBelongTreeId(0);
1758 nodeInfo.SetParentWindowId(0);
1759 }
1760
1761 GridInfo gridInfo(accessibilityProperty->GetCollectionInfo().rows,
1762 accessibilityProperty->GetCollectionInfo().columns, accessibilityProperty->GetCollectionInfo().selectMode);
1763 nodeInfo.SetGrid(gridInfo);
1764 ExtraElementInfo extraElementInfo {};
1765 accessibilityProperty->GetAllExtraElementInfo(extraElementInfo);
1766 AddHasRegisteredHover(node, extraElementInfo);
1767 if (node->IsAccessibilityVirtualNode()) {
1768 auto parentUinode = node->GetVirtualNodeParent().Upgrade();
1769 if (parentUinode) {
1770 auto parentFrame = AceType::DynamicCast<NG::FrameNode>(parentUinode);
1771 AddHasRegisteredHover(parentFrame, extraElementInfo);
1772 }
1773 }
1774 nodeInfo.SetExtraElement(extraElementInfo);
1775
1776 int32_t row = accessibilityProperty->GetCollectionItemInfo().row;
1777 int32_t column = accessibilityProperty->GetCollectionItemInfo().column;
1778 int32_t rowSpan = accessibilityProperty->GetCollectionItemInfo().rowSpan;
1779 int32_t columnSpan = accessibilityProperty->GetCollectionItemInfo().columnSpan;
1780 bool heading = accessibilityProperty->GetCollectionItemInfo().heading;
1781 GridItemInfo gridItemInfo(row, rowSpan, column, columnSpan, heading, nodeInfo.IsSelected());
1782 nodeInfo.SetGridItem(gridItemInfo);
1783
1784 SetAccessibilityFocusAction(nodeInfo, "ace");
1785 if (nodeInfo.IsEnabled()) {
1786 nodeInfo.SetScrollable(accessibilityProperty->IsScrollable());
1787 nodeInfo.SetEditable(accessibilityProperty->IsEditable());
1788 nodeInfo.SetDeletable(accessibilityProperty->IsDeletable());
1789 UpdateSupportAction(node, nodeInfo);
1790 accessibilityProperty->ResetSupportAction();
1791 auto supportAceActions = accessibilityProperty->GetSupportAction();
1792 for (auto it = supportAceActions.begin(); it != supportAceActions.end(); ++it) {
1793 AccessibleAction action(ConvertAceAction(*it), "ace");
1794 nodeInfo.AddAction(action);
1795 }
1796 }
1797 }
1798 #ifdef WEB_SUPPORTED
1799
UpdateWebAccessibilityElementInfo(const std::shared_ptr<NG::TransitionalNodeInfo> & node,AccessibilityElementInfo & nodeInfo,int32_t treeId)1800 void JsAccessibilityManager::UpdateWebAccessibilityElementInfo(
1801 const std::shared_ptr<NG::TransitionalNodeInfo>& node, AccessibilityElementInfo& nodeInfo, int32_t treeId)
1802 {
1803 CHECK_NULL_VOID(node);
1804 nodeInfo.SetContent(node->GetContent());
1805 nodeInfo.SetOriginalText(node->GetContent());
1806 nodeInfo.SetAccessibilityText(node->GetContent());
1807 RangeInfo rangeInfo(node->GetRangeInfoMin(), node->GetRangeInfoMax(), node->GetRangeInfoCurrent());
1808 nodeInfo.SetRange(rangeInfo);
1809 nodeInfo.SetHint(node->GetHint());
1810 nodeInfo.SetHinting(node->GetIsHinting());
1811 nodeInfo.SetDescriptionInfo(node->GetDescriptionInfo());
1812 nodeInfo.SetChecked(node->GetIsChecked());
1813 nodeInfo.SetSelected(node->GetIsSelected());
1814 nodeInfo.SetPassword(node->GetIsPassword());
1815 nodeInfo.SetPluraLineSupported(node->GetIsPluralLineSupported());
1816 nodeInfo.SetLiveRegion(node->GetLiveRegion());
1817 nodeInfo.SetContentInvalid(node->GetIsContentInvalid());
1818 nodeInfo.SetError(node->GetError());
1819 nodeInfo.SetSelectedBegin(node->GetSelectionStart());
1820 nodeInfo.SetSelectedEnd(node->GetSelectionEnd());
1821 nodeInfo.SetInputType(node->GetInputType());
1822 nodeInfo.SetItemCounts(node->GetItemCounts());
1823
1824 nodeInfo.SetBelongTreeId(treeId);
1825 nodeInfo.SetParentWindowId(parentWebWindowId_);
1826 GridInfo gridInfo(node->GetGridRows(), node->GetGridColumns(), node->GetGridSelectedMode());
1827 nodeInfo.SetGrid(gridInfo);
1828
1829 int32_t row = node->GetGridItemRow();
1830 int32_t column = node->GetGridItemColumn();
1831 int32_t rowSpan = node->GetGridItemRowSpan();
1832 int32_t columnSpan = node->GetGridItemColumnSpan();
1833 bool heading = node->GetIsHeading();
1834 GridItemInfo gridItemInfo(row, rowSpan, column, columnSpan, heading, nodeInfo.IsSelected());
1835 nodeInfo.SetGridItem(gridItemInfo);
1836
1837 SetAccessibilityFocusAction(nodeInfo, "web");
1838 nodeInfo.SetCheckable(node->GetIsCheckable());
1839 nodeInfo.SetScrollable(node->GetIsScrollable());
1840 nodeInfo.SetEditable(node->GetIsEditable());
1841 nodeInfo.SetDeletable(node->GetIsDeletable());
1842 nodeInfo.SetClickable(node->GetIsClickable());
1843 auto supportAceActions = node->GetActions();
1844 for (auto it = supportAceActions.begin(); it != supportAceActions.end(); ++it) {
1845 AccessibleAction action(ConvertAceAction(static_cast<AceAction>(*it)), "web");
1846 nodeInfo.AddAction(action);
1847 }
1848 nodeInfo.SetAccessibilityGroup(node->GetIsAccessibilityGroup());
1849 ExtraElementInfo extraElementInfo {};
1850 extraElementInfo.SetExtraElementInfo("componentTypeDescription", node->GetComponentTypeDescription());
1851 extraElementInfo.SetExtraElementInfo("CheckboxGroupSelectedStatus", node->GetCheckboxGroupSelectedStatus());
1852 extraElementInfo.SetExtraElementInfo("expandedState", node->GetExpandedState());
1853 nodeInfo.SetExtraElement(extraElementInfo);
1854 }
1855
1856 #endif
1857 namespace {
UpdateChildrenOfAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo)1858 void UpdateChildrenOfAccessibilityElementInfo(
1859 const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty, AccessibilityElementInfo& nodeInfo)
1860 {
1861 if (!NeedUpdateChildrenOfAccessibilityElementInfo(node)) {
1862 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "Node %{public}s not need update children"
1863 " of accessibilityElementInfo", node->GetTag().c_str());
1864 return;
1865 }
1866 if (!IsExtensionComponent(node) || IsUIExtensionShowPlaceholder(node)) {
1867 std::vector<std::pair<int64_t, int32_t>> childrenIdInfo;
1868 for (const auto& item : node->GetChildren(true)) {
1869 GetFrameNodeChildren(item, childrenIdInfo, commonProperty);
1870 }
1871
1872 auto overlayNode = node->GetOverlayNode();
1873 if (overlayNode != nullptr) {
1874 GetFrameNodeChildren(overlayNode, childrenIdInfo, commonProperty);
1875 }
1876
1877 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1878 auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
1879 if (uiVirtualNode != nullptr) {
1880 auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
1881 if (virtualNode != nullptr) {
1882 childrenIdInfo.clear();
1883 GetFrameNodeChildren(virtualNode, childrenIdInfo, commonProperty);
1884 }
1885 }
1886 std::sort(childrenIdInfo.begin(), childrenIdInfo.end(),
1887 [](const auto&zIndexA, const auto&zIndexB) { return zIndexA.second < zIndexB.second; });
1888 for (const auto& childrenIdPair : childrenIdInfo) {
1889 nodeInfo.AddChild(childrenIdPair.first);
1890 }
1891 }
1892 }
1893
1894 }
1895
UpdateVirtualNodeChildAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeParentInfo,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::PipelineContext> & ngPipeline)1896 void JsAccessibilityManager::UpdateVirtualNodeChildAccessibilityElementInfo(
1897 const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty,
1898 AccessibilityElementInfo& nodeParentInfo, AccessibilityElementInfo& nodeInfo,
1899 const RefPtr<NG::PipelineContext>& ngPipeline)
1900 {
1901 CHECK_NULL_VOID(node);
1902 nodeInfo.SetParent(GetParentId(node));
1903 UpdateChildrenOfAccessibilityElementInfo(node, commonProperty, nodeInfo);
1904
1905 nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
1906 nodeInfo.SetComponentType(node->GetTag());
1907 nodeInfo.SetUniqueId(node->GetId());
1908
1909 nodeInfo.SetEnabled(node->GetFocusHub() ? node->GetFocusHub()->IsEnabled() : true);
1910 nodeInfo.SetFocused(node->GetFocusHub() ? node->GetFocusHub()->IsCurrentFocus() : false);
1911 nodeInfo.SetAccessibilityFocus(node->GetRenderContext()->GetAccessibilityFocus().value_or(false));
1912 nodeInfo.SetInspectorKey(node->GetInspectorId().value_or(""));
1913 nodeInfo.SetVisible(node->IsVisible());
1914 if (node->IsVisible()) {
1915 auto rect = node->GetVirtualNodeTransformRectRelativeToWindow();
1916 auto left = static_cast<int32_t>(rect.Left() + commonProperty.windowLeft);
1917 auto top = static_cast<int32_t>(rect.Top() + commonProperty.windowTop);
1918 auto right = static_cast<int32_t>(rect.Right() + commonProperty.windowLeft);
1919 auto bottom = static_cast<int32_t>(rect.Bottom() + commonProperty.windowTop);
1920 Accessibility::Rect bounds { left, top, right, bottom };
1921 nodeInfo.SetRectInScreen(bounds);
1922 }
1923 nodeInfo.SetWindowId(commonProperty.windowId);
1924 nodeInfo.SetInnerWindowId(commonProperty.innerWindowId);
1925 nodeInfo.SetPageId(node->GetPageId());
1926 nodeInfo.SetPagePath(
1927 GetPagePathInPageNodes(nodeInfo.GetPageId(), commonProperty.pageNodes, commonProperty.pagePaths));
1928 nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
1929
1930 if (nodeInfo.IsEnabled()) {
1931 nodeInfo.SetFocusable(node->GetFocusHub() ? node->GetFocusHub()->IsFocusable() : false);
1932 nodeInfo.SetPopupSupported(IsPopupSupported(ngPipeline, node->GetId()));
1933 }
1934 nodeInfo.SetComponentResourceId(node->GetInspectorId().value_or(""));
1935 UpdateAccessibilityElementInfo(node, nodeInfo);
1936 }
1937
UpdateVirtualNodeAccessibilityElementInfo(const RefPtr<NG::FrameNode> & parent,const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::PipelineContext> & ngPipeline)1938 void JsAccessibilityManager::UpdateVirtualNodeAccessibilityElementInfo(
1939 const RefPtr<NG::FrameNode>& parent, const RefPtr<NG::FrameNode>& node,
1940 const CommonProperty& commonProperty, AccessibilityElementInfo& nodeInfo,
1941 const RefPtr<NG::PipelineContext>& ngPipeline)
1942 {
1943 CHECK_NULL_VOID(parent);
1944 CHECK_NULL_VOID(node);
1945 nodeInfo.SetParent(GetParentId(node));
1946 UpdateChildrenOfAccessibilityElementInfo(node, commonProperty, nodeInfo);
1947
1948 nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
1949 nodeInfo.SetComponentType(node->GetTag());
1950 nodeInfo.SetUniqueId(node->GetId());
1951
1952 nodeInfo.SetEnabled(node->GetFocusHub() ? node->GetFocusHub()->IsEnabled() : true);
1953 nodeInfo.SetFocused(node->GetFocusHub() ? node->GetFocusHub()->IsCurrentFocus() : false);
1954 nodeInfo.SetAccessibilityFocus(node->GetRenderContext()->GetAccessibilityFocus().value_or(false));
1955 nodeInfo.SetInspectorKey(node->GetInspectorId().value_or(""));
1956 nodeInfo.SetVisible(node->IsVisible());
1957 if (node->IsVisible()) {
1958 auto virtualNodeRect = node->GetTransformRectRelativeToWindow();
1959 auto parentRect = parent->GetTransformRectRelativeToWindow();
1960 auto left = static_cast<int32_t>(parentRect.Left() + commonProperty.windowLeft);
1961 auto top = static_cast<int32_t>(parentRect.Top() + commonProperty.windowTop);
1962 auto right = static_cast<int32_t>(parentRect.Left() + virtualNodeRect.Width() + commonProperty.windowLeft);
1963 if (virtualNodeRect.Width() > (parentRect.Right() - parentRect.Left())) {
1964 right = static_cast<int32_t>(parentRect.Right() + commonProperty.windowLeft);
1965 }
1966 auto bottom = static_cast<int32_t>(parentRect.Top() + virtualNodeRect.Height() + commonProperty.windowTop);
1967 if (virtualNodeRect.Height() > (parentRect.Bottom() - parentRect.Top())) {
1968 bottom = static_cast<int32_t>(parentRect.Bottom() + commonProperty.windowTop);
1969 }
1970 Accessibility::Rect bounds { left, top, right, bottom };
1971 nodeInfo.SetRectInScreen(bounds);
1972 }
1973 nodeInfo.SetWindowId(commonProperty.windowId);
1974 nodeInfo.SetInnerWindowId(commonProperty.innerWindowId);
1975 nodeInfo.SetPageId(node->GetPageId());
1976 nodeInfo.SetPagePath(
1977 GetPagePathInPageNodes(nodeInfo.GetPageId(), commonProperty.pageNodes, commonProperty.pagePaths));
1978 nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
1979
1980 if (nodeInfo.IsEnabled()) {
1981 nodeInfo.SetFocusable(node->GetFocusHub() ? node->GetFocusHub()->IsFocusable() : false);
1982 nodeInfo.SetPopupSupported(IsPopupSupported(ngPipeline, node->GetId()));
1983 }
1984 nodeInfo.SetComponentResourceId(node->GetInspectorId().value_or(""));
1985 UpdateAccessibilityElementInfo(node, nodeInfo);
1986 }
1987
1988 namespace {
GetPositionToWindowWithTransform(NG::OffsetF & offset,NG::OffsetF & offsetBottom,const RefPtr<NG::FrameNode> & node)1989 void GetPositionToWindowWithTransform(NG::OffsetF& offset, NG::OffsetF& offsetBottom, const RefPtr<NG::FrameNode>& node)
1990 {
1991 CHECK_NULL_VOID(node);
1992 auto context = node->GetRenderContext();
1993 CHECK_NULL_VOID(context);
1994 auto rect = context->GetPaintRectWithoutTransform();
1995
1996 offset = rect.GetOffset();
1997 offsetBottom = NG::OffsetF(rect.GetX() + rect.Width(), rect.GetY() + rect.Height());
1998
1999 NG::PointF leftTopPointNode(offset.GetX(), offset.GetY());
2000 NG::PointF rightBottomPointNode(rect.GetX() + rect.Width(), rect.GetY() + rect.Height());
2001 context->GetPointTransformRotate(leftTopPointNode);
2002 context->GetPointTransformRotate(rightBottomPointNode);
2003 auto parent = node->GetAncestorNodeOfFrame(true);
2004 while (parent) {
2005 // if get the window boundary (window scene), not calculate transform
2006 if (!parent->IsWindowBoundary()) {
2007 auto parentRenderContext = parent->GetRenderContext();
2008 if (!parentRenderContext) {
2009 parent = parent->GetAncestorNodeOfFrame(true);
2010 continue;
2011 }
2012 auto parentOffset = parentRenderContext->GetPaintRectWithoutTransform().GetOffset();
2013 NG::PointF leftTopPointAfterAddOffset(parentOffset.GetX() + leftTopPointNode.GetX(),
2014 parentOffset.GetY() + leftTopPointNode.GetY());
2015 NG::PointF rightBottomPointAfterAddOffset(parentOffset.GetX() + rightBottomPointNode.GetX(),
2016 parentOffset.GetY() + rightBottomPointNode.GetY());
2017
2018 auto parentTransformMat = parentRenderContext->GetMatrixWithTransformRotate();
2019 Point leftTop(leftTopPointAfterAddOffset.GetX(), leftTopPointAfterAddOffset.GetY());
2020 Point rightBottom(rightBottomPointAfterAddOffset.GetX(), rightBottomPointAfterAddOffset.GetY());
2021 auto leftTopPoint = parentTransformMat * leftTop;
2022 auto rightBottomPoint = parentTransformMat * rightBottom;
2023 leftTopPointNode.SetX(leftTopPoint.GetX());
2024 leftTopPointNode.SetY(leftTopPoint.GetY());
2025 rightBottomPointNode.SetX(rightBottomPoint.GetX());
2026 rightBottomPointNode.SetY(rightBottomPoint.GetY());
2027 }
2028 parent = parent->GetAncestorNodeOfFrame(true);
2029 }
2030 offset.SetX(leftTopPointNode.GetX());
2031 offset.SetY(leftTopPointNode.GetY());
2032 offsetBottom.SetX(rightBottomPointNode.GetX());
2033 offsetBottom.SetY(rightBottomPointNode.GetY());
2034 }
2035
GetFinalRealRect(const RefPtr<NG::FrameNode> & node)2036 NG::RectF GetFinalRealRect(const RefPtr<NG::FrameNode>& node)
2037 {
2038 if ((node->GetTag() == V2::WINDOW_SCENE_ETS_TAG) && node->IsWindowBoundary()) {
2039 auto renderContext = node->GetRenderContext();
2040 CHECK_NULL_RETURN(renderContext, NG::RectF());
2041 auto rect = renderContext->GetPaintRectWithoutTransform();
2042 // commonproperty will contain the offset and scale of the window scene
2043 return {0, 0, rect.Width(), rect.Height()};
2044 }
2045
2046 NG::OffsetF offset;
2047 NG::OffsetF offsetBottom;
2048 GetPositionToWindowWithTransform(offset, offsetBottom, node);
2049 return {
2050 LessNotEqual(offset.GetX(), offsetBottom.GetX()) ? offset.GetX() : offsetBottom.GetX(),
2051 LessNotEqual(offset.GetY(), offsetBottom.GetY()) ? offset.GetY() : offsetBottom.GetY(),
2052 LessNotEqual(offset.GetX(), offsetBottom.GetX())
2053 ? offsetBottom.GetX() - offset.GetX()
2054 : offset.GetX() - offsetBottom.GetX(),
2055 LessNotEqual(offset.GetY(), offsetBottom.GetY())
2056 ? offsetBottom.GetY() - offset.GetY()
2057 : offset.GetY() - offsetBottom.GetY()
2058 };
2059 }
2060
SetRectInScreen(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo,const CommonProperty & commonProperty)2061 void SetRectInScreen(const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo,
2062 const CommonProperty& commonProperty)
2063 {
2064 if (node->IsAccessibilityVirtualNode()) {
2065 auto rect = node->GetVirtualNodeTransformRectRelativeToWindow();
2066 auto left = static_cast<int32_t>(rect.Left() + commonProperty.windowLeft);
2067 auto top = static_cast<int32_t>(rect.Top() + commonProperty.windowTop);
2068 auto right = static_cast<int32_t>(rect.Right() + commonProperty.windowLeft);
2069 auto bottom = static_cast<int32_t>(rect.Bottom() + commonProperty.windowTop);
2070 Accessibility::Rect bounds { left, top, right, bottom };
2071 nodeInfo.SetRectInScreen(bounds);
2072 } else if (node->IsVisible()) {
2073 auto rect = GetFinalRealRect(node);
2074 auto rotateTransformData = commonProperty.rotateTransform;
2075 auto currentDegree = rotateTransformData.rotateDegree;
2076 if (!NearZero(currentDegree, 0)) {
2077 AccessibilityRect rotateRect(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2078 rotateRect.Rotate(rotateTransformData.innerCenterX, rotateTransformData.innerCenterY, currentDegree);
2079 rotateRect.ApplyTransformation(rotateTransformData, commonProperty.scaleX, commonProperty.scaleY);
2080 Accessibility::Rect bounds { static_cast<int32_t>(rotateRect.GetX()),
2081 static_cast<int32_t>(rotateRect.GetY()),
2082 static_cast<int32_t>(rotateRect.GetX() + rotateRect.GetWidth()),
2083 static_cast<int32_t>(rotateRect.GetY() + rotateRect.GetHeight()) };
2084 nodeInfo.SetRectInScreen(bounds);
2085 return;
2086 }
2087 if (!NearZero(commonProperty.scaleX, 0) && !NearZero(commonProperty.scaleY, 0)) {
2088 rect.SetRect(rect.GetX() * commonProperty.scaleX, rect.GetY() * commonProperty.scaleY,
2089 rect.Width() * commonProperty.scaleX, rect.Height() * commonProperty.scaleY);
2090 }
2091 auto left = static_cast<int32_t>(rect.Left() + commonProperty.windowLeft);
2092 auto top = static_cast<int32_t>(rect.Top() + commonProperty.windowTop);
2093 auto right = static_cast<int32_t>(rect.Right() + commonProperty.windowLeft);
2094 auto bottom = static_cast<int32_t>(rect.Bottom() + commonProperty.windowTop);
2095 Accessibility::Rect bounds { left, top, right, bottom };
2096 nodeInfo.SetRectInScreen(bounds);
2097 }
2098 }
2099 }
2100
UpdateAccessibilityVisible(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo)2101 void JsAccessibilityManager::UpdateAccessibilityVisible(
2102 const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo)
2103 {
2104 if (AceApplicationInfo::GetInstance().IsAccessibilityScreenReadEnabled()) {
2105 UpdateAccessibilityVisibleToRoot(node);
2106 nodeInfo.SetAccessibilityVisible(node->GetAccessibilityVisible());
2107 return;
2108 }
2109
2110 auto parentNode = node->GetParentFrameNode();
2111 UpdateElementInfoTreeId(nodeInfo);
2112
2113 if (!parentNode) {
2114 if (node->GetTag() != V2::PAGE_ETS_TAG) {
2115 node->SetAccessibilityVisible(node->IsActive() && node->IsVisible());
2116 }
2117 } else {
2118 if (node->GetTag() == V2::PAGE_ETS_TAG) {
2119 nodeInfo.SetAccessibilityVisible(node->IsActive() && node->IsVisible() && node->GetAccessibilityVisible() &&
2120 parentNode->GetAccessibilityVisible());
2121 return;
2122 }
2123 auto nodeAccessibilityVisible = node->IsActive() && node->IsVisible() && parentNode->GetAccessibilityVisible();
2124 node->SetAccessibilityVisible(nodeAccessibilityVisible);
2125 if (!nodeAccessibilityVisible) {
2126 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
2127 "Element %{public}" PRId64 " is invisible. node isActive %{public}d, node isVisible %{public}d"
2128 "parent accessibilityVisible:%{public}d.parent id %{public}" PRId64,
2129 nodeInfo.GetAccessibilityId(), node->IsActive(), node->IsVisible(),
2130 parentNode->GetAccessibilityVisible(), parentNode->GetAccessibilityId());
2131 }
2132 }
2133 nodeInfo.SetAccessibilityVisible(node->GetAccessibilityVisible());
2134 }
2135
UpdateAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::PipelineContext> & ngPipeline)2136 void JsAccessibilityManager::UpdateAccessibilityElementInfo(
2137 const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty,
2138 AccessibilityElementInfo& nodeInfo, const RefPtr<NG::PipelineContext>& ngPipeline)
2139 {
2140 CHECK_NULL_VOID(node);
2141 nodeInfo.SetParent(GetParentId(node));
2142 UpdateChildrenOfAccessibilityElementInfo(node, commonProperty, nodeInfo);
2143 nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
2144 nodeInfo.SetComponentType(node->GetTag());
2145 nodeInfo.SetUniqueId(node->GetId());
2146
2147 nodeInfo.SetEnabled(node->GetFocusHub() ? node->GetFocusHub()->IsEnabled() : true);
2148 nodeInfo.SetFocused(node->GetFocusHub() ? node->GetFocusHub()->IsCurrentFocus() : false);
2149 nodeInfo.SetAccessibilityFocus(node->GetRenderContext()->GetAccessibilityFocus().value_or(false));
2150 nodeInfo.SetClip(node->GetRenderContext()->GetClipEdge().value_or(false));
2151 nodeInfo.SetInspectorKey(node->GetInspectorId().value_or(""));
2152 nodeInfo.SetVisible(node->IsVisible());
2153 nodeInfo.SetIsActive(node->IsActive());
2154 SetRectInScreen(node, nodeInfo, commonProperty);
2155 nodeInfo.SetWindowId(commonProperty.windowId);
2156 nodeInfo.SetInnerWindowId(commonProperty.innerWindowId);
2157 // is abnormal that pageId equals to 0, use last pageId to fix pageId
2158 if (node->GetPageId()) {
2159 nodeInfo.SetPageId(node->GetPageId());
2160 } else {
2161 nodeInfo.SetPageId(GetLastPageId(ngPipeline));
2162 }
2163 nodeInfo.SetPagePath(
2164 GetPagePathInPageNodes(nodeInfo.GetPageId(), commonProperty.pageNodes, commonProperty.pagePaths));
2165 nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
2166
2167 if (nodeInfo.IsEnabled()) {
2168 nodeInfo.SetFocusable(node->GetFocusHub() ? node->GetFocusHub()->IsFocusable() : false);
2169 nodeInfo.SetPopupSupported(IsPopupSupported(ngPipeline, node->GetId()));
2170 }
2171 nodeInfo.SetComponentResourceId(node->GetInspectorId().value_or(""));
2172 UpdateAccessibilityElementInfo(node, nodeInfo);
2173 UpdateAccessibilityVisible(node, nodeInfo);
2174 }
2175 #ifdef WEB_SUPPORTED
2176
WebSetScreenRect(const std::shared_ptr<NG::TransitionalNodeInfo> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo)2177 void JsAccessibilityManager::WebSetScreenRect(const std::shared_ptr<NG::TransitionalNodeInfo>& node,
2178 const CommonProperty& commonProperty, AccessibilityElementInfo& nodeInfo)
2179 {
2180 auto rotateTransformData = commonProperty.rotateTransform;
2181 auto currentDegree = rotateTransformData.rotateDegree;
2182 if (!NearZero(currentDegree, 0)) {
2183 AccessibilityRect rotateRect(node->GetRectX(), node->GetRectY(),
2184 node->GetRectWidth(), node->GetRectHeight());
2185 rotateRect.Rotate(rotateTransformData.innerCenterX, rotateTransformData.innerCenterY, currentDegree);
2186 rotateRect.ApplyTransformation(rotateTransformData, commonProperty.scaleX, commonProperty.scaleY);
2187 Accessibility::Rect bounds { static_cast<int32_t>(std::floor(rotateRect.GetX())),
2188 static_cast<int32_t>(std::floor(rotateRect.GetY())),
2189 static_cast<int32_t>(std::floor(rotateRect.GetX() + rotateRect.GetWidth())),
2190 static_cast<int32_t>(std::floor(rotateRect.GetY() + rotateRect.GetHeight())) };
2191 nodeInfo.SetRectInScreen(bounds);
2192 } else {
2193 NG::RectT<int32_t> rectInt {
2194 node->GetRectX(),
2195 node->GetRectY(),
2196 node->GetRectWidth(),
2197 node->GetRectHeight()
2198 };
2199 if (!NearZero(commonProperty.scaleX) || !NearZero(commonProperty.scaleY)) {
2200 rectInt.SetRect(static_cast<int32_t>(std::floor(rectInt.GetX() * commonProperty.scaleX)),
2201 static_cast<int32_t>(std::floor(rectInt.GetY() * commonProperty.scaleY)),
2202 static_cast<int32_t>(std::floor(rectInt.Width() * commonProperty.scaleX)),
2203 static_cast<int32_t>(std::floor(rectInt.Height() * commonProperty.scaleY)));
2204 }
2205 auto left = static_cast<int32_t>(rectInt.Left() + commonProperty.windowLeft);
2206 auto top = static_cast<int32_t>(rectInt.Top() + commonProperty.windowTop);
2207 auto right = static_cast<int32_t>(rectInt.Right() + commonProperty.windowLeft);
2208 auto bottom = static_cast<int32_t>(rectInt.Bottom() + commonProperty.windowTop);
2209 Accessibility::Rect bounds { left, top, right, bottom };
2210 nodeInfo.SetRectInScreen(bounds);
2211 }
2212 }
2213
UpdateWebAccessibilityElementInfo(const std::shared_ptr<NG::TransitionalNodeInfo> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::WebPattern> & webPattern)2214 void JsAccessibilityManager::UpdateWebAccessibilityElementInfo(
2215 const std::shared_ptr<NG::TransitionalNodeInfo>& node, const CommonProperty& commonProperty,
2216 AccessibilityElementInfo& nodeInfo, const RefPtr<NG::WebPattern>& webPattern)
2217 {
2218 if (node->GetParentId() == -1) {
2219 nodeInfo.SetParent(INVALID_PARENT_ID);
2220 } else {
2221 nodeInfo.SetParent(node->GetParentId());
2222 }
2223 for (const auto& child : node->GetChildIds()) {
2224 nodeInfo.AddChild(child);
2225 }
2226
2227 nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
2228 nodeInfo.SetComponentType(node->GetComponentType());
2229 if (IsTagInEmbedComponent(nodeInfo.GetComponentType())) {
2230 nodeInfo.SetEnabled(true);
2231 } else {
2232 nodeInfo.SetEnabled(node->GetIsEnabled());
2233 }
2234 nodeInfo.SetFocused(node->GetIsFocused());
2235 nodeInfo.SetAccessibilityFocus(node->GetIsAccessibilityFocus());
2236 nodeInfo.SetVisible(node->GetIsVisible());
2237
2238 if (node->GetIsVisible()) {
2239 CHECK_NULL_VOID(webPattern);
2240 auto webNode = webPattern->GetHost();
2241 CHECK_NULL_VOID(webNode);
2242 WebSetScreenRect(node, commonProperty, nodeInfo);
2243 }
2244
2245 nodeInfo.SetWindowId(commonProperty.windowId);
2246 nodeInfo.SetPageId(node->GetPageId());
2247 nodeInfo.SetPagePath(
2248 GetPagePathInPageNodes(nodeInfo.GetPageId(), commonProperty.pageNodes, commonProperty.pagePaths));
2249 nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
2250
2251 if (nodeInfo.IsEnabled()) {
2252 nodeInfo.SetFocusable(node->GetIsFocusable());
2253 nodeInfo.SetPopupSupported(node->GetIsPopupSupported());
2254 }
2255 CHECK_NULL_VOID(webPattern);
2256 UpdateWebAccessibilityElementInfo(node, nodeInfo, webPattern->GetTreeId());
2257 }
2258
2259 #endif
2260 namespace {
SearchExtensionElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,const RefPtr<NG::FrameNode> & node,int64_t offset)2261 std::list<AccessibilityElementInfo> SearchExtensionElementInfoByAccessibilityIdNG(
2262 int64_t elementId, int32_t mode, const RefPtr<NG::FrameNode>& node, int64_t offset)
2263 {
2264 std::list<AccessibilityElementInfo> extensionElementInfo;
2265 if (NG::UI_EXTENSION_OFFSET_MIN < (offset + 1)) {
2266 node->SearchExtensionElementInfoByAccessibilityIdNG(elementId, mode,
2267 offset / NG::UI_EXTENSION_ID_FACTOR, extensionElementInfo);
2268 }
2269 return extensionElementInfo;
2270 }
2271
UpdateUiExtensionParentIdForFocus(const RefPtr<NG::FrameNode> & rootNode,const int64_t uiExtensionOffset,Accessibility::AccessibilityElementInfo & info)2272 void UpdateUiExtensionParentIdForFocus(const RefPtr<NG::FrameNode>& rootNode, const int64_t uiExtensionOffset,
2273 Accessibility::AccessibilityElementInfo& info)
2274 {
2275 if ((uiExtensionOffset != NG::UI_EXTENSION_OFFSET_MAX) && (info.GetComponentType() != V2::ROOT_ETS_TAG) &&
2276 (info.GetParentNodeId() == rootNode->GetAccessibilityId())) {
2277 info.SetParent(NG::UI_EXTENSION_ROOT_ID);
2278 }
2279 }
2280
GetChildrenFromFrameNode(const RefPtr<NG::FrameNode> & node,std::list<RefPtr<NG::FrameNode>> & children,const CommonProperty & commonProperty)2281 void GetChildrenFromFrameNode(
2282 const RefPtr<NG::FrameNode>& node,
2283 std::list<RefPtr<NG::FrameNode>>& children,
2284 const CommonProperty& commonProperty)
2285 {
2286 std::list<RefPtr<NG::FrameNode>> frameNodeChildren;
2287 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
2288 auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
2289 if (uiVirtualNode != nullptr) {
2290 auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
2291 if (virtualNode != nullptr) {
2292 GetFrameNodeChildren(virtualNode, frameNodeChildren, commonProperty);
2293 }
2294 } else {
2295 for (const auto& item : node->GetChildren(true)) {
2296 GetFrameNodeChildren(item, frameNodeChildren, commonProperty);
2297 }
2298
2299 auto overlayNode = node->GetOverlayNode();
2300 if (overlayNode != nullptr) {
2301 GetFrameNodeChildren(overlayNode, frameNodeChildren, commonProperty);
2302 }
2303 }
2304 while (!frameNodeChildren.empty()) {
2305 children.emplace_back(frameNodeChildren.front());
2306 frameNodeChildren.pop_front();
2307 }
2308 }
2309
GetLastChildFrameNode(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty)2310 RefPtr<NG::FrameNode> GetLastChildFrameNode(const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty)
2311 {
2312 std::list<RefPtr<NG::FrameNode>> children { node };
2313 RefPtr<NG::FrameNode> checkNode;
2314
2315 while (!children.empty()) {
2316 checkNode = children.back();
2317 children.clear();
2318 GetChildrenFromFrameNode(checkNode, children, commonProperty);
2319 }
2320 return checkNode;
2321 }
2322 }
2323
UpdateVirtualNodeInfo(std::list<AccessibilityElementInfo> & infos,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::UINode> & uiVirtualNode,const CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline)2324 void JsAccessibilityManager::UpdateVirtualNodeInfo(std::list<AccessibilityElementInfo>& infos,
2325 AccessibilityElementInfo& nodeInfo, const RefPtr<NG::UINode>& uiVirtualNode, const CommonProperty& commonProperty,
2326 const RefPtr<NG::PipelineContext>& ngPipeline)
2327 {
2328 auto frameParentNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
2329 CHECK_NULL_VOID(frameParentNode);
2330 std::list<RefPtr<NG::FrameNode>> children;
2331
2332 GetChildrenFromFrameNode(frameParentNode, children, commonProperty);
2333 for (const auto& frameNodeChild : children) {
2334 AccessibilityElementInfo virtualInfo;
2335 UpdateVirtualNodeChildAccessibilityElementInfo(frameNodeChild, commonProperty,
2336 nodeInfo, virtualInfo, ngPipeline);
2337 virtualInfo.SetParent(uiVirtualNode->GetAccessibilityId());
2338 nodeInfo.AddChild(frameNodeChild->GetAccessibilityId());
2339 UpdateVirtualNodeInfo(infos, virtualInfo, frameNodeChild, commonProperty, ngPipeline);
2340 infos.push_back(virtualInfo);
2341 }
2342 }
2343
2344 namespace {
SearchExtensionElementInfoNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,Accessibility::AccessibilityElementInfo & parentInfo)2345 void SearchExtensionElementInfoNG(const SearchParameter& searchParam,
2346 const RefPtr<NG::FrameNode>& node, std::list<Accessibility::AccessibilityElementInfo>& infos,
2347 Accessibility::AccessibilityElementInfo& parentInfo)
2348 {
2349 auto extensionElementInfos = SearchExtensionElementInfoByAccessibilityIdNG(
2350 searchParam.nodeId, searchParam.mode, node, searchParam.uiExtensionOffset);
2351 if (!extensionElementInfos.empty()) {
2352 auto rootParentId = extensionElementInfos.front().GetParentNodeId();
2353 ConvertExtensionAccessibilityNodeId(extensionElementInfos, node, searchParam.uiExtensionOffset, parentInfo);
2354 if (rootParentId == NG::UI_EXTENSION_ROOT_ID) {
2355 extensionElementInfos.front().SetParent(node->GetAccessibilityId());
2356 }
2357 if (parentInfo.GetComponentType() == V2::ISOLATED_COMPONENT_ETS_TAG) {
2358 auto windowId = parentInfo.GetWindowId();
2359 for (auto& info : extensionElementInfos) {
2360 info.SetWindowId(windowId);
2361 }
2362 }
2363 for (auto& info : extensionElementInfos) {
2364 infos.push_back(info);
2365 }
2366 }
2367 }
2368 }
2369
UpdateChildrenNodeInCache(std::list<AccessibilityElementInfo> & infos,const CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline,const SearchParameter & searchParam,std::list<RefPtr<NG::FrameNode>> & children)2370 void JsAccessibilityManager::UpdateChildrenNodeInCache(std::list<AccessibilityElementInfo>& infos,
2371 const CommonProperty& commonProperty, const RefPtr<NG::PipelineContext>& ngPipeline,
2372 const SearchParameter& searchParam, std::list<RefPtr<NG::FrameNode>>& children)
2373 {
2374 while (!children.empty()) {
2375 RefPtr<NG::FrameNode> frameNodeParent = children.front();
2376 children.pop_front();
2377 AccessibilityElementInfo nodeInfo;
2378 auto accessibilityProperty = frameNodeParent->GetAccessibilityProperty<NG::AccessibilityProperty>();
2379 auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
2380 if (CheckAndSetAccessibilityVisible(frameNodeParent, commonProperty.isReduceMode)) {
2381 UpdateAccessibilityElementInfo(frameNodeParent, commonProperty, nodeInfo, ngPipeline);
2382 }
2383 if (uiVirtualNode != nullptr) {
2384 auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
2385 if (virtualNode == nullptr) {
2386 continue;
2387 }
2388 AccessibilityElementInfo virtualInfo;
2389 UpdateVirtualNodeAccessibilityElementInfo(
2390 frameNodeParent, virtualNode, commonProperty, virtualInfo, ngPipeline);
2391 virtualInfo.SetParent(frameNodeParent->GetAccessibilityId());
2392 auto childIds = nodeInfo.GetChildIds();
2393 for (auto& child : childIds) {
2394 nodeInfo.RemoveChild(child);
2395 }
2396 nodeInfo.AddChild(virtualNode->GetAccessibilityId());
2397 auto uiParentNode = AceType::DynamicCast<NG::UINode>(frameNodeParent);
2398 if (!uiVirtualNode->GetChildren(true).empty()) {
2399 UpdateVirtualNodeInfo(infos, virtualInfo, uiVirtualNode, commonProperty, ngPipeline);
2400 }
2401 infos.push_back(virtualInfo);
2402 infos.push_back(nodeInfo);
2403 continue;
2404 }
2405 if (!IsExtensionComponent(frameNodeParent) || IsUIExtensionShowPlaceholder(frameNodeParent)) {
2406 infos.push_back(nodeInfo);
2407 GetChildrenFromFrameNode(frameNodeParent, children, commonProperty);
2408 continue;
2409 }
2410 if (!((frameNodeParent->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
2411 (((frameNodeParent->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX) &&
2412 (NG::UI_EXTENSION_OFFSET_MAX == searchParam.uiExtensionOffset)) ||
2413 (frameNodeParent->GetUiExtensionId() <= NG::UI_EXTENSION_ID_OTHER_MAX)))) {
2414 continue;
2415 }
2416 auto transferParam = searchParam;
2417 transferParam.nodeId = NG::UI_EXTENSION_ROOT_ID;
2418 SearchExtensionElementInfoNG(transferParam, frameNodeParent, infos, nodeInfo);
2419 infos.push_back(nodeInfo);
2420 }
2421 }
2422
UpdateCacheInfoNG(std::list<AccessibilityElementInfo> & infos,const RefPtr<NG::FrameNode> & node,CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline,const SearchParameter & searchParam)2423 void JsAccessibilityManager::UpdateCacheInfoNG(std::list<AccessibilityElementInfo>& infos,
2424 const RefPtr<NG::FrameNode>& node, CommonProperty& commonProperty,
2425 const RefPtr<NG::PipelineContext>& ngPipeline, const SearchParameter& searchParam)
2426 {
2427 uint32_t umode = searchParam.mode;
2428 std::list<RefPtr<NG::FrameNode>> children;
2429 // get all children
2430 if ((umode & (static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN) |
2431 static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN_REDUCED))) == 0) {
2432 return;
2433 }
2434 commonProperty.isReduceMode = umode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN_REDUCED);
2435 GetChildrenFromFrameNode(node, children, commonProperty);
2436 UpdateChildrenNodeInCache(infos, commonProperty, ngPipeline, searchParam, children);
2437 }
2438
UpdateEventWhiteList(const std::vector<uint32_t> & eventList)2439 void JsAccessibilityManager::UpdateEventWhiteList(const std::vector<uint32_t>& eventList)
2440 {
2441 eventWhiteList_ = eventList;
2442 }
2443
2444 namespace {
CanAccessibilityFocusedNG(const RefPtr<NG::FrameNode> & node)2445 bool CanAccessibilityFocusedNG(const RefPtr<NG::FrameNode>& node)
2446 {
2447 CHECK_NULL_RETURN(node, false);
2448 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
2449 CHECK_NULL_RETURN(accessibilityProperty, false);
2450 auto level = accessibilityProperty->GetAccessibilityLevel();
2451 return !node->IsRootNode() &&
2452 node->GetLayoutProperty()->GetVisibilityValue(VisibleType::VISIBLE) == VisibleType::VISIBLE &&
2453 level != NG::AccessibilityProperty::Level::NO_STR &&
2454 level != NG::AccessibilityProperty::Level::NO_HIDE_DESCENDANTS;
2455 }
2456 // focus move search
AddFocusableNode(std::list<RefPtr<NG::FrameNode>> & nodeList,const RefPtr<NG::FrameNode> & node)2457 void AddFocusableNode(std::list<RefPtr<NG::FrameNode>>& nodeList, const RefPtr<NG::FrameNode>& node)
2458 {
2459 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
2460 CHECK_NULL_VOID(accessibilityProperty);
2461 auto level = accessibilityProperty->GetAccessibilityLevel();
2462 if (CanAccessibilityFocusedNG(node)) {
2463 nodeList.emplace_back(node);
2464 }
2465
2466 if (!accessibilityProperty->IsAccessibilityGroup() &&
2467 level != NG::AccessibilityProperty::Level::NO_HIDE_DESCENDANTS) {
2468 std::list<RefPtr<NG::FrameNode>> children;
2469 CommonProperty commonProperty;
2470 commonProperty.pageNodes.clear(); // empty means search all page
2471 commonProperty.pagePaths.clear();
2472 for (const auto& child : node->GetChildren(true)) {
2473 GetFrameNodeChildren(child, children, commonProperty);
2474 }
2475
2476 for (const auto& child : children) {
2477 AddFocusableNode(nodeList, child);
2478 }
2479 }
2480 }
2481
2482 // execute action
RequestFocus(RefPtr<NG::FrameNode> & frameNode)2483 bool RequestFocus(RefPtr<NG::FrameNode>& frameNode)
2484 {
2485 auto focusHub = frameNode->GetFocusHub();
2486 CHECK_NULL_RETURN(focusHub, false);
2487 return focusHub->RequestFocusImmediately();
2488 }
2489
LostFocus(const RefPtr<NG::FrameNode> & frameNode)2490 bool LostFocus(const RefPtr<NG::FrameNode>& frameNode)
2491 {
2492 CHECK_NULL_RETURN(frameNode, false);
2493 auto focusHub = frameNode->GetFocusHub();
2494 CHECK_NULL_RETURN(focusHub, false);
2495 focusHub->LostFocus();
2496 return true;
2497 }
2498
HandleWillClickAccept(const RefPtr<NG::FrameNode> & frameNode)2499 void HandleWillClickAccept(const RefPtr<NG::FrameNode>& frameNode)
2500 {
2501 CHECK_NULL_VOID(frameNode);
2502 auto eventHub = frameNode->GetOrCreateEventHub<NG::EventHub>();
2503 CHECK_NULL_VOID(eventHub);
2504 auto gestureEventHub = eventHub->GetGestureEventHub();
2505 CHECK_NULL_VOID(gestureEventHub);
2506 auto gestureEventInfo = gestureEventHub->GetGestureEventInfo();
2507 auto clickInfo = gestureEventHub->GetClickInfo();
2508 NG::UIObserverHandler::GetInstance().NotifyWillClick(gestureEventInfo, clickInfo, frameNode);
2509 }
2510
HandleDidClickAccept(const RefPtr<NG::FrameNode> & frameNode)2511 void HandleDidClickAccept(const RefPtr<NG::FrameNode>& frameNode)
2512 {
2513 CHECK_NULL_VOID(frameNode);
2514 auto eventHub = frameNode->GetOrCreateEventHub<NG::EventHub>();
2515 CHECK_NULL_VOID(eventHub);
2516 auto gestureEventHub = eventHub->GetGestureEventHub();
2517 CHECK_NULL_VOID(gestureEventHub);
2518 auto gestureEventInfo = gestureEventHub->GetGestureEventInfo();
2519 auto clickInfo = gestureEventHub->GetClickInfo();
2520 NG::UIObserverHandler::GetInstance().NotifyDidClick(gestureEventInfo, clickInfo, frameNode);
2521 }
2522
ActClick(RefPtr<NG::FrameNode> & frameNode,const NG::SecCompEnhanceEvent & secEvent)2523 bool ActClick(RefPtr<NG::FrameNode>& frameNode, const NG::SecCompEnhanceEvent& secEvent)
2524 {
2525 if (NG::AccessibilityFunctionUtils::HandleClickBySecComponent(frameNode, secEvent)) {
2526 // notify child action happened to parent
2527 NG::AccessibilityFunctionUtils::HandleNotifyChildAction(frameNode, NotifyChildActionType::ACTION_CLICK);
2528 return true;
2529 }
2530
2531 auto interceptResult =
2532 NG::AccessibilityFunctionUtils::HandleAccessibilityActionIntercept(
2533 frameNode, AccessibilityInterfaceAction::ACCESSIBILITY_CLICK);
2534 if (interceptResult == AccessibilityActionInterceptResult::ACTION_INTERCEPT) {
2535 return true;
2536 }
2537 auto eventHub = frameNode->GetOrCreateEventHub<NG::EventHub>();
2538 CHECK_NULL_RETURN(eventHub, false);
2539 auto gesture = eventHub->GetGestureEventHub();
2540 CHECK_NULL_RETURN(gesture, false);
2541 HandleWillClickAccept(frameNode);
2542 bool result = gesture->ActClick();
2543 HandleDidClickAccept(frameNode);
2544 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
2545 CHECK_NULL_RETURN(accessibilityProperty, result);
2546 auto accessibilityAction = ACTIONS.find(ACCESSIBILITY_ACTION_CLICK);
2547 if (accessibilityAction != ACTIONS.end()) {
2548 AccessibilityActionParam param;
2549 param.accessibilityProperty = accessibilityProperty;
2550 result |= accessibilityAction->second(param);
2551 }
2552
2553 // notify child action happened to parent
2554 NG::AccessibilityFunctionUtils::HandleNotifyChildAction(frameNode, NotifyChildActionType::ACTION_CLICK);
2555 return result;
2556 }
2557
ActLongClick(RefPtr<NG::FrameNode> & frameNode)2558 bool ActLongClick(RefPtr<NG::FrameNode>& frameNode)
2559 {
2560 auto gesture = frameNode->GetOrCreateEventHub<NG::EventHub>()->GetGestureEventHub();
2561 CHECK_NULL_RETURN(gesture, false);
2562 return gesture->ActLongClick();
2563 }
2564
CreateOrUpdateAccessibilityFocusPaint(const RefPtr<NG::FrameNode> & focusFrameNode)2565 void CreateOrUpdateAccessibilityFocusPaint(const RefPtr<NG::FrameNode>& focusFrameNode)
2566 {
2567 CHECK_NULL_VOID(focusFrameNode);
2568 ACE_SCOPED_TRACE("CreateOrUpdateAccessibilityFocusPaint: targetNode[%s].", focusFrameNode->GetTag().c_str());
2569 auto paintNode = NG::FrameNode::CreateFrameNode(V2::ACCESSIBILITY_FOCUS_PAINT_NODE_TAG,
2570 ElementRegister::GetInstance()->MakeUniqueId(),
2571 AceType::MakeRefPtr<NG::AccessibilityFocusPaintNodePattern>(focusFrameNode));
2572 CHECK_NULL_VOID(paintNode);
2573 auto pattern = paintNode->GetPattern<NG::AccessibilityFocusPaintNodePattern>();
2574 CHECK_NULL_VOID(pattern);
2575 pattern->UpdateFocusNode(focusFrameNode);
2576 auto renderContext = paintNode->GetRenderContext();
2577 CHECK_NULL_VOID(renderContext);
2578 renderContext->OnZIndexUpdate(INT32_MAX);
2579 renderContext->ResetAccessibilityFocusRect();
2580 renderContext->UpdateAccessibilityFocus(true);
2581
2582 auto pipeline = focusFrameNode->GetContextRefPtr();
2583 CHECK_NULL_VOID(pipeline);
2584 auto overlayManager = pipeline->GetOverlayManager();
2585 CHECK_NULL_VOID(overlayManager);
2586
2587 auto rootNode = AceType::DynamicCast<NG::FrameNode>(overlayManager->FindWindowScene(focusFrameNode));
2588 CHECK_NULL_VOID(rootNode);
2589 pattern->UpdateRootNode(rootNode);
2590 rootNode->SetFocusPaintNode(paintNode);
2591 rootNode->MarkNeedSyncRenderTree();
2592 rootNode->RebuildRenderContextTree();
2593 }
2594
RemoveAccessibilityFocusPaint(const RefPtr<NG::FrameNode> & focusFrameNode)2595 void RemoveAccessibilityFocusPaint(const RefPtr<NG::FrameNode>& focusFrameNode)
2596 {
2597 CHECK_NULL_VOID(focusFrameNode);
2598 ACE_SCOPED_TRACE("Node[%s] RemoveAccessibilityFocusPaint", focusFrameNode->GetTag().c_str());
2599 auto paintNode = focusFrameNode->GetPaintNode();
2600 CHECK_NULL_VOID(paintNode);
2601 focusFrameNode->SetPaintNode(nullptr);
2602 auto renderContext = paintNode->GetRenderContext();
2603 CHECK_NULL_VOID(renderContext);
2604 renderContext->UpdateAccessibilityFocus(false);
2605 auto pattern = paintNode->GetPattern<NG::AccessibilityFocusPaintNodePattern>();
2606 CHECK_NULL_VOID(pattern);
2607 auto rootNode = AceType::DynamicCast<NG::FrameNode>(pattern->GetRootNode().Upgrade());
2608 CHECK_NULL_VOID(rootNode);
2609 rootNode->SetFocusPaintNode(nullptr);
2610 rootNode->MarkNeedSyncRenderTree();
2611 rootNode->RebuildRenderContextTree();
2612 }
2613
PaintAccessibilityFocusNode(const RefPtr<NG::FrameNode> & focusNode,bool focus)2614 void PaintAccessibilityFocusNode(const RefPtr<NG::FrameNode>& focusNode, bool focus)
2615 {
2616 CHECK_NULL_VOID(focusNode);
2617 if (focusNode->IsDrawFocusOnTop()) {
2618 if (focus) {
2619 CreateOrUpdateAccessibilityFocusPaint(focusNode);
2620 UpdatePaintNodeRender(focusNode);
2621 } else {
2622 RemoveAccessibilityFocusPaint(focusNode);
2623 }
2624 } else {
2625 auto context = focusNode->GetRenderContext();
2626 CHECK_NULL_VOID(context);
2627 context->UpdateAccessibilityFocus(focus);
2628 }
2629 }
2630
ClearAccessibilityFocus(const RefPtr<NG::FrameNode> & root,int64_t focusNodeId)2631 void ClearAccessibilityFocus(const RefPtr<NG::FrameNode>& root, int64_t focusNodeId)
2632 {
2633 auto oldFocusNode = GetFramenodeByAccessibilityId(root, focusNodeId);
2634 CHECK_NULL_VOID(oldFocusNode);
2635 if (oldFocusNode->IsDrawFocusOnTop()) {
2636 PaintAccessibilityFocusNode(oldFocusNode, false);
2637 } else {
2638 oldFocusNode->GetRenderContext()->UpdateAccessibilityFocus(false);
2639 }
2640 }
2641
GetFrameNodeRectInt(const RefPtr<NG::FrameNode> & frameNode)2642 NG::RectT<int32_t> GetFrameNodeRectInt(const RefPtr<NG::FrameNode>& frameNode)
2643 {
2644 auto rect = frameNode->GetTransformRectRelativeToWindow();
2645 NG::RectT<int32_t> rectInt {
2646 static_cast<int32_t>(std::floor(rect.Left())),
2647 static_cast<int32_t>(std::floor(rect.Top())),
2648 static_cast<int32_t>(std::floor(rect.Width())),
2649 static_cast<int32_t>(std::floor(rect.Height()))
2650 };
2651 return rectInt;
2652 }
2653
UpdateAccessibilityFocusRect(const RefPtr<NG::FrameNode> & frameNode,RefPtr<NG::RenderContext> & renderContext,bool isAccessibilityVirtualNode)2654 void UpdateAccessibilityFocusRect(const RefPtr<NG::FrameNode>& frameNode,
2655 RefPtr<NG::RenderContext>& renderContext,
2656 bool isAccessibilityVirtualNode)
2657 {
2658 CHECK_NULL_VOID(frameNode);
2659 CHECK_NULL_VOID(renderContext);
2660 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
2661 CHECK_NULL_VOID(accessibilityProperty);
2662 if (accessibilityProperty->IsMatchAccessibilityResponseRegion(isAccessibilityVirtualNode)) {
2663 auto rectInt = accessibilityProperty->GetAccessibilityResponseRegionRect(isAccessibilityVirtualNode);
2664 renderContext->UpdateAccessibilityFocusRect(rectInt);
2665 if (isAccessibilityVirtualNode) {
2666 renderContext->UpdateAccessibilityFocus(true, frameNode->GetAccessibilityId());
2667 } else {
2668 PaintAccessibilityFocusNode(frameNode, true);
2669 }
2670 } else {
2671 if (isAccessibilityVirtualNode) {
2672 renderContext->UpdateAccessibilityFocusRect(GetFrameNodeRectInt(frameNode));
2673 renderContext->UpdateAccessibilityFocus(true, frameNode->GetAccessibilityId());
2674 } else {
2675 renderContext->ResetAccessibilityFocusRect();
2676 PaintAccessibilityFocusNode(frameNode, true);
2677 }
2678 }
2679 }
2680
ClearVirtualNodeAccessibilityFocus(const RefPtr<NG::FrameNode> & root,int64_t currentFocusVirtualNodeParentId)2681 void ClearVirtualNodeAccessibilityFocus(const RefPtr<NG::FrameNode>& root, int64_t currentFocusVirtualNodeParentId)
2682 {
2683 CHECK_EQUAL_VOID(currentFocusVirtualNodeParentId, -1);
2684 auto currentFocusVirtualNodeParentNode = GetFramenodeByAccessibilityId(root, currentFocusVirtualNodeParentId);
2685 CHECK_NULL_VOID(currentFocusVirtualNodeParentNode);
2686 auto renderContext = currentFocusVirtualNodeParentNode->GetRenderContext();
2687 CHECK_NULL_VOID(renderContext);
2688 renderContext->UpdateAccessibilityFocus(false);
2689 }
2690
SetParentAccessibilityId(const RefPtr<NG::FrameNode> & frameNode,AccessibilityFocusInfo & focusInfo)2691 void SetParentAccessibilityId(const RefPtr<NG::FrameNode>& frameNode, AccessibilityFocusInfo& focusInfo)
2692 {
2693 auto parentUinode = frameNode->GetVirtualNodeParent().Upgrade();
2694 CHECK_NULL_VOID(parentUinode);
2695 auto parentFrame = AceType::DynamicCast<NG::FrameNode>(parentUinode);
2696 CHECK_NULL_VOID(parentFrame);
2697 focusInfo.currentFocusVirtualNodeParentId = parentFrame->GetAccessibilityId();
2698 }
2699
ActAccessibilityFocus(int64_t elementId,const RefPtr<NG::FrameNode> & frameNode,RefPtr<NG::PipelineContext> & context,AccessibilityFocusInfo & focusInfo,bool isNeedClear)2700 bool ActAccessibilityFocus(int64_t elementId, const RefPtr<NG::FrameNode>& frameNode,
2701 RefPtr<NG::PipelineContext>& context, AccessibilityFocusInfo& focusInfo, bool isNeedClear)
2702 {
2703 CHECK_NULL_RETURN(frameNode, false);
2704 bool isAccessibilityVirtualNode = frameNode->IsAccessibilityVirtualNode();
2705 RefPtr<NG::RenderContext> renderContext = nullptr;
2706 if (isAccessibilityVirtualNode) {
2707 auto parentUinode = frameNode->GetVirtualNodeParent().Upgrade();
2708 CHECK_NULL_RETURN(parentUinode, false);
2709 auto parentFrame = AceType::DynamicCast<NG::FrameNode>(parentUinode);
2710 CHECK_NULL_RETURN(parentFrame, false);
2711 renderContext = parentFrame->GetRenderContext();
2712 } else {
2713 renderContext = frameNode->GetRenderContext();
2714 }
2715 CHECK_NULL_RETURN(renderContext, false);
2716 if (isNeedClear) {
2717 if (elementId != focusInfo.currentFocusNodeId) {
2718 return false;
2719 }
2720 if (isAccessibilityVirtualNode) {
2721 renderContext->UpdateAccessibilityFocus(false);
2722 focusInfo.currentFocusVirtualNodeParentId = -1;
2723 } else {
2724 PaintAccessibilityFocusNode(frameNode, false);
2725 }
2726 focusInfo.currentFocusNodeId = -1;
2727 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
2728 CHECK_NULL_RETURN(accessibilityProperty, true);
2729 accessibilityProperty->OnAccessibilityFocusCallback(false);
2730 accessibilityProperty->SetAccessibilityFocusState(false);
2731 return true;
2732 }
2733 CHECK_EQUAL_RETURN(elementId, focusInfo.currentFocusNodeId, false);
2734 ClearAccessibilityFocus(context->GetRootElement(), focusInfo.currentFocusNodeId);
2735 if (focusInfo.currentFocusNodeId != focusInfo.currentFocusVirtualNodeParentId) {
2736 ClearVirtualNodeAccessibilityFocus(context->GetRootElement(), focusInfo.currentFocusVirtualNodeParentId);
2737 }
2738 UpdateAccessibilityFocusRect(frameNode, renderContext, isAccessibilityVirtualNode);
2739 focusInfo.currentFocusNodeId = frameNode->GetAccessibilityId();
2740 if (isAccessibilityVirtualNode) {
2741 SetParentAccessibilityId(frameNode, focusInfo);
2742 }
2743 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
2744 CHECK_NULL_RETURN(accessibilityProperty, false);
2745 accessibilityProperty->OnAccessibilityFocusCallback(true);
2746 accessibilityProperty->SetAccessibilityFocusState(true);
2747 ProcessFocusScroll(frameNode, context);
2748 return true;
2749 }
2750
GetSupportAction(const std::unordered_set<AceAction> & supportAceActions)2751 inline std::string GetSupportAction(const std::unordered_set<AceAction>& supportAceActions)
2752 {
2753 std::string actionForDump;
2754 for (const auto& action : supportAceActions) {
2755 if (!actionForDump.empty()) {
2756 actionForDump.append(",");
2757 }
2758 actionForDump.append(std::to_string(static_cast<int32_t>(action)));
2759 }
2760 return actionForDump;
2761 }
2762
ConvertActionTypeToString(ActionType action)2763 static std::string ConvertActionTypeToString(ActionType action)
2764 {
2765 static const ActionStrTable actionStrTable[] = {
2766 { ActionType::ACCESSIBILITY_ACTION_FOCUS, "ACCESSIBILITY_ACTION_FOCUS" },
2767 { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ACCESSIBILITY_ACTION_CLEAR_FOCUS" },
2768 { ActionType::ACCESSIBILITY_ACTION_SELECT, "ACCESSIBILITY_ACTION_SELECT" },
2769 { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, "ACCESSIBILITY_ACTION_CLEAR_SELECTION" },
2770 { ActionType::ACCESSIBILITY_ACTION_CLICK, "ACCESSIBILITY_ACTION_CLICK" },
2771 { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, "ACCESSIBILITY_ACTION_LONG_CLICK" },
2772 { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, "ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS" },
2773 { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS,
2774 "ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS" },
2775 { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, "ACCESSIBILITY_ACTION_SCROLL_FORWARD" },
2776 { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, "ACCESSIBILITY_ACTION_SCROLL_BACKWARD" },
2777 { ActionType::ACCESSIBILITY_ACTION_COPY, "ACCESSIBILITY_ACTION_COPY" },
2778 { ActionType::ACCESSIBILITY_ACTION_PASTE, "ACCESSIBILITY_ACTION_PASTE" },
2779 { ActionType::ACCESSIBILITY_ACTION_CUT, "ACCESSIBILITY_ACTION_CUT" },
2780 { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, "ACCESSIBILITY_ACTION_SET_SELECTION" },
2781 { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, "ACCESSIBILITY_ACTION_SET_TEXT" },
2782 { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, "ACCESSIBILITY_ACTION_NEXT_TEXT" },
2783 { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, "ACCESSIBILITY_ACTION_PREVIOUS_TEXT" },
2784 { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, "ACCESSIBILITY_ACTION_SET_CURSOR_POSITION" },
2785 { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, "ACCESSIBILITY_ACTION_SPAN_CLICK" },
2786 { ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM, "ACCESSIBILITY_ACTION_NEXT_HTML_ITEM" },
2787 { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM, "ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM" },
2788 };
2789 for (const auto& item : actionStrTable) {
2790 if (action == item.action) {
2791 return item.actionStr;
2792 }
2793 }
2794 return ACTION_DEFAULT_PARAM;
2795 }
2796
ConvertAccessibilityAction(ActionType accessibilityAction)2797 static AceAction ConvertAccessibilityAction(ActionType accessibilityAction)
2798 {
2799 static const ActionTable actionTable[] = {
2800 { AceAction::ACTION_CLICK, ActionType::ACCESSIBILITY_ACTION_CLICK },
2801 { AceAction::ACTION_LONG_CLICK, ActionType::ACCESSIBILITY_ACTION_LONG_CLICK },
2802 { AceAction::ACTION_SCROLL_FORWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD },
2803 { AceAction::ACTION_SCROLL_BACKWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD },
2804 { AceAction::ACTION_FOCUS, ActionType::ACCESSIBILITY_ACTION_FOCUS },
2805 { AceAction::ACTION_CLEAR_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS },
2806 { AceAction::ACTION_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS },
2807 { AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS },
2808 { AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT },
2809 { AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT },
2810 { AceAction::ACTION_SET_TEXT, ActionType::ACCESSIBILITY_ACTION_SET_TEXT },
2811 { AceAction::ACTION_COPY, ActionType::ACCESSIBILITY_ACTION_COPY },
2812 { AceAction::ACTION_PASTE, ActionType::ACCESSIBILITY_ACTION_PASTE },
2813 { AceAction::ACTION_CUT, ActionType::ACCESSIBILITY_ACTION_CUT },
2814 { AceAction::ACTION_SELECT, ActionType::ACCESSIBILITY_ACTION_SELECT },
2815 { AceAction::ACTION_CLEAR_SELECTION, ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION },
2816 { AceAction::ACTION_SET_SELECTION, ActionType::ACCESSIBILITY_ACTION_SET_SELECTION },
2817 { AceAction::ACTION_SET_CURSOR_POSITION, ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION },
2818 { AceAction::ACTION_EXEC_SUB_COMPONENT, ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK },
2819 { AceAction::ACTION_NEXT_HTML_ITEM, ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM },
2820 { AceAction::ACTION_PREVIOUS_HTML_ITEM, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM },
2821 };
2822 for (const auto& item : actionTable) {
2823 if (accessibilityAction == item.action) {
2824 return item.aceAction;
2825 }
2826 }
2827 return AceAction::ACTION_NONE;
2828 }
2829
DumpSupportActionNG(const AccessibilityElementInfo & nodeInfo)2830 static void DumpSupportActionNG(const AccessibilityElementInfo& nodeInfo)
2831 {
2832 DumpLog::GetInstance().AddDesc(
2833 "support action instructions: use command to make application components perform corresponding action");
2834 DumpLog::GetInstance().AddDesc(
2835 "use support action command: aa dump -i [AbilityRecord] -c -inspector [AccessibilityId] [AceAction]");
2836 std::string actionForDump;
2837 for (const auto& action : nodeInfo.GetActionList()) {
2838 if (!actionForDump.empty()) {
2839 actionForDump.append(",");
2840 }
2841 actionForDump.append(ConvertActionTypeToString(action.GetActionType()));
2842 actionForDump.append(": ");
2843 actionForDump.append(std::to_string(static_cast<int32_t>(ConvertAccessibilityAction(action.GetActionType()))));
2844 }
2845 DumpLog::GetInstance().AddDesc("support action: ", actionForDump);
2846 }
2847
DumpGridInfoNG(const AccessibilityElementInfo & nodeInfo)2848 static void DumpGridInfoNG(const AccessibilityElementInfo& nodeInfo)
2849 {
2850 DumpLog::GetInstance().AddDesc("grid info rows: ", nodeInfo.GetGrid().GetRowCount());
2851 DumpLog::GetInstance().AddDesc("grid info columns: ", nodeInfo.GetGrid().GetColumnCount());
2852 DumpLog::GetInstance().AddDesc("grid info select mode: ", nodeInfo.GetGrid().GetSelectionMode());
2853 DumpLog::GetInstance().AddDesc("grid item info, row: ", nodeInfo.GetGridItem().GetRowIndex());
2854 DumpLog::GetInstance().AddDesc("grid item info, column: ", nodeInfo.GetGridItem().GetColumnIndex());
2855 DumpLog::GetInstance().AddDesc("grid item info, rowSpan: ", nodeInfo.GetGridItem().GetRowSpan());
2856 DumpLog::GetInstance().AddDesc("grid item info, columnSpan: ", nodeInfo.GetGridItem().GetColumnSpan());
2857 DumpLog::GetInstance().AddDesc("grid item info, is heading: ", nodeInfo.GetGridItem().IsHeading());
2858 DumpLog::GetInstance().AddDesc("grid item info, selected: ", nodeInfo.GetGridItem().IsSelected());
2859 }
2860
DumpContentListNG(const AccessibilityElementInfo & nodeInfo)2861 inline void DumpContentListNG(const AccessibilityElementInfo& nodeInfo)
2862 {
2863 std::vector<std::string> contentList;
2864 nodeInfo.GetContentList(contentList);
2865 std::string contents;
2866 for (const auto& content : contentList) {
2867 if (!contents.empty()) {
2868 contents.append(",");
2869 }
2870 contents.append(content);
2871 }
2872 DumpLog::GetInstance().AddDesc("content list: ", contents);
2873 }
2874
DumpExtraElementInfoNG(const AccessibilityElementInfo & nodeInfo)2875 static void DumpExtraElementInfoNG(const AccessibilityElementInfo& nodeInfo)
2876 {
2877 ExtraElementInfo extraElementInfo = nodeInfo.GetExtraElement();
2878 if (!extraElementInfo.GetExtraElementInfoValueStr().empty()) {
2879 for (auto i = extraElementInfo.GetExtraElementInfoValueStr().begin();
2880 i != extraElementInfo.GetExtraElementInfoValueStr().end(); ++i) {
2881 DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second);
2882 }
2883 }
2884 if (!extraElementInfo.GetExtraElementInfoValueInt().empty()) {
2885 for (auto i = extraElementInfo.GetExtraElementInfoValueInt().begin();
2886 i != extraElementInfo.GetExtraElementInfoValueInt().end(); ++i) {
2887 DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second);
2888 }
2889 }
2890 }
2891
UpdateSpanList(std::vector<SpanInfo> & spansInfosList,std::string & spans)2892 static void UpdateSpanList(std::vector<SpanInfo>& spansInfosList, std::string& spans)
2893 {
2894 for (const auto& span : spansInfosList) {
2895 if (!spans.empty()) {
2896 spans.append(",");
2897 }
2898 spans.append("\n\t span id: ");
2899 spans.append(std::to_string(span.GetSpanId()));
2900 spans.append(", span text: ");
2901 spans.append(span.GetSpanText());
2902 spans.append(", accessibility text: ");
2903 spans.append(span.GetAccessibilityText());
2904 spans.append(", accessibility description: ");
2905 spans.append(span.GetAccessibilityDescription());
2906 spans.append(", accessibility level: ");
2907 spans.append(span.GetAccessibilityLevel());
2908 }
2909 }
2910
DumpSpanListNG(const AccessibilityElementInfo & nodeInfo)2911 inline void DumpSpanListNG(const AccessibilityElementInfo& nodeInfo)
2912 {
2913 std::string spans;
2914 std::vector<SpanInfo> spansInfosList = nodeInfo.GetSpanList();
2915 std::size_t spanCount = spansInfosList.size();
2916 UpdateSpanList(spansInfosList, spans);
2917 DumpLog::GetInstance().AddDesc("span list count: ", static_cast<int32_t>(spanCount));
2918 DumpLog::GetInstance().AddDesc("span list: ", spans);
2919 }
2920
GenerateAccessibilityEventInfo(const AccessibilityEvent & accessibilityEvent,AccessibilityEventInfo & eventInfo)2921 void GenerateAccessibilityEventInfo(const AccessibilityEvent& accessibilityEvent, AccessibilityEventInfo& eventInfo)
2922 {
2923 Accessibility::EventType type = Accessibility::EventType::TYPE_VIEW_INVALID;
2924 if (accessibilityEvent.type != AccessibilityEventType::UNKNOWN) {
2925 type = ConvertAceEventType(accessibilityEvent.type);
2926 } else {
2927 type = ConvertStrToEventType(accessibilityEvent.eventType);
2928 }
2929
2930 if (type == Accessibility::EventType::TYPE_VIEW_INVALID) {
2931 return;
2932 }
2933
2934 eventInfo.SetTimeStamp(GetMicroTickCount());
2935 eventInfo.SetBeforeText(accessibilityEvent.beforeText);
2936 eventInfo.SetLatestContent(accessibilityEvent.latestContent);
2937 eventInfo.SetTextAnnouncedForAccessibility(accessibilityEvent.textAnnouncedForAccessibility);
2938 eventInfo.SetWindowChangeTypes(static_cast<Accessibility::WindowUpdateType>(accessibilityEvent.windowChangeTypes));
2939 eventInfo.SetWindowContentChangeTypes(
2940 static_cast<Accessibility::WindowsContentChangeTypes>(accessibilityEvent.windowContentChangeTypes));
2941 eventInfo.SetSource(accessibilityEvent.nodeId);
2942 eventInfo.SetEventType(type);
2943 eventInfo.SetCurrentIndex(static_cast<int>(accessibilityEvent.currentItemIndex));
2944 eventInfo.SetItemCounts(static_cast<int>(accessibilityEvent.itemCount));
2945 eventInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
2946 eventInfo.SetBeginIndex(accessibilityEvent.startIndex);
2947 eventInfo.SetEndIndex(accessibilityEvent.endIndex);
2948 if (accessibilityEvent.extraEventInfo.size() > 0) {
2949 ExtraEventInfo extraEventInfo;
2950 for (const auto& info : accessibilityEvent.extraEventInfo) {
2951 auto ret = extraEventInfo.SetExtraEventInfo(info.first, info.second);
2952 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "The result of SetExtraEventInfo:%{public}d, keyStrLen:%{public}d",
2953 ret, static_cast<int>(info.first.length()));
2954 }
2955 eventInfo.SetExtraEvent(extraEventInfo);
2956 }
2957 }
2958 } // namespace
2959
DumpAccessibilityPropertyNG(const AccessibilityElementInfo & nodeInfo)2960 void JsAccessibilityManager::DumpAccessibilityPropertyNG(const AccessibilityElementInfo& nodeInfo)
2961 {
2962 DumpLog::GetInstance().AddDesc("checked: ", BoolToString(nodeInfo.IsChecked()));
2963 DumpLog::GetInstance().AddDesc("selected: ", BoolToString(nodeInfo.IsSelected()));
2964 DumpLog::GetInstance().AddDesc("checkable: ", BoolToString(nodeInfo.IsCheckable()));
2965 DumpLog::GetInstance().AddDesc("scrollable: ", BoolToString(nodeInfo.IsScrollable()));
2966 DumpLog::GetInstance().AddDesc("accessibility hint: ", BoolToString(nodeInfo.IsGivingHint()));
2967 DumpLog::GetInstance().AddDesc("hint text: ", nodeInfo.GetHint());
2968 DumpLog::GetInstance().AddDesc("error text: ", nodeInfo.GetError());
2969 DumpLog::GetInstance().AddDesc("max text length: ", nodeInfo.GetTextLengthLimit());
2970 DumpLog::GetInstance().AddDesc("scroll offset: ", nodeInfo.GetOffset());
2971 DumpLog::GetInstance().AddDesc("text selection start: ", nodeInfo.GetSelectedBegin());
2972 DumpLog::GetInstance().AddDesc("text selection end: ", nodeInfo.GetSelectedEnd());
2973 DumpLog::GetInstance().AddDesc("is multi line: ", BoolToString(nodeInfo.IsPluraLineSupported()));
2974 DumpLog::GetInstance().AddDesc("is password: ", BoolToString(nodeInfo.IsPassword()));
2975 DumpLog::GetInstance().AddDesc(
2976 "text input type: ", ConvertInputTypeToString(static_cast<AceTextCategory>(nodeInfo.GetInputType())));
2977 DumpGridInfoNG(nodeInfo);
2978 DumpLog::GetInstance().AddDesc("min value: ", nodeInfo.GetRange().GetMin());
2979 DumpLog::GetInstance().AddDesc("max value: ", nodeInfo.GetRange().GetMax());
2980 DumpLog::GetInstance().AddDesc("current value: ", nodeInfo.GetRange().GetCurrent());
2981 DumpLog::GetInstance().AddDesc("current index: ", nodeInfo.GetCurrentIndex());
2982 DumpLog::GetInstance().AddDesc("begin index: ", nodeInfo.GetBeginIndex());
2983 DumpLog::GetInstance().AddDesc("end index: ", nodeInfo.GetEndIndex());
2984 DumpLog::GetInstance().AddDesc("collection item counts: ", nodeInfo.GetItemCounts());
2985 DumpLog::GetInstance().AddDesc("editable: ", BoolToString(nodeInfo.IsEditable()));
2986 DumpLog::GetInstance().AddDesc("is essential: ", BoolToString(nodeInfo.IsEssential()));
2987 DumpLog::GetInstance().AddDesc("deletable: ", nodeInfo.IsDeletable());
2988 DumpLog::GetInstance().AddDesc("live region: ", nodeInfo.GetLiveRegion());
2989 DumpLog::GetInstance().AddDesc("content description: ", nodeInfo.GetDescriptionInfo());
2990 DumpLog::GetInstance().AddDesc("content invalid: ", BoolToString(nodeInfo.GetContentInvalid()));
2991 DumpLog::GetInstance().AddDesc("accessibility label: ", nodeInfo.GetLabeledAccessibilityId());
2992 DumpLog::GetInstance().AddDesc("isActive: ", nodeInfo.GetIsActive());
2993 DumpLog::GetInstance().AddDesc("accessibilityVisible: ", nodeInfo.GetAccessibilityVisible());
2994 DumpLog::GetInstance().AddDesc("accessibilityNextFocusInspectorKey: ",
2995 nodeInfo.GetAccessibilityNextFocusInspectorKey());
2996 DumpLog::GetInstance().AddDesc("accessibilityScrollTriggerable: ",
2997 nodeInfo.GetAccessibilityScrollable());
2998 DumpLog::GetInstance().AddDesc("accessibilityNextFocusId: ", nodeInfo.GetAccessibilityNextFocusId());
2999 DumpLog::GetInstance().AddDesc("accessibilityPreviousFocusId: ", nodeInfo.GetAccessibilityPreviousFocusId());
3000 DumpLog::GetInstance().AddDesc("clip: ", nodeInfo.GetClip());
3001 DumpExtraElementInfoNG(nodeInfo);
3002 DumpLog::GetInstance().AddDesc(
3003 "trigger action: ", static_cast<int32_t>(ConvertAccessibilityAction(nodeInfo.GetTriggerAction())));
3004 DumpLog::GetInstance().AddDesc("text move step: " + std::to_string(nodeInfo.GetTextMovementStep()));
3005 DumpSpanListNG(nodeInfo);
3006 DumpSupportActionNG(nodeInfo);
3007 DumpContentListNG(nodeInfo);
3008 DumpLog::GetInstance().AddDesc("latest content: ", nodeInfo.GetLatestContent());
3009 }
3010
DumpCommonPropertyNG(const AccessibilityElementInfo & nodeInfo,int32_t treeId)3011 void JsAccessibilityManager::DumpCommonPropertyNG(const AccessibilityElementInfo& nodeInfo, int32_t treeId)
3012 {
3013 AccessibilityElementInfoUtils::ToCommonInfo(nodeInfo, treeId_);
3014 }
3015
UpdateVirtualNodeFocus()3016 void JsAccessibilityManager::UpdateVirtualNodeFocus()
3017 {
3018 auto frameNode = lastFrameNode_.Upgrade();
3019 CHECK_NULL_VOID(frameNode);
3020 if (!frameNode->IsAccessibilityVirtualNode()) {
3021 return;
3022 }
3023 RefPtr<NG::RenderContext> renderContext;
3024 if (frameNode->GetAccessibilityId() == currentFocusNodeId_) {
3025 auto parentUinode = frameNode->GetVirtualNodeParent().Upgrade();
3026 CHECK_NULL_VOID(parentUinode);
3027 auto parentFrame = AceType::DynamicCast<NG::FrameNode>(parentUinode);
3028 CHECK_NULL_VOID(parentFrame);
3029 renderContext = parentFrame->GetRenderContext();
3030 CHECK_NULL_VOID(renderContext);
3031 renderContext->UpdateAccessibilityFocus(false);
3032 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
3033 CHECK_NULL_VOID(accessibilityProperty);
3034 if (accessibilityProperty->IsMatchAccessibilityResponseRegion(true)) {
3035 auto rectInt = accessibilityProperty->GetAccessibilityResponseRegionRect(true);
3036 renderContext->UpdateAccessibilityFocusRect(rectInt);
3037 } else {
3038 renderContext->UpdateAccessibilityFocusRect(GetFrameNodeRectInt(frameNode));
3039 }
3040 renderContext->UpdateAccessibilityFocus(true, frameNode->GetAccessibilityId());
3041 accessibilityProperty->SetAccessibilityFocusState(true);
3042 }
3043 }
3044
~JsAccessibilityManager()3045 JsAccessibilityManager::~JsAccessibilityManager()
3046 {
3047 UnsubscribeStateObserver(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED);
3048 UnsubscribeStateObserver(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED);
3049 UnsubscribeStateObserver(AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED);
3050
3051 DeregisterInteractionOperation();
3052 }
OnConfigChanged(const AccessibilityConfig::CONFIG_ID id,const AccessibilityConfig::ConfigValue & value)3053 void JsAccessibilityManager::ToastAccessibilityConfigObserver::OnConfigChanged(
3054 const AccessibilityConfig::CONFIG_ID id, const AccessibilityConfig::ConfigValue& value)
3055 {
3056 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "accessibility content timeout changed:%{public}u", value.contentTimeout);
3057 AceApplicationInfo::GetInstance().SetBarrierfreeDuration((int32_t)value.contentTimeout);
3058 }
3059
SubscribeToastObserver()3060 bool JsAccessibilityManager::SubscribeToastObserver()
3061 {
3062 if (!toastObserver_) {
3063 toastObserver_ = std::make_shared<ToastAccessibilityConfigObserver>();
3064 }
3065 CHECK_NULL_RETURN(toastObserver_, false);
3066 auto& config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
3067 bool isSuccess = config.InitializeContext();
3068 if (!isSuccess) {
3069 return false;
3070 }
3071 config.SubscribeConfigObserver(CONFIG_CONTENT_TIMEOUT, toastObserver_);
3072 return true;
3073 }
3074
UnsubscribeToastObserver()3075 bool JsAccessibilityManager::UnsubscribeToastObserver()
3076 {
3077 CHECK_NULL_RETURN(toastObserver_, false);
3078 auto& config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
3079 bool isSuccess = config.InitializeContext();
3080 if (!isSuccess) {
3081 return false;
3082 }
3083 config.UnsubscribeConfigObserver(CONFIG_CONTENT_TIMEOUT, toastObserver_);
3084 return true;
3085 }
3086
SubscribeStateObserver(uint32_t eventType)3087 bool JsAccessibilityManager::SubscribeStateObserver(uint32_t eventType)
3088 {
3089 if (!stateObserver_[eventType]) {
3090 stateObserver_[eventType] = std::make_shared<JsAccessibilityStateObserver>();
3091 }
3092
3093 stateObserver_[eventType]->SetAccessibilityManager(WeakClaim(this));
3094 stateObserver_[eventType]->SetPipeline(context_);
3095 stateObserver_[eventType]->SetEventType(eventType);
3096
3097 auto instance = AccessibilitySystemAbilityClient::GetInstance();
3098 CHECK_NULL_RETURN(instance, false);
3099 Accessibility::RetError ret = instance->SubscribeStateObserver(stateObserver_[eventType], eventType);
3100 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, " the result of SubscribeStateObserver:%{public}d, eventType:%{public}u",
3101 ret, eventType);
3102 return ret == RET_OK;
3103 }
3104
UnsubscribeStateObserver(uint32_t eventType)3105 bool JsAccessibilityManager::UnsubscribeStateObserver(uint32_t eventType)
3106 {
3107 CHECK_NULL_RETURN(stateObserver_[eventType], false);
3108 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
3109 CHECK_NULL_RETURN(instance, false);
3110 Accessibility::RetError ret = instance->UnsubscribeStateObserver(stateObserver_[eventType], eventType);
3111 return ret == RET_OK;
3112 }
3113
GenerateAccessibilityWorkMode()3114 AccessibilityWorkMode JsAccessibilityManager::GenerateAccessibilityWorkMode()
3115 {
3116 AccessibilityWorkMode accessibilityWorkMode;
3117 auto client = AccessibilitySystemAbilityClient::GetInstance();
3118 CHECK_NULL_RETURN(client, accessibilityWorkMode);
3119 auto ret = client->IsTouchExplorationEnabled(accessibilityWorkMode.isTouchExplorationEnabled);
3120 if (ret != RET_OK) {
3121 accessibilityWorkMode.isTouchExplorationEnabled = true;
3122 }
3123 return accessibilityWorkMode;
3124 }
3125
UpdateAccessibilityNextFocusIdMap(int32_t containerId,const std::string & nextFocusInspectorKey,int64_t preAccessibilityId)3126 void JsAccessibilityManager::UpdateAccessibilityNextFocusIdMap(int32_t containerId,
3127 const std::string& nextFocusInspectorKey,
3128 int64_t preAccessibilityId)
3129 {
3130 std::lock_guard<std::mutex> lock(nextFocusMapWithSubWindowMutex_);
3131
3132 auto it = nextFocusMapWithSubWindow_.find(containerId);
3133 if (it != nextFocusMapWithSubWindow_.end()) {
3134 HandleExistingContext(it, nextFocusInspectorKey, preAccessibilityId);
3135 } else {
3136 if (!nextFocusInspectorKey.empty()) {
3137 nextFocusMapWithSubWindow_.emplace(
3138 containerId, std::map<std::string, int64_t> {{ nextFocusInspectorKey, preAccessibilityId }});
3139 }
3140 }
3141 }
3142
InitializeCallback()3143 void JsAccessibilityManager::InitializeCallback()
3144 {
3145 if (IsRegister()) {
3146 return;
3147 }
3148
3149 auto pipelineContext = GetPipelineContext().Upgrade();
3150 CHECK_NULL_VOID(pipelineContext);
3151 windowId_ = pipelineContext->GetWindowId();
3152
3153 auto client = AccessibilitySystemAbilityClient::GetInstance();
3154 CHECK_NULL_VOID(client);
3155 bool isEnabled = false;
3156 client->IsEnabled(isEnabled);
3157 AceApplicationInfo::GetInstance().SetAccessibilityEnabled(isEnabled);
3158 bool isScreenReadEnabled = false;
3159 client->IsScreenReaderEnabled(isScreenReadEnabled);
3160 AceApplicationInfo::GetInstance().SetAccessibilityScreenReadEnabled(isScreenReadEnabled);
3161
3162 std::vector<uint32_t> needEvents;
3163 client->SearchNeedEvents(needEvents);
3164 UpdateEventWhiteList(needEvents);
3165
3166 SubscribeStateObserver(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED);
3167 SubscribeStateObserver(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED);
3168 SubscribeStateObserver(AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED);
3169
3170 auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
3171 if (container != nullptr && container->IsDynamicRender()) {
3172 RegisterDynamicRenderGetParentRectHandler();
3173 return;
3174 }
3175
3176 if (pipelineContext->IsFormRender() || pipelineContext->IsJsCard() || pipelineContext->IsJsPlugin()) {
3177 return;
3178 }
3179
3180 if (container != nullptr && container->IsUIExtensionWindow()) {
3181 pipelineContext->AddUIExtensionCallbackEvent(OHOS::Ace::NG::UIExtCallbackEventId::ON_UEA_ACCESSIBILITY_READY);
3182 RegisterUIExtBusinessConsumeCallback();
3183 RegisterGetParentRectHandler();
3184 if (container->GetUIContentType() == UIContentType::PREVIEW_UI_EXTENSION) {
3185 SetIsIgnoreAllAction(true);
3186 }
3187 return;
3188 }
3189
3190 if (isEnabled) {
3191 RegisterInteractionOperation(windowId_);
3192 }
3193 }
3194
RegisterGetParentRectHandler()3195 void JsAccessibilityManager::RegisterGetParentRectHandler()
3196 {
3197 auto accessibilityGetParentRect = [weak = WeakClaim(this)](AccessibilityParentRectInfo& parentRectInfo) {
3198 auto jsAccessibilityManager = weak.Upgrade();
3199 CHECK_NULL_VOID(jsAccessibilityManager);
3200 auto uecRectInfo = jsAccessibilityManager->GetUECAccessibilityParentRectInfo();
3201 if (uecRectInfo.isChanged) {
3202 parentRectInfo.left = uecRectInfo.left;
3203 parentRectInfo.top = uecRectInfo.top;
3204 parentRectInfo.scaleX = uecRectInfo.scaleX;
3205 parentRectInfo.scaleY = uecRectInfo.scaleY;
3206 parentRectInfo.rotateTransform = uecRectInfo.rotateTransform;
3207 } else {
3208 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(jsAccessibilityManager->context_.Upgrade());
3209 CHECK_NULL_VOID(ngPipeline);
3210 parentRectInfo.left = jsAccessibilityManager->GetWindowLeft(ngPipeline->GetWindowId());
3211 parentRectInfo.top = jsAccessibilityManager->GetWindowTop(ngPipeline->GetWindowId());
3212 auto container = Container::CurrentSafely();
3213 if (container) {
3214 auto windowScale = container->GetWindowScale();
3215 parentRectInfo.scaleX = windowScale;
3216 parentRectInfo.scaleY = windowScale;
3217 }
3218 }
3219 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3220 "Get host rect [scaleX:%{public}f, scaleY:%{public}f].", parentRectInfo.scaleX, parentRectInfo.scaleY);
3221 };
3222 SetAccessibilityGetParentRectHandler(accessibilityGetParentRect);
3223 }
3224
RegisterUIExtBusinessConsumeCallback()3225 void JsAccessibilityManager::RegisterUIExtBusinessConsumeCallback()
3226 {
3227 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
3228 CHECK_NULL_VOID(ngPipeline);
3229 auto uiExtManager = ngPipeline->GetUIExtensionManager();
3230 CHECK_NULL_VOID(uiExtManager);
3231 auto updateAccessibilityParentRectCallback = [weak = WeakClaim(this)](const AAFwk::Want& data) -> int32_t {
3232 auto jsAccessibilityManager = weak.Upgrade();
3233 CHECK_NULL_RETURN(jsAccessibilityManager, -1);
3234 AccessibilityParentRectInfo info;
3235 info.left = data.GetIntParam("left", 0);
3236 info.top = data.GetIntParam("top", 0);
3237 info.scaleX = data.GetFloatParam("scaleX", 1.0f);
3238 info.scaleY = data.GetFloatParam("scaleY", 1.0f);
3239 RotateTransform rotateTransform(data.GetIntParam("rotateDegree", 0), data.GetIntParam("centerX", 0),
3240 data.GetIntParam("centerY", 0), data.GetIntParam("innerCenterX", 0),
3241 data.GetIntParam("innerCenterY", 0));
3242 info.rotateTransform = rotateTransform;
3243 info.isChanged = true;
3244 jsAccessibilityManager->UpdateUECAccessibilityParentRectInfo(info);
3245 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3246 "Update UIExt Accessiblity [scaleX:%{public}f, scaleY:%{public}f].", info.scaleX, info.scaleY);
3247 // go on transfer info to next uiextension
3248 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(jsAccessibilityManager->context_.Upgrade());
3249 CHECK_NULL_RETURN(ngPipeline, -1);
3250 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3251 CHECK_NULL_RETURN(uiExtensionManager, -1);
3252 uiExtensionManager->TransferAccessibilityRectInfo();
3253 return 0;
3254 };
3255 uiExtManager->RegisterBusinessDataConsumeCallback(
3256 Ace::NG::UIContentBusinessCode::TRANSFORM_PARAM, updateAccessibilityParentRectCallback);
3257 }
3258
GetUECAccessibilityParentRectInfo() const3259 AccessibilityParentRectInfo JsAccessibilityManager::GetUECAccessibilityParentRectInfo() const
3260 {
3261 return uecRectInfo_;
3262 }
3263
UpdateUECAccessibilityParentRectInfo(const AccessibilityParentRectInfo & info)3264 void JsAccessibilityManager::UpdateUECAccessibilityParentRectInfo(const AccessibilityParentRectInfo& info)
3265 {
3266 uecRectInfo_ = info;
3267 }
3268
RegisterDynamicRenderGetParentRectHandler()3269 void JsAccessibilityManager::RegisterDynamicRenderGetParentRectHandler()
3270 {
3271 auto accessibilityGetParentRect = [weak = WeakClaim(this)](AccessibilityParentRectInfo& parentRectInfo) {
3272 auto jsAccessibilityManager = weak.Upgrade();
3273 CHECK_NULL_VOID(jsAccessibilityManager);
3274 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(jsAccessibilityManager->context_.Upgrade());
3275 CHECK_NULL_VOID(ngPipeline);
3276 auto container = Platform::AceContainer::GetContainer(ngPipeline->GetInstanceId());
3277 CHECK_NULL_VOID(container);
3278 auto containerHandler = container->GetContainerHandler();
3279 CHECK_NULL_VOID(containerHandler);
3280
3281 HandlerData data = {
3282 .actionCode = static_cast<int32_t>(NG::DynamicContainerHandleAction::ACCESSIBILITY_GET_RECT) };
3283 HandlerReply reply;
3284
3285 containerHandler->SendDataToHost(data, reply);
3286
3287 parentRectInfo.left = reply.GetParam<int32_t>("left", 0);
3288 parentRectInfo.top = reply.GetParam<int32_t>("top", 0);
3289 parentRectInfo.scaleX = reply.GetParam<float>("scaleX", 1.0f);
3290 parentRectInfo.scaleY = reply.GetParam<float>("scaleY", 1.0f);
3291 RotateTransform rotateData(reply.GetParam<int32_t>("rotateDegree", 0),
3292 reply.GetParam<int32_t>("centerX", 0),
3293 reply.GetParam<int32_t>("centerY", 0),
3294 reply.GetParam<int32_t>("innerCenterX", 0),
3295 reply.GetParam<int32_t>("innerCenterY", 0));
3296 parentRectInfo.rotateTransform = rotateData;
3297 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3298 "Get DC host rect [left:%{public}d, top:%{public}d, scaleX:%{public}f, scaleY:%{public}f].",
3299 parentRectInfo.left, parentRectInfo.top, parentRectInfo.scaleX, parentRectInfo.scaleY);
3300 };
3301 SetAccessibilityGetParentRectHandler(accessibilityGetParentRect);
3302 }
3303
3304
3305 namespace {
3306 const char FULL_SILENT[] = "FULL_SILENT";
3307
IsPageEvent(const Accessibility::EventType & eventType)3308 bool IsPageEvent(const Accessibility::EventType& eventType)
3309 {
3310 return eventType && (eventType == Accessibility::EventType::TYPE_PAGE_STATE_UPDATE
3311 || eventType == Accessibility::EventType::TYPE_PAGE_CONTENT_UPDATE
3312 || eventType == Accessibility::EventType::TYPE_PAGE_OPEN
3313 || eventType == Accessibility::EventType::TYPE_PAGE_CLOSE);
3314 }
3315
IsRootOrPageComponent(const std::string & componentType)3316 bool IsRootOrPageComponent(const std::string& componentType)
3317 {
3318 return !componentType.empty() && (componentType == V2::ROOT_ETS_TAG || componentType == V2::PAGE_ETS_TAG);
3319 }
3320
CheckSendAccessibilityEventByPageMode(const std::string & pageMode,const std::string & componentType,const int32_t pageId)3321 bool CheckSendAccessibilityEventByPageMode(
3322 const std::string& pageMode, const std::string& componentType, const int32_t pageId)
3323 {
3324 if (pageMode == FULL_SILENT) {
3325 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
3326 "current pageMode:%{public}s, drop page event", pageMode.c_str());
3327 return false;
3328 }
3329 if (IsRootOrPageComponent(componentType) && pageId <= 1) {
3330 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
3331 "current pageMode:%{public}s componentType:%{public}s pageId:%{public}d, drop page event",
3332 pageMode.c_str(), componentType.c_str(), pageId);
3333 return false;
3334 }
3335 return true;
3336 }
3337
CheckExtensionComponentReadyByPageId(const int32_t pageId,const std::vector<std::pair<WeakPtr<NG::FrameNode>,bool>> & nodeVec)3338 bool CheckExtensionComponentReadyByPageId(
3339 const int32_t pageId, const std::vector<std::pair<WeakPtr<NG::FrameNode>, bool>>& nodeVec)
3340 {
3341 for (const auto& [node, status] : nodeVec) {
3342 auto frameNode = node.Upgrade();
3343 if (frameNode && (frameNode->GetPageId() == pageId && !status)) {
3344 return false;
3345 }
3346 }
3347 return true;
3348 }
3349
IsDelNode(const WeakPtr<NG::FrameNode> & node)3350 bool IsDelNode(const WeakPtr<NG::FrameNode>& node)
3351 {
3352 auto frameNode = node.Upgrade();
3353 CHECK_NULL_RETURN(frameNode, true);
3354 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
3355 CHECK_NULL_RETURN(accessibilityProperty, true);
3356 return !accessibilityProperty->HasAccessibilitySamePage();
3357 }
3358
UpdateExtensionComponentStatusVec(std::vector<std::pair<WeakPtr<NG::FrameNode>,bool>> & nodeVec)3359 void UpdateExtensionComponentStatusVec(std::vector<std::pair<WeakPtr<NG::FrameNode>, bool>>& nodeVec)
3360 {
3361 for (auto it = nodeVec.begin(); it != nodeVec.end();) {
3362 if (IsDelNode(it->first)) {
3363 it = nodeVec.erase(it);
3364 } else {
3365 ++it;
3366 }
3367 }
3368 }
3369
ClearDefaultFocusList(std::list<WeakPtr<NG::FrameNode>> & nodeList)3370 void ClearDefaultFocusList(std::list<WeakPtr<NG::FrameNode>>& nodeList)
3371 {
3372 for (auto it = nodeList.begin(); it != nodeList.end();) {
3373 auto node = it->Upgrade();
3374 if (!node) {
3375 it = nodeList.erase(it);
3376 } else {
3377 ++it;
3378 }
3379 }
3380 }
3381
GetEventTypeByAccessibilityEvent(const AccessibilityEvent & accessibilityEvent)3382 Accessibility::EventType GetEventTypeByAccessibilityEvent(const AccessibilityEvent& accessibilityEvent)
3383 {
3384 Accessibility::EventType type = Accessibility::EventType::TYPE_VIEW_INVALID;
3385 if (accessibilityEvent.type != AccessibilityEventType::UNKNOWN) {
3386 type = ConvertAceEventType(accessibilityEvent.type);
3387 } else {
3388 type = ConvertStrToEventType(accessibilityEvent.eventType);
3389 }
3390 return type;
3391 }
3392 }
3393
CachePageEventByController(const AccessibilityEvent & accessibilityEvent,const std::string & componentType,int32_t pageId,int32_t containerId)3394 bool JsAccessibilityManager::CachePageEventByController(
3395 const AccessibilityEvent& accessibilityEvent,
3396 const std::string& componentType,
3397 int32_t pageId,
3398 int32_t containerId)
3399 {
3400 auto accessibilityWorkMode = GenerateAccessibilityWorkMode();
3401 if (!accessibilityWorkMode.isTouchExplorationEnabled) {
3402 return false;
3403 }
3404
3405 AccessibilityEvent event = accessibilityEvent;
3406 event.componentType = componentType;
3407 auto eventType = GetEventTypeByAccessibilityEvent(event);
3408 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3409 "cache page event from pageEventController, componentType:%{public}s event:%{public}d nodeId:%{public}"
3410 PRId64, event.componentType.c_str(), eventType, event.nodeId);
3411 pageController_.AddAccessibilityEvent(containerId, pageId, event);
3412 return true;
3413 }
3414
IsSendAccessibilityEvent(const AccessibilityEvent & accessibilityEvent)3415 bool JsAccessibilityManager::IsSendAccessibilityEvent(const AccessibilityEvent& accessibilityEvent)
3416 {
3417 if (!IsPageEvent(GetEventTypeByAccessibilityEvent(accessibilityEvent))) {
3418 return true;
3419 }
3420 GetInfoByNodeId infoOfNode;
3421 auto pipelineContext = GetPipelineContext().Upgrade();
3422 if (!pipelineContext) {
3423 return IsSendAccessibilityEventForHost(accessibilityEvent, infoOfNode.componentType, infoOfNode.pageId);
3424 }
3425
3426 GetComponentTypeAndPageIdByNodeId(accessibilityEvent.nodeId, pipelineContext, infoOfNode);
3427 auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
3428 if (container != nullptr && container->IsUIExtensionWindow()) {
3429 if (!IsSendAccessibilityEventForUEA(accessibilityEvent, infoOfNode.componentType, infoOfNode.pageId)) {
3430 return false;
3431 }
3432 pageController_.Update();
3433 if (!pageController_.CheckEmpty(infoOfNode.nodeInstanceId)) {
3434 auto cached = CachePageEventByController(
3435 accessibilityEvent, infoOfNode.componentType, infoOfNode.pageId, infoOfNode.nodeInstanceId);
3436 return !cached;
3437 }
3438 }
3439 return IsSendAccessibilityEventForHost(accessibilityEvent, infoOfNode.componentType, infoOfNode.pageId);
3440 }
3441
ReleaseCacheEvent()3442 void JsAccessibilityManager::ReleaseCacheEvent()
3443 {
3444 if (eventQueue_.empty()) {
3445 return;
3446 }
3447 while (!eventQueue_.empty()) {
3448 auto event = eventQueue_.front();
3449 SendAccessibilityAsyncEvent(event);
3450 eventQueue_.pop();
3451 }
3452 }
3453
IsSendAccessibilityEventForUEA(const AccessibilityEvent & accessibilityEvent,const std::string & componentType,const int32_t pageId)3454 bool JsAccessibilityManager::IsSendAccessibilityEventForUEA(
3455 const AccessibilityEvent& accessibilityEvent, const std::string& componentType, const int32_t pageId)
3456 {
3457 if (!pageMode_.has_value()) {
3458 eventQueue_.push(accessibilityEvent);
3459 return false;
3460 }
3461 const auto& pageMode = pageMode_.value();
3462 if (pageMode.empty()) {
3463 if (treeId_ == -1) {
3464 cacheEventVec_.push_back(accessibilityEvent);
3465 return false;
3466 }
3467 return true;
3468 }
3469 if (!CheckSendAccessibilityEventByPageMode(pageMode, componentType, pageId)) {
3470 return false;
3471 }
3472 if (treeId_ == -1) {
3473 cacheEventVec_.push_back(accessibilityEvent);
3474 return false;
3475 }
3476 return true;
3477 }
3478
IsSendAccessibilityEventForHost(const AccessibilityEvent & accessibilityEvent,const std::string & componentType,const int32_t pageId)3479 bool JsAccessibilityManager::IsSendAccessibilityEventForHost(
3480 const AccessibilityEvent& accessibilityEvent, const std::string& componentType, const int32_t pageId)
3481 {
3482 UpdateExtensionComponentStatusVec(extensionComponentStatusVec_);
3483 ClearDefaultFocusList(defaultFocusList_);
3484 RefPtr<NG::FrameNode> findeNode;
3485 auto ngPipeline = FindPipelineByElementId(accessibilityEvent.nodeId, findeNode);
3486
3487 pageController_.Update();
3488 bool isPageEventControllerEmpty = ngPipeline ? pageController_.CheckEmpty(ngPipeline->GetInstanceId()) : true;
3489 if (extensionComponentStatusVec_.empty() && isPageEventControllerEmpty) {
3490 return true;
3491 }
3492
3493 for (const auto& [node, status] : extensionComponentStatusVec_) {
3494 auto frameNode = node.Upgrade();
3495 CHECK_NULL_CONTINUE(frameNode);
3496 auto nodePageId = frameNode->GetPageId();
3497 if (!pageIdEventMap_.count(nodePageId)) {
3498 pageIdEventMap_[nodePageId] = std::nullopt;
3499 }
3500 }
3501 if (!CheckExtensionComponentReadyByPageId(pageId, extensionComponentStatusVec_)) {
3502 if (pageIdEventMap_.count(pageId) && pageIdEventMap_[pageId].has_value()) {
3503 auto event = pageIdEventMap_[pageId].value();
3504 auto eventType = GetEventTypeByAccessibilityEvent(event);
3505 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
3506 "override the event, componentType:%{public}s event:%{public}d nodeId:%{public}" PRId64,
3507 event.componentType.c_str(), eventType, event.nodeId);
3508 }
3509 AccessibilityEvent event = accessibilityEvent;
3510 event.componentType = componentType;
3511 pageIdEventMap_[pageId] = event;
3512 return false;
3513 } else if (!isPageEventControllerEmpty) {
3514 auto containerId = ngPipeline ? ngPipeline->GetInstanceId() : 0;
3515 auto cached = CachePageEventByController(accessibilityEvent, componentType, pageId, containerId);
3516 return !cached;
3517 }
3518 return true;
3519 }
3520
GetComponentTypeAndPageIdByNodeId(const int64_t nodeId,const RefPtr<PipelineBase> & context,GetInfoByNodeId & infoOfNode)3521 void JsAccessibilityManager::GetComponentTypeAndPageIdByNodeId(
3522 const int64_t nodeId,
3523 const RefPtr<PipelineBase>& context,
3524 GetInfoByNodeId& infoOfNode)
3525 {
3526 CHECK_NULL_VOID(context);
3527 if (AceType::InstanceOf<NG::PipelineContext>(context)) {
3528 RefPtr<NG::FrameNode> node;
3529 auto nodePipeline = FindPipelineByElementId(nodeId, node);
3530 CHECK_NULL_VOID(node);
3531 infoOfNode.componentType = node->GetTag();
3532 infoOfNode.pageId = node->GetPageId();
3533 infoOfNode.nodeInstanceId = nodePipeline ? nodePipeline->GetInstanceId() : -1;
3534 } else {
3535 auto node = GetAccessibilityNodeFromPage(nodeId);
3536 CHECK_NULL_VOID(node);
3537 infoOfNode.componentType = node->GetTag();
3538 infoOfNode.pageId = node->GetPageId();
3539 infoOfNode.nodeInstanceId = -1;
3540 }
3541 }
3542
SendCacheAccessibilityEvent(int32_t instanceId)3543 void JsAccessibilityManager::SendCacheAccessibilityEvent(int32_t instanceId)
3544 {
3545 auto container = Platform::AceContainer::GetContainer(instanceId);
3546 if (container == nullptr || !container->IsUIExtensionWindow()) {
3547 return;
3548 }
3549
3550 if (!cacheEventVec_.empty()) {
3551 for (const auto& event : cacheEventVec_) {
3552 SendAccessibilityAsyncEventInner(event);
3553 }
3554 cacheEventVec_.clear();
3555 }
3556 }
3557
SendCacheAccessibilityEventForHost(const int32_t pageId)3558 void JsAccessibilityManager::SendCacheAccessibilityEventForHost(const int32_t pageId)
3559 {
3560 if (!CheckExtensionComponentReadyByPageId(pageId, extensionComponentStatusVec_)) {
3561 return;
3562 }
3563
3564 if (pageIdEventMap_.count(pageId) && pageIdEventMap_[pageId].has_value()) {
3565 auto event = pageIdEventMap_[pageId].value();
3566 SendAccessibilityAsyncEventInner(event);
3567 pageIdEventMap_[pageId] = std::nullopt;
3568 }
3569 }
3570
CheckPageEventValidInCache(int32_t containerId)3571 bool JsAccessibilityManager::CheckPageEventValidInCache(int32_t containerId)
3572 {
3573 return pageController_.HasAnyAccessibilityEvent(containerId);
3574 }
3575
CheckPageEventByPageInCache(int32_t containerId,int32_t pageId)3576 bool JsAccessibilityManager::CheckPageEventByPageInCache(int32_t containerId, int32_t pageId)
3577 {
3578 return pageController_.HasAccessibilityEvent(containerId, pageId);
3579 }
3580
ReleaseAccessibilityEventList(const std::list<std::pair<int32_t,AccessibilityEvent>> & eventList)3581 void JsAccessibilityManager::ReleaseAccessibilityEventList(
3582 const std::list<std::pair<int32_t, AccessibilityEvent>>& eventList)
3583 {
3584 for (auto& pair : eventList) {
3585 auto eventType = GetEventTypeByAccessibilityEvent(pair.second);
3586 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3587 "release page event from pageEventController, componentType:%{public}s event:%{public}d nodeId:%{public}"
3588 PRId64, pair.second.componentType.c_str(), eventType, pair.second.nodeId);
3589 SendAccessibilityAsyncEventInner(pair.second);
3590 }
3591 }
3592
ReleaseAllCacheAccessibilityEvent(int32_t containerId)3593 void JsAccessibilityManager::ReleaseAllCacheAccessibilityEvent(int32_t containerId)
3594 {
3595 std::list<std::pair<int32_t, AccessibilityEvent>> eventList;
3596 pageController_.ReleaseAllAccessibilityEvent(containerId, eventList);
3597 ReleaseAccessibilityEventList(eventList);
3598 }
3599
ReleaseCacheAccessibilityEvent(int32_t containerId,int32_t pageId)3600 void JsAccessibilityManager::ReleaseCacheAccessibilityEvent(int32_t containerId, int32_t pageId)
3601 {
3602 std::list<std::pair<int32_t, AccessibilityEvent>> eventList;
3603 pageController_.ReleaseAccessibilityEvent(containerId, pageId, eventList);
3604 ReleaseAccessibilityEventList(eventList);
3605 if ((pageId == 0) || (pageId == -1)) {
3606 ReleaseAllCacheAccessibilityEvent(containerId);
3607 }
3608 }
3609
ReleasePageEvent(const RefPtr<NG::FrameNode> & node,bool deleteController,bool releaseAll)3610 void JsAccessibilityManager::ReleasePageEvent(const RefPtr<NG::FrameNode>& node, bool deleteController, bool releaseAll)
3611 {
3612 CHECK_NULL_VOID(node);
3613 auto pipeline = node->GetContextRefPtr();
3614 CHECK_NULL_VOID(pipeline);
3615 auto containerId = pipeline->GetInstanceId();
3616 if (pageController_.CheckNode(node, deleteController)) {
3617 ReleaseCacheAccessibilityEvent(containerId, node->GetPageId());
3618 }
3619
3620 if (releaseAll) {
3621 pageController_.DeleteInstanceNodeAll(node);
3622 ReleaseAllCacheAccessibilityEvent(containerId);
3623 }
3624 }
3625
AddToPageEventController(const RefPtr<NG::FrameNode> & node)3626 void JsAccessibilityManager::AddToPageEventController(const RefPtr<NG::FrameNode>& node)
3627 {
3628 pageController_.Add(node);
3629 }
3630
DeleteFromPageEventController(const RefPtr<NG::FrameNode> & node)3631 bool JsAccessibilityManager::DeleteFromPageEventController(const RefPtr<NG::FrameNode>& node)
3632 {
3633 return pageController_.Delete(node);
3634 }
3635
CheckPageEventCached(const RefPtr<NG::FrameNode> & node,bool onlyCurrentPage)3636 bool JsAccessibilityManager::CheckPageEventCached(const RefPtr<NG::FrameNode>& node, bool onlyCurrentPage)
3637 {
3638 CHECK_NULL_RETURN(node, false);
3639 auto pipeline = node->GetContextRefPtr();
3640 CHECK_NULL_RETURN(pipeline, false);
3641 auto containerId = pipeline->GetInstanceId();
3642
3643 if (onlyCurrentPage == false) {
3644 auto ret = CheckPageEventValidInCache(containerId);
3645 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3646 "CheckPageEventCached not onlyCurrentPage return %{public}d containerId %{public}d control Id :%{public}"
3647 PRId64, ret, containerId, node->GetAccessibilityId());
3648 return ret;
3649 }
3650
3651 auto pageId = node->GetPageId();
3652 if ((pageId == 0) || (pageId == -1)) {
3653 auto ret = CheckPageEventValidInCache(containerId);
3654 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3655 "CheckPageEventCached pageId %{public}d return %{public}d containerId %{public}d control Id :%{public}"
3656 PRId64, pageId, ret, containerId, node->GetAccessibilityId());
3657 return ret;
3658 }
3659 auto ret = CheckPageEventByPageInCache(containerId, pageId);
3660 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3661 "CheckPageEventCached pageId %{public}d return %{public}d containerId %{public}d control Id :%{public}"
3662 PRId64, pageId, ret, containerId, node->GetAccessibilityId());
3663 return ret;
3664 }
3665
3666
AddFrameNodeToUecStatusVec(const RefPtr<NG::FrameNode> & node)3667 void JsAccessibilityManager::AddFrameNodeToUecStatusVec(const RefPtr<NG::FrameNode>& node)
3668 {
3669 extensionComponentStatusVec_.emplace_back(WeakPtr(node), false);
3670 }
3671
AddFrameNodeToDefaultFocusList(const RefPtr<NG::FrameNode> & node,bool isFocus)3672 void JsAccessibilityManager::AddFrameNodeToDefaultFocusList(const RefPtr<NG::FrameNode>& node, bool isFocus)
3673 {
3674 if (isFocus) {
3675 AddDefaultFocusNode(node);
3676 return;
3677 }
3678 EraseDefaultFocusNode(node);
3679 }
3680
AddDefaultFocusNode(const RefPtr<NG::FrameNode> & defaultFocusNode)3681 void JsAccessibilityManager::AddDefaultFocusNode(const RefPtr<NG::FrameNode>& defaultFocusNode)
3682 {
3683 CHECK_NULL_VOID(defaultFocusNode);
3684 auto nodeId = defaultFocusNode->GetId();
3685 for (const auto& node : defaultFocusList_) {
3686 auto frameNode = node.Upgrade();
3687 if (frameNode && (frameNode->GetId() == nodeId)) {
3688 return;
3689 }
3690 }
3691 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
3692 "add frameNode to defaultFocusList, nodeId: %{public}d.", nodeId);
3693 defaultFocusList_.push_back(WeakPtr(defaultFocusNode));
3694 }
3695
EraseDefaultFocusNode(const RefPtr<NG::FrameNode> & defaultFocusNode)3696 void JsAccessibilityManager::EraseDefaultFocusNode(const RefPtr<NG::FrameNode>& defaultFocusNode)
3697 {
3698 CHECK_NULL_VOID(defaultFocusNode);
3699 auto nodeId = defaultFocusNode->GetId();
3700 for (auto it = defaultFocusList_.begin(); it != defaultFocusList_.end();) {
3701 auto node = it->Upgrade();
3702 if (node && (node->GetId() == nodeId)) {
3703 it = defaultFocusList_.erase(it);
3704 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
3705 "erase frameNode from defaultFocusList, nodeId: %{public}d.", nodeId);
3706 return;
3707 } else {
3708 ++it;
3709 }
3710 }
3711 }
3712
AddHoverTransparentCallback(const RefPtr<NG::FrameNode> & node)3713 void JsAccessibilityManager::AddHoverTransparentCallback(const RefPtr<NG::FrameNode>& node)
3714 {
3715 hoverTransparentCallbackController_.AddToHoverTransparentCallbackList(node);
3716 }
3717
CheckHoverTransparentCallbackListEmpty(int32_t containerId)3718 bool JsAccessibilityManager::CheckHoverTransparentCallbackListEmpty(int32_t containerId)
3719 {
3720 return hoverTransparentCallbackController_.CheckHoverTransparentCallbackListEmpty(containerId);
3721 }
3722
CheckAndGetEmbedFrameNode(const RefPtr<NG::FrameNode> & node)3723 int64_t JsAccessibilityManager::CheckAndGetEmbedFrameNode(const RefPtr<NG::FrameNode>& node)
3724 {
3725 auto surfaceId = GetSurfaceIdByEmbedNode(node);
3726 if (surfaceId == "0") {
3727 return INVALID_NODE_ID;
3728 }
3729 #ifdef WEB_SUPPORTED
3730 return GetWebAccessibilityIdBySurfaceId(surfaceId);
3731 #else
3732 return INVALID_NODE_ID;
3733 #endif
3734 }
3735
RegisterUIExtGetPageModeCallback(RefPtr<NG::UIExtensionManager> & uiExtManager)3736 void JsAccessibilityManager::RegisterUIExtGetPageModeCallback(RefPtr<NG::UIExtensionManager>& uiExtManager)
3737 {
3738 CHECK_NULL_VOID(uiExtManager);
3739 auto callback = [weak = WeakClaim(this)](const AAFwk::Want& data) -> int32_t {
3740 if (!data.HasParameter("pageMode")) {
3741 return -1;
3742 }
3743 auto accessibilityManager = weak.Upgrade();
3744 CHECK_NULL_RETURN(accessibilityManager, -1);
3745
3746 auto pageMode = data.GetStringParam("pageMode");
3747 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
3748 "host send pageMode to uea, pageMode: %{public}s.", pageMode.c_str());
3749 accessibilityManager->UpdatePageMode(pageMode);
3750 accessibilityManager->ReleaseCacheEvent();
3751 return 0;
3752 };
3753 uiExtManager->RegisterBusinessDataConsumeCallback(NG::UIContentBusinessCode::SEND_PAGE_MODE_TO_UEA, callback);
3754 }
3755
UpdateFrameNodeState(int32_t nodeId)3756 void JsAccessibilityManager::UpdateFrameNodeState(int32_t nodeId)
3757 {
3758 for (auto& [node, status] : extensionComponentStatusVec_) {
3759 auto frameNode = node.Upgrade();
3760 if (frameNode && (frameNode->GetId() == nodeId)) {
3761 status = true;
3762 SendCacheAccessibilityEventForHost(frameNode->GetPageId());
3763 return;
3764 }
3765 }
3766 }
3767
SendAccessibilitySyncEvent(const AccessibilityEvent & accessibilityEvent,AccessibilityEventInfo eventInfo)3768 bool JsAccessibilityManager::SendAccessibilitySyncEvent(
3769 const AccessibilityEvent& accessibilityEvent, AccessibilityEventInfo eventInfo)
3770 {
3771 if (!IsRegister()) {
3772 return false;
3773 }
3774 auto client = AccessibilitySystemAbilityClient::GetInstance();
3775 CHECK_NULL_RETURN(client, false);
3776 bool isEnabled = false;
3777 client->IsEnabled(isEnabled);
3778 if (!isEnabled) {
3779 return false;
3780 }
3781 AccessibilityElementInfo info = eventInfo.GetElementInfo();
3782 int64_t elementId = eventInfo.GetAccessibilityId();
3783 if (info.GetBelongTreeId() > 0) {
3784 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(info.GetBelongTreeId(), elementId);
3785 }
3786 eventInfo.SetSource(elementId);
3787 UpdateElementInfoTreeId(info);
3788 eventInfo.SetElementInfo(info);
3789 eventInfo.SetPageId(info.GetPageId());
3790 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3791 "send accessibility componentType:%{public}s event:%{public}d accessibilityId:%{public}" PRId64,
3792 eventInfo.GetComponentType().c_str(), eventInfo.GetEventType(), eventInfo.GetAccessibilityId());
3793 if (IsTagInEmbedComponent(eventInfo.GetComponentType()) &&
3794 eventInfo.GetEventType() == TYPE_VIEW_HOVER_ENTER_EVENT) {
3795 TAG_LOGI(AceLogTag::ACE_WEB, "dont hover on embeddedObject without same layer rendering");
3796 return false;
3797 }
3798 return client->SendEvent(eventInfo);
3799 }
3800
TransferAccessibilityAsyncEvent(const AccessibilityEventInfo & eventInfo,int64_t uiExtensionOffset)3801 bool JsAccessibilityManager::TransferAccessibilityAsyncEvent(
3802 const AccessibilityEventInfo& eventInfo, int64_t uiExtensionOffset)
3803 {
3804 #ifdef WINDOW_SCENE_SUPPORTED
3805 auto client = AccessibilitySystemAbilityClient::GetInstance();
3806 CHECK_NULL_RETURN(client, false);
3807 bool isEnabled = false;
3808 client->IsEnabled(isEnabled);
3809 if (!isEnabled) {
3810 return false;
3811 }
3812
3813 auto pipeline = context_.Upgrade();
3814 CHECK_NULL_RETURN(pipeline, false);
3815 RefPtr<NG::PipelineContext> ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
3816 CHECK_NULL_RETURN(ngPipeline, false);
3817 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3818 CHECK_NULL_RETURN(uiExtensionManager, false);
3819 auto container = Container::GetContainer(ngPipeline->GetInstanceId());
3820 bool isDynamicRender = container && container->IsDynamicRender() &&
3821 container->GetUIContentType() == UIContentType::ISOLATED_COMPONENT;
3822 if (!IsRegister() && !isDynamicRender) {
3823 return false;
3824 }
3825 AccessibilityEventInfo eventInfoNew = eventInfo;
3826 if (isDynamicRender) {
3827 auto focusedContainer = Container::GetFocused();
3828 if (focusedContainer) {
3829 eventInfoNew.SetWindowId(focusedContainer->GetWindowId());
3830 }
3831 }
3832 eventInfoNew.SetSource(uiExtensionOffset * GetUiextensionId() + eventInfo.GetViewId());
3833 AccessibilityElementInfo elementInfo;
3834 FillElementInfo(eventInfoNew.GetAccessibilityId(), elementInfo, pipeline, Claim(this),
3835 FillEventInfoParam { eventInfoNew.GetAccessibilityId(), -1,
3836 static_cast<int32_t>(eventInfoNew.GetWindowId()) });
3837 eventInfoNew.SetElementInfo(elementInfo);
3838 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "send accessibility event:%{public}d accessibilityId:%{public}" PRId64,
3839 eventInfoNew.GetEventType(), eventInfoNew.GetAccessibilityId());
3840 return client->SendEvent(eventInfoNew);
3841 #endif
3842 return false;
3843 }
3844
SendExtensionAccessibilityEvent(const AccessibilityEventInfo & eventInfo,int64_t uiExtensionOffset)3845 void JsAccessibilityManager::SendExtensionAccessibilityEvent(
3846 const AccessibilityEventInfo& eventInfo, int64_t uiExtensionOffset)
3847 {
3848 TransferAccessibilityAsyncEvent(eventInfo, uiExtensionOffset);
3849 }
3850
FillEventInfoWithNode(const RefPtr<NG::FrameNode> & node,AccessibilityEventInfo & eventInfo,const RefPtr<NG::PipelineContext> & context,int64_t elementId)3851 void JsAccessibilityManager::FillEventInfoWithNode(
3852 const RefPtr<NG::FrameNode>& node,
3853 AccessibilityEventInfo& eventInfo,
3854 const RefPtr<NG::PipelineContext>& context,
3855 int64_t elementId)
3856 {
3857 CHECK_NULL_VOID(node);
3858 eventInfo.SetComponentType(node->GetTag());
3859 eventInfo.SetPageId(node->GetPageId());
3860 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
3861 CHECK_NULL_VOID(accessibilityProperty);
3862 eventInfo.SetItemCounts(accessibilityProperty->GetCollectionItemCounts());
3863 eventInfo.SetBeginIndex(accessibilityProperty->GetBeginIndex());
3864 eventInfo.SetEndIndex(accessibilityProperty->GetEndIndex());
3865 AccessibilityElementInfo elementInfo;
3866
3867 CommonProperty commonProperty;
3868 auto mainContext = context_.Upgrade();
3869 CHECK_NULL_VOID(mainContext);
3870 GenerateCommonProperty(context, commonProperty, mainContext, node);
3871 UpdateAccessibilityElementInfo(node, commonProperty, elementInfo, context);
3872 elementInfo.SetWindowId(eventInfo.GetWindowId());
3873 eventInfo.AddContent(elementInfo.GetContent());
3874 eventInfo.SetElementInfo(elementInfo);
3875 }
3876
GetDelayTimeBeforeSendEvent(const AccessibilityEvent & accessibilityEvent,const RefPtr<AceType> & node)3877 int64_t JsAccessibilityManager::GetDelayTimeBeforeSendEvent(
3878 const AccessibilityEvent& accessibilityEvent,
3879 const RefPtr<AceType>& node)
3880 {
3881 if (accessibilityEvent.type != AccessibilityEventType::CLICK) {
3882 return 0;
3883 }
3884
3885 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
3886 if (frameNode) {
3887 if (IsUserCheckedOrSelected(frameNode)) {
3888 return DELAY_SEND_EVENT_MILLISECOND;
3889 }
3890 } else {
3891 auto context = GetPipelineContext().Upgrade();
3892 if (!AceType::InstanceOf<NG::PipelineContext>(context)) {
3893 return 0;
3894 }
3895 RefPtr<NG::FrameNode> findeNode;
3896 auto ngPipeline = FindPipelineByElementId(accessibilityEvent.nodeId, findeNode);
3897 if ((findeNode) && IsUserCheckedOrSelected(findeNode)) {
3898 return DELAY_SEND_EVENT_MILLISECOND;
3899 }
3900 }
3901
3902 return 0;
3903 }
3904
IsEventIgnoredByWorkMode(const AccessibilityEvent & accessibilityEvent)3905 bool JsAccessibilityManager::IsEventIgnoredByWorkMode(const AccessibilityEvent& accessibilityEvent)
3906 {
3907 auto accessibilityWorkMode = GenerateAccessibilityWorkMode();
3908 if (!accessibilityWorkMode.isTouchExplorationEnabled) {
3909 switch (accessibilityEvent.type) {
3910 case AccessibilityEventType::ELEMENT_INFO_CHANGE:
3911 case AccessibilityEventType::TEXT_CHANGE:
3912 case AccessibilityEventType::FOCUS:
3913 case AccessibilityEventType::SCROLLING_EVENT:
3914 return true;
3915 default:
3916 return false;
3917 }
3918 }
3919 return false;
3920 }
3921
SendEventToAccessibilityWithNode(const AccessibilityEvent & accessibilityEvent,const RefPtr<AceType> & node,const RefPtr<PipelineBase> & context)3922 void JsAccessibilityManager::SendEventToAccessibilityWithNode(
3923 const AccessibilityEvent& accessibilityEvent, const RefPtr<AceType>& node, const RefPtr<PipelineBase>& context)
3924 {
3925 auto eventType = GetEventTypeByAccessibilityEvent(accessibilityEvent);
3926 if (!CheckWhiteList(eventType)) {
3927 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3928 "send accessibility check whitelist failed event:%{public}d" PRId64, eventType);
3929 return;
3930 }
3931
3932 if (IsEventIgnoredByWorkMode(accessibilityEvent) || !IsSendAccessibilityEvent(accessibilityEvent)) {
3933 return;
3934 }
3935
3936 auto delayTime = GetDelayTimeBeforeSendEvent(accessibilityEvent, node);
3937 if ((delayTime > 0) && context) {
3938 context->GetTaskExecutor()->PostDelayedTask(
3939 [weak = WeakClaim(this), accessibilityEvent, node, context] {
3940 auto jsAccessibilityManager = weak.Upgrade();
3941 CHECK_NULL_VOID(jsAccessibilityManager);
3942 jsAccessibilityManager->SendEventToAccessibilityWithNodeInner(accessibilityEvent, node, context);
3943 },
3944 TaskExecutor::TaskType::UI, delayTime, "ArkUIAccessibilitySendSyncEventWithDelay");
3945 return;
3946 }
3947 SendEventToAccessibilityWithNodeInner(accessibilityEvent, node, context);
3948 }
3949
SendEventToAccessibilityWithNodeInner(const AccessibilityEvent & accessibilityEvent,const RefPtr<AceType> & node,const RefPtr<PipelineBase> & context)3950 void JsAccessibilityManager::SendEventToAccessibilityWithNodeInner(
3951 const AccessibilityEvent& accessibilityEvent, const RefPtr<AceType>& node, const RefPtr<PipelineBase>& context)
3952 {
3953 ACE_SCOPED_TRACE("SendAccessibilityAsyncEvent");
3954 CHECK_NULL_VOID(node);
3955 CHECK_NULL_VOID(context);
3956 int32_t windowId = static_cast<int32_t>(context->GetRealHostWindowId());
3957 if (windowId == 0) {
3958 return;
3959 }
3960 if (!AceType::InstanceOf<NG::FrameNode>(node)) {
3961 return;
3962 }
3963 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
3964 CHECK_NULL_VOID(frameNode);
3965 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
3966 CHECK_NULL_VOID(ngPipeline);
3967
3968 if ((!frameNode->IsActive()) || frameNode->CheckAccessibilityLevelNo()) {
3969 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "node: %{public}" PRId64 ", is not active or level is no",
3970 frameNode->GetAccessibilityId());
3971 return;
3972 }
3973
3974 AccessibilityEventInfo eventInfo;
3975
3976 if (accessibilityEvent.type != AccessibilityEventType::PAGE_CHANGE || accessibilityEvent.windowId == 0) {
3977 eventInfo.SetWindowId(windowId);
3978 } else {
3979 eventInfo.SetWindowId(accessibilityEvent.windowId);
3980 }
3981 FillEventInfoWithNode(frameNode, eventInfo, ngPipeline, accessibilityEvent.nodeId);
3982 if ((ngPipeline != nullptr) && (ngPipeline->IsFormRender())) {
3983 eventInfo.SetWindowId(static_cast<int32_t>(GetWindowId()));
3984 }
3985 GenerateAccessibilityEventInfo(accessibilityEvent, eventInfo);
3986
3987 auto container = Container::GetContainer(context->GetInstanceId());
3988 if (container && container->IsDynamicRender() &&
3989 container->GetUIContentType() == UIContentType::ISOLATED_COMPONENT) {
3990 SendExtensionAccessibilityEvent(eventInfo, NG::UI_EXTENSION_UNKNOW_ID);
3991 } else {
3992 context->GetTaskExecutor()->PostTask(
3993 [weak = WeakClaim(this), accessibilityEvent, eventInfo] {
3994 auto jsAccessibilityManager = weak.Upgrade();
3995 CHECK_NULL_VOID(jsAccessibilityManager);
3996 jsAccessibilityManager->SendAccessibilitySyncEvent(accessibilityEvent, eventInfo);
3997 },
3998 TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySendSyncEvent");
3999 }
4000 }
4001
GetRealEventWindowId(const AccessibilityEvent & accessibilityEvent,const RefPtr<NG::PipelineContext> & ngPipeline,uint32_t & windowId)4002 void GetRealEventWindowId(
4003 const AccessibilityEvent& accessibilityEvent, const RefPtr<NG::PipelineContext>& ngPipeline, uint32_t& windowId)
4004 {
4005 if ((accessibilityEvent.type == AccessibilityEventType::PAGE_CHANGE && accessibilityEvent.windowId != 0) ||
4006 accessibilityEvent.windowChangeTypes == WINDOW_UPDATE_ADDED) {
4007 windowId = accessibilityEvent.windowId;
4008 return;
4009 }
4010 if ((ngPipeline != nullptr) && (ngPipeline->IsFormRender())) {
4011 return;
4012 }
4013 windowId = ngPipeline->GetRealHostWindowId();
4014 }
4015
SendAccessibilityAsyncEvent(const AccessibilityEvent & accessibilityEvent)4016 void JsAccessibilityManager::SendAccessibilityAsyncEvent(const AccessibilityEvent& accessibilityEvent)
4017 {
4018 auto eventType = GetEventTypeByAccessibilityEvent(accessibilityEvent);
4019 if (!CheckWhiteList(eventType)) {
4020 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
4021 "send accessibility check whitelist failed event:%{public}d" PRId64, eventType);
4022 return;
4023 }
4024 if (IsEventIgnoredByWorkMode(accessibilityEvent) || !IsSendAccessibilityEvent(accessibilityEvent)) {
4025 return;
4026 }
4027
4028 auto delayTime = GetDelayTimeBeforeSendEvent(accessibilityEvent, nullptr);
4029 if (delayTime > 0) {
4030 auto context = GetPipelineContext().Upgrade();
4031 if (context) {
4032 context->GetTaskExecutor()->PostDelayedTask(
4033 [weak = WeakClaim(this), accessibilityEvent] {
4034 auto jsAccessibilityManager = weak.Upgrade();
4035 CHECK_NULL_VOID(jsAccessibilityManager);
4036 jsAccessibilityManager->SendAccessibilityAsyncEventInner(accessibilityEvent);
4037 },
4038 TaskExecutor::TaskType::UI, delayTime, "ArkUIAccessibilitySendSyncEventWithDelay");
4039 }
4040 return;
4041 }
4042 SendAccessibilityAsyncEventInner(accessibilityEvent);
4043 }
4044
SendAccessibilityAsyncEventInner(const AccessibilityEvent & accessibilityEvent)4045 void JsAccessibilityManager::SendAccessibilityAsyncEventInner(const AccessibilityEvent& accessibilityEvent)
4046 {
4047 ACE_ACCESS_SCOPED_TRACE("SendAccessibilityAsyncEvent");
4048 auto context = GetPipelineContext().Upgrade();
4049 CHECK_NULL_VOID(context);
4050 int32_t windowId = static_cast<int32_t>(context->GetRealHostWindowId());
4051 if (windowId == 0) {
4052 return;
4053 }
4054 RefPtr<NG::PipelineContext> ngPipeline;
4055 AccessibilityEventInfo eventInfo;
4056 uint32_t realWindowId = GetWindowId();
4057 if (AceType::InstanceOf<NG::PipelineContext>(context)) {
4058 RefPtr<NG::FrameNode> node;
4059 ngPipeline = FindPipelineByElementId(accessibilityEvent.nodeId, node);
4060 CHECK_NULL_VOID(ngPipeline);
4061 CHECK_NULL_VOID(node);
4062 GetRealEventWindowId(accessibilityEvent, ngPipeline, realWindowId);
4063 FillEventInfo(node, eventInfo, ngPipeline, Claim(this),
4064 FillEventInfoParam {
4065 accessibilityEvent.nodeId, accessibilityEvent.stackNodeId, realWindowId });
4066 eventInfo.SetWindowId(realWindowId);
4067 } else {
4068 ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4069 auto node = GetAccessibilityNodeFromPage(accessibilityEvent.nodeId);
4070 CHECK_NULL_VOID(node);
4071 FillEventInfo(node, eventInfo);
4072 eventInfo.SetWindowId(windowId);
4073 }
4074 if (accessibilityEvent.type == AccessibilityEventType::PAGE_CHANGE && accessibilityEvent.windowId != 0) {
4075 eventInfo.SetWindowId(accessibilityEvent.windowId);
4076 }
4077 if ((ngPipeline != nullptr) && (ngPipeline->IsFormRender())) {
4078 eventInfo.SetWindowId(static_cast<int32_t>(GetWindowId()));
4079 }
4080
4081 GenerateAccessibilityEventInfo(accessibilityEvent, eventInfo);
4082
4083 auto container = Container::GetContainer(context->GetInstanceId());
4084 if (container && container->IsDynamicRender() &&
4085 container->GetUIContentType() == UIContentType::ISOLATED_COMPONENT) {
4086 SendExtensionAccessibilityEvent(eventInfo, NG::UI_EXTENSION_OFFSET_MAX);
4087 } else {
4088 context->GetTaskExecutor()->PostTask(
4089 [weak = WeakClaim(this), accessibilityEvent, eventInfo] {
4090 auto jsAccessibilityManager = weak.Upgrade();
4091 CHECK_NULL_VOID(jsAccessibilityManager);
4092 jsAccessibilityManager->SendAccessibilitySyncEvent(accessibilityEvent, eventInfo);
4093 },
4094 TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySendSyncEvent");
4095 }
4096 }
4097
4098 #ifdef WEB_SUPPORTED
4099
SendWebAccessibilityAsyncEvent(const AccessibilityEvent & accessibilityEvent,const RefPtr<NG::WebPattern> & webPattern)4100 void JsAccessibilityManager::SendWebAccessibilityAsyncEvent(
4101 const AccessibilityEvent& accessibilityEvent, const RefPtr<NG::WebPattern>& webPattern)
4102 {
4103 ACE_ACCESS_SCOPED_TRACE("SendWebAccessibilityAsyncEvent");
4104 auto context = GetPipelineContext().Upgrade();
4105 CHECK_NULL_VOID(context);
4106 int32_t windowId = static_cast<int32_t>(context->GetRealHostWindowId());
4107 if (windowId == 0) {
4108 return;
4109 }
4110
4111 AccessibilityEventInfo eventInfo;
4112 RefPtr<NG::PipelineContext> ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
4113 CHECK_NULL_VOID(ngPipeline);
4114 FillWebEventInfo(eventInfo, ngPipeline, Claim(this),
4115 FillEventInfoParam {
4116 accessibilityEvent.nodeId, accessibilityEvent.stackNodeId, ngPipeline->GetRealHostWindowId() },
4117 webPattern);
4118 eventInfo.SetWindowId(ngPipeline->GetRealHostWindowId());
4119
4120 if (accessibilityEvent.type == AccessibilityEventType::PAGE_CHANGE && accessibilityEvent.windowId != 0) {
4121 eventInfo.SetWindowId(accessibilityEvent.windowId);
4122 }
4123
4124 GenerateAccessibilityEventInfo(accessibilityEvent, eventInfo);
4125
4126 context->GetTaskExecutor()->PostTask(
4127 [weak = WeakClaim(this), accessibilityEvent, eventInfo] {
4128 auto jsAccessibilityManager = weak.Upgrade();
4129 CHECK_NULL_VOID(jsAccessibilityManager);
4130 jsAccessibilityManager->SendAccessibilitySyncEvent(accessibilityEvent, eventInfo);
4131 },
4132 TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySendSyncEvent");
4133 }
4134 #endif
4135
UpdateNodeChildIds(const RefPtr<AccessibilityNode> & node)4136 void JsAccessibilityManager::UpdateNodeChildIds(const RefPtr<AccessibilityNode>& node)
4137 {
4138 CHECK_NULL_VOID(node);
4139 node->ActionUpdateIds();
4140 const auto& children = node->GetChildList();
4141 std::vector<int32_t> childrenVec;
4142 auto cardId = GetCardId();
4143 auto rootNodeId = GetRootNodeId();
4144
4145 // get last stack children to barrier free service.
4146 if ((node->GetNodeId() == GetRootNodeId() + ROOT_STACK_BASE) && !children.empty() && !IsDeclarative()) {
4147 auto lastChildNodeId = children.back()->GetNodeId();
4148 if (isOhosHostCard()) {
4149 childrenVec.emplace_back(ConvertToCardAccessibilityId(lastChildNodeId, cardId, rootNodeId));
4150 } else {
4151 childrenVec.emplace_back(lastChildNodeId);
4152 for (const auto& child : children) {
4153 if (child->GetNodeId() == ROOT_DECOR_BASE - 1) {
4154 childrenVec.emplace_back(child->GetNodeId());
4155 break;
4156 }
4157 }
4158 }
4159 } else {
4160 childrenVec.resize(children.size());
4161 if (isOhosHostCard()) {
4162 std::transform(children.begin(), children.end(), childrenVec.begin(),
4163 [cardId, rootNodeId](const RefPtr<AccessibilityNode>& child) {
4164 return ConvertToCardAccessibilityId(child->GetNodeId(), cardId, rootNodeId);
4165 });
4166 } else {
4167 std::transform(children.begin(), children.end(), childrenVec.begin(),
4168 [](const RefPtr<AccessibilityNode>& child) { return child->GetNodeId(); });
4169 }
4170 }
4171 node->SetChildIds(childrenVec);
4172 }
4173
ProcessParameters(ActionType op,const std::vector<std::string> & params,std::map<std::string,std::string> & paramsMap)4174 void JsAccessibilityManager::ProcessParameters(
4175 ActionType op, const std::vector<std::string>& params, std::map<std::string, std::string>& paramsMap)
4176 {
4177 if (op == ActionType::ACCESSIBILITY_ACTION_SET_TEXT) {
4178 if (params.size() == (EVENT_DUMP_ACTION_PARAM_INDEX + 1)) {
4179 paramsMap = { { ACTION_ARGU_SET_TEXT, params[EVENT_DUMP_ACTION_PARAM_INDEX] } };
4180 }
4181 }
4182
4183 if (op == ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) {
4184 paramsMap[ACTION_ARGU_SELECT_TEXT_START] = "-1";
4185 paramsMap[ACTION_ARGU_SELECT_TEXT_END] = "-1";
4186 paramsMap[ACTION_ARGU_SELECT_TEXT_INFORWARD] = STRING_DIR_BACKWARD;
4187 if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER) {
4188 paramsMap[ACTION_ARGU_SELECT_TEXT_START] = params[EVENT_DUMP_ACTION_PARAM_INDEX];
4189 }
4190 if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER + 1) {
4191 paramsMap[ACTION_ARGU_SELECT_TEXT_END] = params[EVENT_DUMP_ACTION_PARAM_INDEX + 1];
4192 }
4193 // 2 means params number Offset
4194 if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER + 2) {
4195 // 2 means params number Offset
4196 paramsMap[ACTION_ARGU_SELECT_TEXT_INFORWARD] = params[EVENT_DUMP_ACTION_PARAM_INDEX + 2];
4197 }
4198 }
4199
4200 if (op == ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT || op == ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT) {
4201 if (params.size() == EVENT_DUMP_PARAM_LENGTH_UPPER) {
4202 paramsMap[ACTION_ARGU_MOVE_UNIT] = std::to_string(TextMoveUnit::STEP_CHARACTER);
4203 }
4204 paramsMap[ACTION_ARGU_MOVE_UNIT] = std::to_string(TextMoveUnit::STEP_CHARACTER);
4205 }
4206
4207 if (op == ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION) {
4208 paramsMap[ACTION_ARGU_SET_OFFSET] = params[EVENT_DUMP_ACTION_PARAM_INDEX];
4209 }
4210
4211 if ((op == ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD) ||
4212 (op == ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD)) {
4213 if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER) {
4214 paramsMap = { { ACTION_ARGU_SCROLL_STUB, params[EVENT_DUMP_ACTION_PARAM_INDEX] } };
4215 }
4216 }
4217
4218 if (op == ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK) {
4219 if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER) {
4220 paramsMap = { { ACTION_ARGU_SPAN_ID, params[EVENT_DUMP_ACTION_PARAM_INDEX] } };
4221 }
4222 }
4223 }
4224
TransferExecuteAction(int64_t elementId,const RefPtr<NG::FrameNode> & node,const std::map<std::string,std::string> & actionArguments,ActionType action,int64_t uiExtensionOffset)4225 bool TransferExecuteAction(int64_t elementId, const RefPtr<NG::FrameNode>& node,
4226 const std::map<std::string, std::string>& actionArguments,
4227 ActionType action, int64_t uiExtensionOffset)
4228 {
4229 bool isExecuted = false;
4230 if ((uiExtensionOffset + 1) > NG::UI_EXTENSION_OFFSET_MIN) {
4231 isExecuted = node->TransferExecuteAction(
4232 elementId, actionArguments, static_cast<int>(action),
4233 uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
4234 }
4235 return isExecuted;
4236 }
4237
GetPipelineByWindowId(uint32_t windowId)4238 RefPtr<NG::PipelineContext> JsAccessibilityManager::GetPipelineByWindowId(uint32_t windowId)
4239 {
4240 auto mainPipeline = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
4241 if (mainPipeline!= nullptr && mainPipeline->GetWindowId() == windowId) {
4242 return mainPipeline;
4243 }
4244 for (auto subPipelineWeak : GetSubPipelineContexts()) {
4245 auto subContextNG = AceType::DynamicCast<NG::PipelineContext>(subPipelineWeak.Upgrade());
4246 if (subContextNG!= nullptr && subContextNG->GetWindowId() == windowId) {
4247 return subContextNG;
4248 }
4249 }
4250 if (GetWindowId() == windowId) {
4251 return mainPipeline;
4252 }
4253 return nullptr;
4254 }
4255
4256 // DFX related
4257 namespace {
4258
CheckAndGetEventTestArgument(std::vector<std::string>::const_iterator start,const std::vector<std::string> & params,DumpInfoArgument & argument)4259 bool CheckAndGetEventTestArgument(std::vector<std::string>::const_iterator start,
4260 const std::vector<std::string>& params, DumpInfoArgument& argument)
4261 {
4262 auto arg = start;
4263 argument.mode = DumpMode::EVENT_TEST;
4264 constexpr int32_t NUM_EVENT_DIMENSION = 2;
4265 if (std::distance(arg, params.end()) <= NUM_EVENT_DIMENSION) {
4266 DumpLog::GetInstance().Print(std::string("Error: --event-test is used to send event with node ") +
4267 "need elementId and eventId, e.g. '--event-test ${elementId} ${eventId}'!");
4268 return false;
4269 }
4270 ++arg;
4271 argument.nodeId = StringUtils::StringToLongInt(*arg);
4272 ++arg;
4273 argument.eventId = StringUtils::StringToInt(*arg);
4274 return true;
4275 }
4276
CheckAndGetHoverTestArgument(std::vector<std::string>::const_iterator start,const std::vector<std::string> & params,DumpInfoArgument & argument)4277 bool CheckAndGetHoverTestArgument(std::vector<std::string>::const_iterator start,
4278 const std::vector<std::string>& params, DumpInfoArgument& argument)
4279 {
4280 auto arg = start;
4281 argument.mode = DumpMode::HOVER_TEST;
4282 static constexpr int32_t NUM_POINT_DIMENSION = 2;
4283 if (std::distance(arg, params.end()) <= NUM_POINT_DIMENSION) {
4284 DumpLog::GetInstance().Print(std::string("Error: --hover-test is used to get nodes at a point ") +
4285 "relative to the root node, e.g. '--hover-test ${x} ${y}'!");
4286 return false;
4287 }
4288 ++arg;
4289 argument.pointX = StringUtils::StringToInt(*arg);
4290 ++arg;
4291 argument.pointY = StringUtils::StringToInt(*arg);
4292 return true;
4293 }
4294
DumpProcessEmbedSearchParameters(const std::vector<std::string> & params,int64_t & nodeId,SearchSurfaceIdType & searchType)4295 bool DumpProcessEmbedSearchParameters(
4296 const std::vector<std::string>& params,
4297 int64_t& nodeId,
4298 SearchSurfaceIdType& searchType)
4299 {
4300 constexpr int32_t NUM_PARAMETERS_DIMENSION = 2;
4301 if (params.size() < 1) {
4302 return false;
4303 }
4304
4305 for (auto arg = params.begin() + 1; arg != params.end(); ++arg) {
4306 // Process the embed node parameters and dump its subtree info.
4307 if (*arg == "--embed-search") {
4308 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4309 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4310 return false;
4311 }
4312 ++arg;
4313 nodeId = StringUtils::StringToLongInt(*arg);
4314 ++arg;
4315 searchType = static_cast<SearchSurfaceIdType>(StringUtils::StringToInt(*arg));
4316 return true;
4317 }
4318 }
4319 return false;
4320 }
4321
DumpProcessEmbedHoverParameters(const std::vector<std::string> & params,int64_t & nodeId,int32_t & x,int32_t & y)4322 bool DumpProcessEmbedHoverParameters(
4323 const std::vector<std::string>& params,
4324 int64_t& nodeId,
4325 int32_t& x,
4326 int32_t& y)
4327 {
4328 constexpr int32_t NUM_PARAMETERS_DIMENSION = 3;
4329 if (params.size() < 1) {
4330 return false;
4331 }
4332
4333 for (auto arg = params.begin() + 1; arg != params.end(); ++arg) {
4334 // Process the embed node parameters and hover test.
4335 if (*arg == "--embed-hover") {
4336 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4337 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4338 return false;
4339 }
4340 ++arg;
4341 nodeId = StringUtils::StringToLongInt(*arg);
4342 ++arg;
4343 x = StringUtils::StringToInt(*arg);
4344 ++arg;
4345 y = StringUtils::StringToInt(*arg);
4346 return true;
4347 }
4348 }
4349 return false;
4350 }
4351
DumpProcessSetCheckListParameters(const std::vector<std::string> & params,std::vector<uint32_t> & vec)4352 bool DumpProcessSetCheckListParameters(
4353 const std::vector<std::string>& params,
4354 std::vector<uint32_t>& vec)
4355 {
4356 if (params.size() < MIN_NUM) {
4357 return false;
4358 }
4359 auto arg = params.begin() + 1;
4360 if (*arg != "--set-whitelist") {
4361 return false;
4362 }
4363 for (++arg; arg != params.end();) {
4364 vec.emplace_back(StringUtils::StringToUint(*arg++));
4365 }
4366 return true;
4367 }
4368
DumpProcessGetCheckListParameters(const std::vector<std::string> & params)4369 bool DumpProcessGetCheckListParameters(
4370 const std::vector<std::string>& params)
4371 {
4372 if (params.size() < MIN_NUM) {
4373 return false;
4374 }
4375 auto arg = params.begin() + 1;
4376 if (*arg != "--get-whitelist") {
4377 return false;
4378 }
4379 return true;
4380 }
4381
DumpProcessSpecificSearchParameters(const std::vector<std::string> & params,int64_t & nodeId,std::string & propertyTarget,int32_t & propertyType)4382 bool DumpProcessSpecificSearchParameters(
4383 const std::vector<std::string>& params,
4384 int64_t& nodeId,
4385 std::string& propertyTarget,
4386 int32_t& propertyType)
4387 {
4388 constexpr int32_t NUM_PARAMETERS_DIMENSION = 3;
4389 if (params.size() < MIN_PARAMS_SIZE) {
4390 return false;
4391 }
4392
4393 for (auto arg = params.begin() + 1; arg != params.end(); ++arg) {
4394 if (*arg == "--specific-search") {
4395 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4396 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4397 return false;
4398 }
4399 ++arg;
4400 nodeId = StringUtils::StringToLongInt(*arg);
4401 ++arg;
4402 propertyTarget = *arg;
4403 ++arg;
4404 propertyType = StringUtils::StringToInt(*arg);
4405 return true;
4406 }
4407 }
4408 return false;
4409 }
4410 } // DFX related
4411
DumpInjectActionTest(const std::vector<std::string> & params)4412 void JsAccessibilityManager::DumpInjectActionTest(const std::vector<std::string>& params)
4413 {
4414 int64_t nodeId = 0;
4415 int32_t result = 0;
4416 InjectActionType actionType = InjectActionType::UNDEFINED_ACTION;
4417
4418 if (!AccessibilityHidumper::DumpProcessInjectActionParameters(params, nodeId, result, actionType)) {
4419 return;
4420 }
4421
4422 auto pipeline = context_.Upgrade();
4423 CHECK_NULL_VOID(pipeline);
4424 RefPtr<NG::PipelineContext> ngPipeline;
4425
4426 RefPtr<NG::FrameNode> frameNode;
4427 ngPipeline = FindPipelineByElementId(nodeId, frameNode);
4428 CHECK_NULL_VOID(ngPipeline);
4429 CHECK_NULL_VOID(frameNode);
4430 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
4431 CHECK_NULL_VOID(accessibilityProperty);
4432 if (actionType == InjectActionType::NOTIFY_CHILD_ACTION) {
4433 accessibilityProperty->SetNotifyChildAction([nodeId, result] (
4434 const RefPtr<NG::FrameNode>& node,
4435 NotifyChildActionType childActionType) {
4436 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "onNotifyChildAction callback: nodeid %{public}" \
4437 PRId64 " result %{public}d", nodeId, result);
4438 return static_cast<AccessibilityActionResult>(result);
4439 });
4440 }
4441 if (actionType == InjectActionType::SECURITY_CLICK_ACTION) {
4442 accessibilityProperty->SetSecurityClickAction (
4443 [nodeId] (const NG::SecCompEnhanceEvent& event) {
4444 std::string hmac(event.dataBuffer.begin(), event.dataBuffer.end());
4445 uint64_t time = std::chrono::duration_cast<std::chrono::milliseconds>(
4446 event.time.time_since_epoch()).count();
4447 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "onSecurityClickAction callback: nodeid %{public}" \
4448 PRId64 " hmac %{public}s timesttamp %{public}" PRId64, nodeId, hmac.c_str(), time);
4449 }
4450 );
4451 }
4452 DumpLog::GetInstance().Print(std::string("Result: inject action done"));
4453 }
4454
DumpEmbedSearchTest(const std::vector<std::string> & params)4455 void JsAccessibilityManager::DumpEmbedSearchTest(const std::vector<std::string>& params)
4456 {
4457 int64_t nodeId = 0;
4458 SearchSurfaceIdType searchType = SearchSurfaceIdType::SEARCH_ALL;
4459
4460 if (!DumpProcessEmbedSearchParameters(params, nodeId, searchType)) {
4461 return;
4462 }
4463
4464 auto pipeline = context_.Upgrade();
4465 CHECK_NULL_VOID(pipeline);
4466 RefPtr<NG::PipelineContext> ngPipeline;
4467
4468 RefPtr<NG::FrameNode> frameNode;
4469 ngPipeline = FindPipelineByElementId(nodeId, frameNode);
4470 CHECK_NULL_VOID(ngPipeline);
4471 CHECK_NULL_VOID(frameNode);
4472 auto surfaceId = GetSurfaceIdByEmbedNode(frameNode);
4473 if (surfaceId.empty()) {
4474 DumpLog::GetInstance().Print(std::string("Result: embed search not have surfaceId"));
4475 return;
4476 }
4477 std::list<AccessibilityElementInfo> infos;
4478
4479 SearchElementInfoBySurfaceId(surfaceId, ngPipeline->GetWindowId(), searchType, infos);
4480 if (infos.empty()) {
4481 DumpLog::GetInstance().Print(std::string("Result: embed search empty"));
4482 return;
4483 }
4484 auto accessibilityId = infos.front().GetAccessibilityId();
4485 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
4486 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
4487 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(
4488 accessibilityId, splitElementId, splitTreeId);
4489
4490 for (auto& info : infos) {
4491 DumpCommonPropertyNG(info, splitTreeId);
4492 }
4493 DumpLog::GetInstance().Print(0, surfaceId, infos.size());
4494 DumpLog::GetInstance().Print(std::string("Result: embed search done"));
4495 }
4496
DumpEmbedHoverTestNG(const std::vector<std::string> & params,uint32_t windowId)4497 void JsAccessibilityManager::DumpEmbedHoverTestNG(const std::vector<std::string>& params, uint32_t windowId)
4498 {
4499 int64_t rootId = INVALID_NODE_ID;
4500 int32_t x = 0;
4501 int32_t y = 0;
4502 if (!DumpProcessEmbedHoverParameters(params, rootId, x, y)) {
4503 return;
4504 }
4505
4506 auto pipeline = GetPipelineByWindowId(windowId);
4507 CHECK_NULL_VOID(pipeline);
4508 auto accessibilityManagerNG = pipeline->GetAccessibilityManagerNG();
4509 CHECK_NULL_VOID(accessibilityManagerNG);
4510 auto pipelineRoot = pipeline->GetRootElement();
4511 RefPtr<NG::FrameNode> root = nullptr;
4512 if (rootId == -1) {
4513 root = pipelineRoot;
4514 } else {
4515 root = GetFramenodeByAccessibilityId(pipelineRoot, rootId);
4516 }
4517 CHECK_NULL_VOID(root);
4518
4519 auto mainContext = context_.Upgrade();
4520 CHECK_NULL_VOID(mainContext);
4521 CommonProperty commonProperty;
4522 GenerateCommonProperty(pipeline, commonProperty, mainContext, root);
4523 AccessibilityElementInfo elementInfo;
4524 UpdateAccessibilityElementInfo(root, commonProperty, elementInfo, pipeline);
4525 x -= elementInfo.GetRectInScreen().GetLeftTopXScreenPostion();
4526 y -= elementInfo.GetRectInScreen().GetLeftTopYScreenPostion();
4527
4528 DumpLog::GetInstance().Print("Window ID: " + std::to_string(windowId));
4529 DumpLog::GetInstance().Print("Root ID: " + std::to_string(root->GetAccessibilityId()));
4530 NG::PointF hoverPoint(x, y);
4531 DumpLog::GetInstance().Print("Hover Point: " + hoverPoint.ToString());
4532 auto surfaceId = GetSurfaceIdByEmbedNode(root);
4533 if (surfaceId.empty()) {
4534 DumpLog::GetInstance().Print(std::string("Result: embed hover test not have surfaceId"));
4535 return;
4536 }
4537 DumpLog::GetInstance().Print("surfaceId: " + surfaceId);
4538
4539 TimeStamp time;
4540 NG::HandleHoverEventParam param = {
4541 hoverPoint, SourceType::TOUCH, NG::AccessibilityHoverEventType::ENTER, time, true };
4542 accessibilityManagerNG->HandleAccessibilityHoverEventBySurfaceId(surfaceId, param);
4543 }
4544
DumpSetCheckListTest(const std::vector<std::string> & params)4545 void JsAccessibilityManager::DumpSetCheckListTest(const std::vector<std::string>& params)
4546 {
4547 std::vector<uint32_t> vec;
4548 if (!DumpProcessSetCheckListParameters(params, vec)) {
4549 return;
4550 }
4551 UpdateEventWhiteList(vec);
4552 DumpLog::GetInstance().Print("white list size: " + std::to_string(eventWhiteList_.size()));
4553 DumpLog::GetInstance().Print(std::string("Result: Set White List Done"));
4554 }
4555
DumpGetCheckListTest(const std::vector<std::string> & params)4556 void JsAccessibilityManager::DumpGetCheckListTest(const std::vector<std::string>& params)
4557 {
4558 if (!DumpProcessGetCheckListParameters(params)) {
4559 return;
4560 }
4561 DumpLog::GetInstance().Print("white list size: " + std::to_string(eventWhiteList_.size()));
4562 for (const auto& event : eventWhiteList_) {
4563 DumpLog::GetInstance().Print("white list No: "+ std::to_string(event));
4564 }
4565 DumpLog::GetInstance().Print(std::string("Result: Get White List Done"));
4566 }
4567
DumpSpecificPropertySearchTest(const std::vector<std::string> & params,uint32_t windowId)4568 void JsAccessibilityManager::DumpSpecificPropertySearchTest(const std::vector<std::string>& params, uint32_t windowId)
4569 {
4570 int64_t nodeId = INVALID_NODE_ID;
4571 std::string propertyTarget;
4572 int32_t propertyType = 0;
4573 if (!DumpProcessSpecificSearchParameters(params, nodeId, propertyTarget, propertyType)) {
4574 return;
4575 }
4576
4577 if (propertyType != SEARCH_TYPE::CUSTOMID) {
4578 return;
4579 }
4580 auto pipeline = GetPipelineByWindowId(windowId);
4581 CHECK_NULL_VOID(pipeline);
4582 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
4583 CHECK_NULL_VOID(ngPipeline);
4584
4585 std::list<AccessibilityElementInfo> infos;
4586 std::list<AccessibilityElementInfo> treeInfos;
4587 SpecificPropertyParam propertyParam {
4588 .propertyTarget = propertyTarget, .propertyType = static_cast<SEARCH_TYPE>(propertyType)};
4589 SearchElementInfoByCustomIdNG(nodeId, propertyParam.propertyTarget, infos, treeInfos, ngPipeline);
4590 DumpLog::GetInstance().Print(std::string("customId search start"));
4591 DumpLog::GetInstance().Print("info size: " + std::to_string(infos.size()));
4592 for (const auto& info : infos) {
4593 DumpLog::GetInstance().Print("info Element ID: " + std::to_string(info.GetAccessibilityId()));
4594 }
4595 DumpLog::GetInstance().Print("treeInfos size: " + std::to_string(treeInfos.size()));
4596 for (const auto& treeInfo : treeInfos) {
4597 DumpLog::GetInstance().Print("treeInfo Element ID " + std::to_string(treeInfo.GetAccessibilityId()));
4598 }
4599 DumpLog::GetInstance().Print(std::string("Result: customId search done"));
4600 }
4601
DumpTreeNG(bool useWindowId,uint32_t windowId,int64_t rootId,bool isDumpSimplify)4602 void JsAccessibilityManager::DumpTreeNG(bool useWindowId, uint32_t windowId, int64_t rootId, bool isDumpSimplify)
4603 {
4604 if (!useWindowId && rootId == -1) {
4605 // used to adapt old function
4606 DumpTree(0, 0);
4607 return;
4608 }
4609
4610 auto pipeline = GetPipelineByWindowId(windowId);
4611 if (pipeline == nullptr) {
4612 DumpLog::GetInstance().Print("Error: pipeline is not found!");
4613 return;
4614 }
4615 auto rootNode = pipeline->GetRootElement();
4616 CHECK_NULL_VOID(rootNode);
4617 CommonProperty commonProperty;
4618 auto mainPipeline = context_.Upgrade();
4619 CHECK_NULL_VOID(mainPipeline);
4620 GenerateCommonProperty(pipeline, commonProperty, mainPipeline, rootNode);
4621 auto nodeId = rootId == -1 ? rootNode->GetAccessibilityId() : rootId;
4622 DumpTreeNG(rootNode, 0, nodeId, commonProperty, isDumpSimplify);
4623 }
4624
DumpHoverTestNG(uint32_t windowId,int64_t rootId,int32_t x,int32_t y,bool verbose)4625 void JsAccessibilityManager::DumpHoverTestNG(uint32_t windowId, int64_t rootId, int32_t x, int32_t y, bool verbose)
4626 {
4627 auto pipeline = GetPipelineByWindowId(windowId);
4628 CHECK_NULL_VOID(pipeline);
4629 auto accessibilityManagerNG = pipeline->GetAccessibilityManagerNG();
4630 CHECK_NULL_VOID(accessibilityManagerNG);
4631 auto pipelineRoot = pipeline->GetRootElement();
4632 RefPtr<NG::FrameNode> root = nullptr;
4633 if (rootId == -1) {
4634 root = pipelineRoot;
4635 } else {
4636 root = GetFramenodeByAccessibilityId(pipelineRoot, rootId);
4637 }
4638 CHECK_NULL_VOID(root);
4639
4640 DumpLog::GetInstance().Print("Window ID: " + std::to_string(windowId));
4641 DumpLog::GetInstance().Print("Root ID: " + std::to_string(root->GetAccessibilityId()));
4642 NG::PointF hoverPoint(x, y);
4643 DumpLog::GetInstance().Print("Hover Point: " + hoverPoint.ToString());
4644
4645 std::string summary;
4646 std::string detail;
4647 accessibilityManagerNG->HoverTestDebug(root, hoverPoint, summary, detail);
4648 DumpLog::GetInstance().Print(summary);
4649 if (verbose) {
4650 DumpLog::GetInstance().Print(detail);
4651 }
4652 }
4653
DumpProcessEventParameters(AccessibilityEvent & event,const std::vector<std::string> & params)4654 bool JsAccessibilityManager::DumpProcessEventParameters(
4655 AccessibilityEvent& event, const std::vector<std::string>& params)
4656 {
4657 constexpr int32_t NUM_PARAMETERS_DIMENSION = 1;
4658 if (params.size() < 1) {
4659 return false;
4660 }
4661 for (auto arg = params.begin() + 1; arg != params.end(); ++arg) {
4662 if (*arg == "--stackNodeId") {
4663 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4664 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4665 return false;
4666 }
4667 ++arg;
4668 event.stackNodeId = StringUtils::StringToLongInt(*arg);
4669 } else if (*arg == "--beforeText") {
4670 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4671 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4672 return false;
4673 }
4674 ++arg;
4675 event.beforeText = *arg;
4676 } else if (*arg == "--latestContent") {
4677 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4678 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4679 return false;
4680 }
4681 ++arg;
4682 event.latestContent = *arg;
4683 } else if (*arg == "--textAnnounced") {
4684 if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) {
4685 DumpLog::GetInstance().Print(std::string("Error: parameters need with data"));
4686 return false;
4687 }
4688 ++arg;
4689 event.textAnnouncedForAccessibility = *arg;
4690 }
4691 }
4692 return true;
4693 }
4694
DumpSendEventTest(int64_t nodeId,int32_t eventId,const std::vector<std::string> & params)4695 void JsAccessibilityManager::DumpSendEventTest(int64_t nodeId, int32_t eventId, const std::vector<std::string>& params)
4696 {
4697 auto pipeline = context_.Upgrade();
4698 CHECK_NULL_VOID(pipeline);
4699 RefPtr<NG::PipelineContext> ngPipeline;
4700
4701 RefPtr<NG::FrameNode> frameNode;
4702 ngPipeline = FindPipelineByElementId(nodeId, frameNode);
4703 CHECK_NULL_VOID(ngPipeline);
4704 CHECK_NULL_VOID(frameNode);
4705
4706 AccessibilityEvent accessibilityEvent;
4707 accessibilityEvent.nodeId = nodeId;
4708 accessibilityEvent.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
4709 accessibilityEvent.type = static_cast<AccessibilityEventType>(eventId);
4710 if (DumpProcessEventParameters(accessibilityEvent, params)) {
4711 SendEventToAccessibilityWithNode(accessibilityEvent, frameNode, ngPipeline);
4712 }
4713 }
4714
CheckDumpInfoParams(const std::vector<std::string> & params)4715 bool JsAccessibilityManager::CheckDumpInfoParams(const std::vector<std::string> ¶ms)
4716 {
4717 if (params.size() < 1) {
4718 return false;
4719 }
4720 const std::string firstParam = params[0];
4721 if (firstParam.compare("-inspector") != 0 && firstParam.compare("-accessibility") != 0 &&
4722 firstParam.compare("-simplify") != 0) {
4723 return false;
4724 }
4725 return true;
4726 }
4727
GetDumpInfoArgument(const std::vector<std::string> & params,DumpInfoArgument & argument)4728 bool JsAccessibilityManager::GetDumpInfoArgument(const std::vector<std::string>& params, DumpInfoArgument& argument)
4729 {
4730 if (params.size() < 1) {
4731 return false;
4732 }
4733 argument.isDumpSimplify = params[0].compare("-simplify") == 0;
4734 bool isArgument = DumpInfoParams(params, argument);
4735 return isArgument;
4736 }
4737
DumpInfoParams(const std::vector<std::string> & params,DumpInfoArgument & argument)4738 bool JsAccessibilityManager::DumpInfoParams(const std::vector<std::string>& params, DumpInfoArgument& argument)
4739 {
4740 for (auto arg = params.begin() + 1; arg != params.end(); ++arg) {
4741 if (*arg == "-w") {
4742 argument.useWindowId = true;
4743 } else if (*arg == "--root") {
4744 ++arg;
4745 if (arg == params.end()) {
4746 DumpLog::GetInstance().Print(std::string("Error: --root is used to set the root node, ") +
4747 "e.g. '--root ${AccessibilityId}'!");
4748 return false;
4749 }
4750 argument.rootId = StringUtils::StringToLongInt(*arg);
4751 } else if (*arg == "--hover-test") {
4752 if (!CheckAndGetHoverTestArgument(arg, params, argument)) {
4753 return false;
4754 }
4755 } else if (*arg == "--event-test") {
4756 return CheckAndGetEventTestArgument(arg, params, argument);
4757 } else if (*arg == "--inject-action") {
4758 argument.mode = DumpMode::INJECT_ACTION_TEST;
4759 break;
4760 } else if (*arg == "--embed-search") {
4761 argument.mode = DumpMode::EMBED_SEARCH_TEST;
4762 break;
4763 } else if (*arg == "--embed-hover") {
4764 argument.mode = DumpMode::EMBED_HOVER_TEST;
4765 break;
4766 } else if (*arg == "--set-whitelist") {
4767 argument.mode = DumpMode::SET_CHECKLIST_TEST;
4768 break;
4769 } else if (*arg == "--get-whitelist") {
4770 argument.mode = DumpMode::GET_CHECKLIST_TEST;
4771 break;
4772 } else if (*arg == "--specific-search") {
4773 argument.mode = DumpMode::SPECIFIC_SEARCH_TEST;
4774 break;
4775 } else if (*arg == "-v") {
4776 argument.verbose = true;
4777 } else if (*arg == "-json") {
4778 argument.mode = DumpMode::TREE;
4779 } else {
4780 if (HandleNodeModeParam(*arg, argument)) {
4781 break;
4782 }
4783 }
4784 }
4785 return true;
4786 }
4787
HandleNodeModeParam(const std::string & param,DumpInfoArgument & argument)4788 bool JsAccessibilityManager::HandleNodeModeParam(const std::string& param, DumpInfoArgument& argument)
4789 {
4790 if (argument.mode == DumpMode::NODE) {
4791 argument.mode = DumpMode::HANDLE_EVENT;
4792 return true;
4793 } else {
4794 argument.mode = DumpMode::NODE;
4795 argument.nodeId = StringUtils::StringToLongInt(param);
4796 return false;
4797 }
4798 }
4799
OnDumpInfoNG(const std::vector<std::string> & params,uint32_t windowId,bool hasJson)4800 void JsAccessibilityManager::OnDumpInfoNG(const std::vector<std::string>& params, uint32_t windowId, bool hasJson)
4801 {
4802 if (!CheckDumpInfoParams(params)) {
4803 DumpLog::GetInstance().Print("Error: invalid arguments!");
4804 return;
4805 }
4806 DumpInfoArgument argument;
4807 if (!GetDumpInfoArgument(params, argument)) {
4808 return;
4809 }
4810 std::vector<std::string> info;
4811 bool isChildElement = CheckIsChildElement(argument.nodeId, params, info, argument.mode, argument.rootId);
4812 if (isChildElement) {
4813 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "dump child element: %{public}" PRId64, argument.nodeId);
4814 return;
4815 }
4816 ChooseDumpEvent(params, argument, windowId, hasJson);
4817 }
4818
ChooseDumpEvent(const std::vector<std::string> & params,DumpInfoArgument & argument,uint32_t windowId,bool hasJson)4819 void JsAccessibilityManager::ChooseDumpEvent(const std::vector<std::string>& params,
4820 DumpInfoArgument& argument, uint32_t windowId, bool hasJson)
4821 {
4822 switch (argument.mode) {
4823 case DumpMode::TREE:
4824 isUseJson_ = hasJson;
4825 DumpTreeNG(argument.useWindowId, windowId, argument.rootId, argument.isDumpSimplify);
4826 break;
4827 case DumpMode::NODE:
4828 DumpPropertyNG(argument.nodeId);
4829 break;
4830 case DumpMode::HANDLE_EVENT:
4831 DumpHandleEvent(params);
4832 break;
4833 case DumpMode::HOVER_TEST:
4834 DumpHoverTestNG(windowId, argument.rootId, argument.pointX, argument.pointY, argument.verbose);
4835 break;
4836 case DumpMode::EVENT_TEST:
4837 DumpSendEventTest(argument.nodeId, argument.eventId, params);
4838 break;
4839 case DumpMode::INJECT_ACTION_TEST:
4840 DumpInjectActionTest(params);
4841 break;
4842 case DumpMode::EMBED_SEARCH_TEST:
4843 DumpEmbedSearchTest(params);
4844 break;
4845 case DumpMode::EMBED_HOVER_TEST:
4846 DumpEmbedHoverTestNG(params, windowId);
4847 break;
4848 case DumpMode::SET_CHECKLIST_TEST:
4849 DumpSetCheckListTest(params);
4850 break;
4851 case DumpMode::GET_CHECKLIST_TEST:
4852 DumpGetCheckListTest(params);
4853 break;
4854 case DumpMode::SPECIFIC_SEARCH_TEST:
4855 DumpSpecificPropertySearchTest(params, windowId);
4856 break;
4857 default:
4858 DumpLog::GetInstance().Print("Error: invalid arguments!");
4859 break;
4860 }
4861 }
4862
CheckDumpHandleEventParams(const std::vector<std::string> & params)4863 bool JsAccessibilityManager::CheckDumpHandleEventParams(const std::vector<std::string>& params)
4864 {
4865 if (params.size() > EVENT_DUMP_PARAM_LENGTH_UPPER + 1) {
4866 DumpLog::GetInstance().Print("Error: params length is illegal!");
4867 return false;
4868 }
4869 if (params[EVENT_DUMP_ORDER_INDEX] != DUMP_ORDER && params[EVENT_DUMP_ORDER_INDEX] != DUMP_INSPECTOR) {
4870 DumpLog::GetInstance().Print("Error: Unrecognized dump command for accessibility!");
4871 return false;
4872 }
4873 return true;
4874 }
4875
CheckGetActionIdAndOp(const std::vector<std::string> & params,int64_t & actionAccessibilityId,ActionType & actionOp)4876 bool JsAccessibilityManager::CheckGetActionIdAndOp(
4877 const std::vector<std::string>& params,
4878 int64_t& actionAccessibilityId,
4879 ActionType& actionOp)
4880 {
4881 if (EVENT_DUMP_ID_INDEX > params.size()) {
4882 return false;
4883 }
4884 if (EVENT_DUMP_ACTION_INDEX != std::clamp(EVENT_DUMP_ACTION_INDEX, EVENT_DUMP_ID_INDEX, params.size())) {
4885 return false;
4886 }
4887 actionAccessibilityId = StringUtils::StringToLongInt(params[EVENT_DUMP_ID_INDEX]);
4888 auto action = static_cast<AceAction>(StringUtils::StringToInt(params[EVENT_DUMP_ACTION_INDEX]));
4889 actionOp = ConvertAceAction(action);
4890 if ((actionOp != ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) &&
4891 (params.size() > EVENT_DUMP_PARAM_LENGTH_UPPER + 1)) {
4892 return false;
4893 }
4894 if (actionOp == ActionType::ACCESSIBILITY_ACTION_INVALID) {
4895 return false;
4896 }
4897 return true;
4898 }
4899
DumpHandleEvent(const std::vector<std::string> & params)4900 void JsAccessibilityManager::DumpHandleEvent(const std::vector<std::string>& params)
4901 {
4902 if (!CheckDumpHandleEventParams(params)) {
4903 return;
4904 }
4905 auto pipeline = context_.Upgrade();
4906 CHECK_NULL_VOID(pipeline);
4907 int64_t nodeId = StringUtils::StringToLongInt(params[EVENT_DUMP_ID_INDEX]);
4908
4909 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
4910 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
4911 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(nodeId, splitElementId, splitTreeId);
4912 nodeId = splitElementId;
4913
4914 auto action = static_cast<AceAction>(StringUtils::StringToInt(params[EVENT_DUMP_ACTION_INDEX]));
4915 auto op = ConvertAceAction(action);
4916 if ((op != ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) && (params.size() > EVENT_DUMP_PARAM_LENGTH_UPPER + 1)) {
4917 return DumpLog::GetInstance().Print("Error: params is illegal!");
4918 }
4919 std::map<std::string, std::string> paramsMap;
4920 ProcessParameters(op, params, paramsMap);
4921 if (AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
4922 RefPtr<NG::FrameNode> node;
4923 #ifdef WINDOW_SCENE_SUPPORTED
4924 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
4925 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
4926 CHECK_NULL_VOID(uiExtensionManager);
4927 if (uiExtensionManager->IsWrapExtensionAbilityId(nodeId)) {
4928 ExecuteActionNG(nodeId, paramsMap, op, ngPipeline, NG::UI_EXTENSION_OFFSET_MAX);
4929 return;
4930 }
4931 #endif
4932 pipeline = FindPipelineByElementId(nodeId, node);
4933 CHECK_NULL_VOID(pipeline);
4934 pipeline->GetTaskExecutor()->PostTask(
4935 [weak = WeakClaim(this), op, nodeId, paramsMap]() {
4936 auto jsAccessibilityManager = weak.Upgrade();
4937 CHECK_NULL_VOID(jsAccessibilityManager);
4938 RefPtr<NG::FrameNode> node;
4939 auto pipeline = jsAccessibilityManager->FindPipelineByElementId(nodeId, node);
4940 CHECK_NULL_VOID(pipeline);
4941 jsAccessibilityManager->ExecuteActionNG(nodeId, paramsMap, op, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
4942 },
4943 TaskExecutor::TaskType::UI, "ArkUIAccessibilityExecuteAction");
4944 return;
4945 }
4946 auto node = GetAccessibilityNodeFromPage(nodeId);
4947 CHECK_NULL_VOID(node);
4948 pipeline->GetTaskExecutor()->PostTask(
4949 [weak = WeakClaim(this), op, node, paramsMap]() {
4950 auto jsAccessibilityManager = weak.Upgrade();
4951 CHECK_NULL_VOID(jsAccessibilityManager);
4952 auto pipeline = jsAccessibilityManager->context_.Upgrade();
4953 CHECK_NULL_VOID(pipeline);
4954 jsAccessibilityManager->AccessibilityActionEvent(
4955 op, paramsMap, node, AceType::DynamicCast<PipelineContext>(pipeline));
4956 },
4957 TaskExecutor::TaskType::UI, "ArkUIAccessibilityActionEvent");
4958 }
4959
DumpProperty(const RefPtr<AccessibilityNode> & node)4960 void JsAccessibilityManager::DumpProperty(const RefPtr<AccessibilityNode>& node)
4961 {
4962 const auto& supportAceActions = node->GetSupportAction();
4963 const auto& charValue = node->GetChartValue();
4964
4965 DumpLog::GetInstance().AddDesc("ID: ", node->GetNodeId());
4966 DumpLog::GetInstance().AddDesc("parent ID: ", node->GetParentId());
4967 DumpLog::GetInstance().AddDesc("child IDs: ", GetNodeChildIds(node));
4968 DumpLog::GetInstance().AddDesc("component type: ", node->GetTag());
4969 DumpLog::GetInstance().AddDesc("input type: ", node->GetInputType());
4970 DumpLog::GetInstance().AddDesc("text: ", node->GetText());
4971 DumpLog::GetInstance().AddDesc("width: ", node->GetWidth());
4972 DumpLog::GetInstance().AddDesc("height: ", node->GetHeight());
4973 DumpLog::GetInstance().AddDesc("left: ", node->GetLeft() + GetCardOffset().GetX());
4974 DumpLog::GetInstance().AddDesc("top: ", node->GetTop() + GetCardOffset().GetY());
4975 DumpLog::GetInstance().AddDesc("enabled: ", BoolToString(node->GetEnabledState()));
4976 DumpLog::GetInstance().AddDesc("checked: ", BoolToString(node->GetCheckedState()));
4977 DumpLog::GetInstance().AddDesc("selected: ", BoolToString(node->GetSelectedState()));
4978 DumpLog::GetInstance().AddDesc("focusable: ", BoolToString(node->GetFocusableState()));
4979 DumpLog::GetInstance().AddDesc("focused: ", BoolToString(node->GetFocusedState()));
4980 DumpLog::GetInstance().AddDesc("checkable: ", BoolToString(node->GetCheckableState()));
4981 DumpLog::GetInstance().AddDesc("clickable: ", BoolToString(node->GetClickableState()));
4982 DumpLog::GetInstance().AddDesc("long clickable: ", BoolToString(node->GetLongClickableState()));
4983 DumpLog::GetInstance().AddDesc("scrollable: ", BoolToString(node->GetScrollableState()));
4984 DumpLog::GetInstance().AddDesc("editable: ", BoolToString(node->GetEditable()));
4985 DumpLog::GetInstance().AddDesc("hint text: ", node->GetHintText());
4986 DumpLog::GetInstance().AddDesc("error text: ", node->GetErrorText());
4987 DumpLog::GetInstance().AddDesc("js component id: ", node->GetJsComponentId());
4988 DumpLog::GetInstance().AddDesc("accessibility label: ", node->GetAccessibilityLabel());
4989 DumpLog::GetInstance().AddDesc("accessibility hint: ", node->GetAccessibilityHint());
4990 DumpLog::GetInstance().AddDesc("max text length: ", node->GetMaxTextLength());
4991 DumpLog::GetInstance().AddDesc("text selection start: ", node->GetTextSelectionStart());
4992 DumpLog::GetInstance().AddDesc("text selection end: ", node->GetTextSelectionEnd());
4993 DumpLog::GetInstance().AddDesc("is multi line: ", BoolToString(node->GetIsMultiLine()));
4994 DumpLog::GetInstance().AddDesc("is password", BoolToString(node->GetIsPassword()));
4995 DumpLog::GetInstance().AddDesc("text input type: ", ConvertInputTypeToString(node->GetTextInputType()));
4996 DumpLog::GetInstance().AddDesc("min value: ", node->GetAccessibilityValue().min);
4997 DumpLog::GetInstance().AddDesc("max value: ", node->GetAccessibilityValue().max);
4998 DumpLog::GetInstance().AddDesc("current value: ", node->GetAccessibilityValue().current);
4999 DumpLog::GetInstance().AddDesc("collection info rows: ", node->GetCollectionInfo().rows);
5000 DumpLog::GetInstance().AddDesc("collection info columns: ", node->GetCollectionInfo().columns);
5001 DumpLog::GetInstance().AddDesc("collection item info, row: ", node->GetCollectionItemInfo().row);
5002 DumpLog::GetInstance().AddDesc("collection item info, column: ", node->GetCollectionItemInfo().column);
5003 DumpLog::GetInstance().AddDesc("chart has value: ", BoolToString(charValue && !charValue->empty()));
5004 DumpLog::GetInstance().AddDesc("accessibilityGroup: ", BoolToString(node->GetAccessible()));
5005 DumpLog::GetInstance().AddDesc("accessibilityImportance: ", node->GetImportantForAccessibility());
5006 DumpLog::GetInstance().AddDesc("support action: ", GetSupportAction(supportAceActions));
5007 DumpLog::GetInstance().Print(0, node->GetTag(), node->GetChildList().size());
5008 }
5009
DumpPropertyInfo(const RefPtr<NG::FrameNode> & frameNode,AccessibilityElementInfo & nodeInfo)5010 void JsAccessibilityManager::DumpPropertyInfo(
5011 const RefPtr<NG::FrameNode>& frameNode, AccessibilityElementInfo& nodeInfo)
5012 {
5013 DumpCommonPropertyNG(nodeInfo, treeId_);
5014 DumpAccessibilityPropertyNG(nodeInfo);
5015 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
5016 if (accessibilityProperty) {
5017 DumpLog::GetInstance().AddDesc("offset: ", accessibilityProperty->GetScrollOffSet());
5018 DumpLog::GetInstance().AddDesc("childTreeId: ", accessibilityProperty->GetChildTreeId());
5019 DumpLog::GetInstance().AddDesc("childWindowId: ", accessibilityProperty->GetChildWindowId());
5020 }
5021
5022 DumpLog::GetInstance().AddDesc("surfaceId: ", GetSurfaceIdByEmbedNode(frameNode));
5023 DumpLog::GetInstance().Print(0, nodeInfo.GetComponentType(), nodeInfo.GetChildCount());
5024 }
5025
DumpPropertyNG(int64_t nodeID)5026 void JsAccessibilityManager::DumpPropertyNG(int64_t nodeID)
5027 {
5028 auto pipeline = context_.Upgrade();
5029 CHECK_NULL_VOID(pipeline);
5030 RefPtr<NG::PipelineContext> ngPipeline;
5031
5032 #ifdef WINDOW_SCENE_SUPPORTED
5033 ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
5034 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
5035 CHECK_NULL_VOID(uiExtensionManager);
5036 std::list<AccessibilityElementInfo> extensionElementInfos;
5037 if (uiExtensionManager->IsWrapExtensionAbilityId(nodeID)) {
5038 SearchElementInfoByAccessibilityIdNG(
5039 nodeID, PREFETCH_RECURSIVE_CHILDREN, extensionElementInfos, ngPipeline, NG::UI_EXTENSION_OFFSET_MAX);
5040 for (auto& extensionElementInfo : extensionElementInfos) {
5041 if (nodeID == extensionElementInfo.GetAccessibilityId()) {
5042 DumpCommonPropertyNG(extensionElementInfo, treeId_);
5043 DumpAccessibilityPropertyNG(extensionElementInfo);
5044 DumpLog::GetInstance().Print(
5045 0, extensionElementInfo.GetComponentType(), extensionElementInfo.GetChildCount());
5046 return;
5047 }
5048 }
5049 }
5050 #endif
5051
5052 RefPtr<NG::FrameNode> frameNode;
5053 ngPipeline = FindPipelineByElementId(nodeID, frameNode);
5054 CHECK_NULL_VOID(ngPipeline);
5055 CHECK_NULL_VOID(frameNode);
5056
5057 CommonProperty commonProperty;
5058 GenerateCommonProperty(ngPipeline, commonProperty, pipeline, frameNode);
5059 commonProperty.checkEmbedNode = false;
5060 AccessibilityElementInfo nodeInfo;
5061 UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, ngPipeline);
5062 SetRootAccessibilityVisible(frameNode, nodeInfo);
5063 SetRootAccessibilityNextFocusId(frameNode, ngPipeline->GetRootElement(), nodeInfo);
5064 SetRootAccessibilityPreFocusId(frameNode, ngPipeline->GetRootElement(), nodeInfo,
5065 nextFocusMapWithSubWindow_[pipeline->GetInstanceId()]);
5066 if (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode)) {
5067 SearchParameter param {-1, "", PREFETCH_RECURSIVE_CHILDREN, NG::UI_EXTENSION_OFFSET_MAX};
5068 std::list<AccessibilityElementInfo> extensionElementInfos;
5069 SearchExtensionElementInfoNG(param, frameNode, extensionElementInfos, nodeInfo);
5070 }
5071 DumpPropertyInfo(frameNode, nodeInfo);
5072 }
5073
DumpProperty(const std::vector<std::string> & params)5074 void JsAccessibilityManager::DumpProperty(const std::vector<std::string>& params)
5075 {
5076 CHECK_NULL_VOID(DumpLog::GetInstance().GetDumpFile());
5077 if (params.empty()) {
5078 DumpLog::GetInstance().Print("Error: params cannot be empty!");
5079 return;
5080 }
5081 if (params.size() != PROPERTY_DUMP_PARAM_LENGTH) {
5082 DumpLog::GetInstance().Print("Error: params length is illegal!");
5083 return;
5084 }
5085 if (params[0] != DUMP_ORDER && params[0] != DUMP_INSPECTOR) {
5086 DumpLog::GetInstance().Print("Error: not accessibility dump order!");
5087 return;
5088 }
5089
5090 auto pipeline = context_.Upgrade();
5091 CHECK_NULL_VOID(pipeline);
5092
5093 if (!AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
5094 auto node = GetAccessibilityNodeFromPage(StringUtils::StringToLongInt(params[1]));
5095 if (!node) {
5096 DumpLog::GetInstance().Print("Error: can't find node with ID " + params[1]);
5097 return;
5098 }
5099 DumpProperty(node);
5100 } else {
5101 DumpPropertyNG(StringUtils::StringToLongInt(params[1]));
5102 }
5103 }
5104
DumpAccessibilityElementInfosTreeNG(std::list<AccessibilityElementInfo> & infos,int32_t depth,int64_t accessibilityId,bool isRoot)5105 static void DumpAccessibilityElementInfosTreeNG(
5106 std::list<AccessibilityElementInfo>& infos, int32_t depth, int64_t accessibilityId, bool isRoot)
5107 {
5108 AccessibilityElementInfo accessibilityInfo;
5109 for (auto& info : infos) {
5110 if (accessibilityId == info.GetAccessibilityId()) {
5111 accessibilityInfo = info;
5112 break;
5113 }
5114 }
5115 if (!isRoot) {
5116 DumpLog::GetInstance().AddDesc("ID: " + std::to_string(accessibilityInfo.GetAccessibilityId()));
5117 DumpLog::GetInstance().AddDesc("compid: " + accessibilityInfo.GetInspectorKey());
5118 DumpLog::GetInstance().AddDesc("text: " + accessibilityInfo.GetContent());
5119 DumpLog::GetInstance().AddDesc("accessibilityText: " + accessibilityInfo.GetContent());
5120 DumpLog::GetInstance().AddDesc("accessibilityGroup: ");
5121 DumpLog::GetInstance().AddDesc("accessibilityLevel: ");
5122 DumpLog::GetInstance().AddDesc("accessibilityCustomRole: " + accessibilityInfo.GetCustomComponentType());
5123 DumpLog::GetInstance().AddDesc("top: " +
5124 std::to_string(accessibilityInfo.GetRectInScreen().GetLeftTopYScreenPostion()));
5125 DumpLog::GetInstance().AddDesc("left: " +
5126 std::to_string(accessibilityInfo.GetRectInScreen().GetLeftTopXScreenPostion()));
5127 DumpLog::GetInstance().AddDesc("width: " + std::to_string(
5128 accessibilityInfo.GetRectInScreen().GetRightBottomXScreenPostion() -
5129 accessibilityInfo.GetRectInScreen().GetLeftTopXScreenPostion()));
5130 DumpLog::GetInstance().AddDesc("height: " + std::to_string(
5131 accessibilityInfo.GetRectInScreen().GetRightBottomYScreenPostion() -
5132 accessibilityInfo.GetRectInScreen().GetLeftTopYScreenPostion()));
5133 DumpLog::GetInstance().AddDesc("visible: " + std::to_string(accessibilityInfo.IsVisible()));
5134 DumpLog::GetInstance().AddDesc(
5135 "clickable: " + std::to_string(accessibilityInfo.IsClickable()));
5136 DumpLog::GetInstance().AddDesc("longclickable: " +
5137 std::to_string(accessibilityInfo.IsLongClickable()));
5138 DumpLog::GetInstance().AddDesc("checkable: " + std::to_string(accessibilityInfo.IsCheckable()));
5139 DumpLog::GetInstance().AddDesc("scrollable: " + std::to_string(accessibilityInfo.IsScrollable()));
5140 DumpLog::GetInstance().AddDesc("checked: " + std::to_string(accessibilityInfo.IsChecked()));
5141 DumpLog::GetInstance().AddDesc("hint: " + accessibilityInfo.GetHint());
5142 DumpLog::GetInstance().Print(depth, accessibilityInfo.GetComponentType(), accessibilityInfo.GetChildCount());
5143 depth ++;
5144 }
5145 for (auto child : accessibilityInfo.GetChildIds()) {
5146 DumpAccessibilityElementInfosTreeNG(infos, depth, child, false);
5147 }
5148 }
5149
DumpTreeNodeInfoNG(const RefPtr<NG::FrameNode> & node,int32_t depth,const CommonProperty & commonProperty,int32_t childSize)5150 static void DumpTreeNodeInfoNG(
5151 const RefPtr<NG::FrameNode>& node, int32_t depth, const CommonProperty& commonProperty, int32_t childSize)
5152 {
5153 NG::RectF rect = node->GetTransformRectRelativeToWindow(true);
5154 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
5155 DumpLog::GetInstance().AddDesc("ID: " + std::to_string(node->GetAccessibilityId()));
5156 DumpLog::GetInstance().AddDesc("compid: " + node->GetInspectorId().value_or(""));
5157 if (accessibilityProperty) {
5158 DumpLog::GetInstance().AddDesc("text: " + accessibilityProperty->GetGroupText());
5159 DumpLog::GetInstance().AddDesc("accessibilityText: " + accessibilityProperty->GetAccessibilityText());
5160 DumpLog::GetInstance().AddDesc(
5161 "accessibilityGroup: " + std::to_string(accessibilityProperty->IsAccessibilityGroup()));
5162 DumpLog::GetInstance().AddDesc("accessibilityLevel: " + accessibilityProperty->GetAccessibilityLevel());
5163 DumpLog::GetInstance().AddDesc(
5164 "accessibilityCustomRole: " + accessibilityProperty->GetAccessibilityCustomRole());
5165 }
5166 DumpLog::GetInstance().AddDesc("top: " + std::to_string(rect.Top() + commonProperty.windowTop));
5167 DumpLog::GetInstance().AddDesc("left: " + std::to_string(rect.Left() + commonProperty.windowLeft));
5168 DumpLog::GetInstance().AddDesc("width: " + std::to_string(rect.Width()));
5169 DumpLog::GetInstance().AddDesc("height: " + std::to_string(rect.Height()));
5170 DumpLog::GetInstance().AddDesc("visible: " + std::to_string(node->IsVisible()));
5171 auto eventHub = node->GetOrCreateEventHub<NG::EventHub>();
5172 if (eventHub) {
5173 auto gestureEventHub = eventHub->GetGestureEventHub();
5174 DumpLog::GetInstance().AddDesc(
5175 "clickable: " + std::to_string(gestureEventHub ? gestureEventHub->IsAccessibilityClickable() : false));
5176 DumpLog::GetInstance().AddDesc("longclickable: " +
5177 std::to_string(gestureEventHub ? gestureEventHub->IsAccessibilityLongClickable() : false));
5178 }
5179 if (accessibilityProperty) {
5180 DumpLog::GetInstance().AddDesc("checkable: " + std::to_string(accessibilityProperty->IsCheckable()));
5181 DumpLog::GetInstance().AddDesc("scrollable: " + std::to_string(accessibilityProperty->IsScrollable()));
5182 DumpLog::GetInstance().AddDesc("checked: " + std::to_string(accessibilityProperty->IsChecked()));
5183 DumpLog::GetInstance().AddDesc("hint: " + accessibilityProperty->GetHintText());
5184 DumpLog::GetInstance().AddDesc("childTree: " + std::to_string(accessibilityProperty->GetChildTreeId()));
5185 }
5186 DumpLog::GetInstance().Print(depth, node->GetTag(), childSize);
5187 }
5188
DumpTreeNodeSafeAreaInfoNg(const RefPtr<NG::FrameNode> & node)5189 void JsAccessibilityManager::DumpTreeNodeSafeAreaInfoNg(const RefPtr<NG::FrameNode>& node)
5190 {
5191 auto layoutProperty = node->GetLayoutProperty();
5192 if (layoutProperty) {
5193 auto&& opts = layoutProperty->GetSafeAreaExpandOpts();
5194 if (opts && opts->type != NG::SAFE_AREA_TYPE_NONE && opts->edges != NG::SAFE_AREA_EDGE_NONE) {
5195 DumpLog::GetInstance().AddDesc(opts->ToString());
5196 }
5197 if (layoutProperty->GetSafeAreaInsets()) {
5198 DumpLog::GetInstance().AddDesc(layoutProperty->GetSafeAreaInsets()->ToString());
5199 }
5200 }
5201 if (node->SelfOrParentExpansive()) {
5202 auto geometryNode = node->GetGeometryNode();
5203 if (geometryNode) {
5204 auto rect = geometryNode->GetSelfAdjust();
5205 auto parentRect = geometryNode->GetParentAdjust();
5206 bool isDefaultSize = NearZero(rect.GetX(), 0.0) && NearZero(rect.GetY(), 0.0) &&
5207 NearZero(rect.Width(), 0.0) && NearZero(rect.Height(), 0.0);
5208 bool isParentDefaultSize = NearZero(parentRect.GetX(), 0.0) && NearZero(parentRect.GetY(), 0.0) &&
5209 NearZero(parentRect.Width(), 0.0) && NearZero(parentRect.Height(), 0.0);
5210 if (!isDefaultSize && !isParentDefaultSize) {
5211 DumpLog::GetInstance().AddDesc(std::string("selfAdjust: ")
5212 .append(rect.ToString().c_str())
5213 .append(",parentAdjust")
5214 .append(parentRect.ToString().c_str()));
5215 }
5216 }
5217 }
5218 CHECK_NULL_VOID(node->GetTag() == V2::PAGE_ETS_TAG);
5219 auto pipeline = node->GetContext();
5220 CHECK_NULL_VOID(pipeline);
5221 auto manager = pipeline->GetSafeAreaManager();
5222 CHECK_NULL_VOID(manager);
5223 if (!manager->IsIgnoreSafeArea() && !manager->IsNeedAvoidWindow() && !manager->IsFullScreen() &&
5224 !manager->KeyboardSafeAreaEnabled() && !manager->GetUseCutout()) {
5225 DumpLog::GetInstance().AddDesc(
5226 std::string("ignoreSafeArea: ")
5227 .append(std::to_string(manager->IsIgnoreSafeArea()))
5228 .append(std::string(", isNeedAvoidWindow: ").c_str())
5229 .append(std::to_string(manager->IsNeedAvoidWindow()))
5230 .append(std::string(", IisFullScreen: ").c_str())
5231 .append(std::to_string(manager->IsFullScreen()))
5232 .append(std::string(", isKeyboardAvoidMode: ").c_str())
5233 .append(std::to_string(static_cast<int32_t>(manager->GetKeyBoardAvoidMode())))
5234 .append(std::string(", isUseCutout: ").c_str())
5235 .append(std::to_string(manager->GetUseCutout())));
5236 }
5237 }
5238
DumpPadding(const std::unique_ptr<NG::PaddingProperty> & padding,std::string label)5239 void JsAccessibilityManager::DumpPadding(const std::unique_ptr<NG::PaddingProperty>& padding, std::string label)
5240 {
5241 NG::CalcLength defaultValue = NG::CalcLength(Dimension(0));
5242 auto left = padding->left.value_or(defaultValue).GetDimension().Value();
5243 auto right = padding->right.value_or(defaultValue).GetDimension().Value();
5244 auto top = padding->top.value_or(defaultValue).GetDimension().Value();
5245 auto bottom = padding->bottom.value_or(defaultValue).GetDimension().Value();
5246 if (!NearZero(left, 0.0) && !NearZero(right, 0.0) && !NearZero(top, 0.0) && !NearZero(bottom, 0.0)) {
5247 DumpLog::GetInstance().AddDesc(label.append(padding->ToString().c_str()));
5248 }
5249 }
5250
DumpBorder(const std::unique_ptr<NG::BorderWidthProperty> & border,std::string label)5251 void JsAccessibilityManager::DumpBorder(const std::unique_ptr<NG::BorderWidthProperty>& border, std::string label)
5252 {
5253 Dimension defaultValue(0);
5254 auto left = border->leftDimen.value_or(defaultValue).Value();
5255 auto right = border->rightDimen.value_or(defaultValue).Value();
5256 auto top = border->topDimen.value_or(defaultValue).Value();
5257 auto bottom = border->bottomDimen.value_or(defaultValue).Value();
5258 if (!NearZero(left, 0.0) && !NearZero(right, 0.0) && !NearZero(top, 0.0) && !NearZero(bottom, 0.0)) {
5259 DumpLog::GetInstance().AddDesc(label.append(border->ToString().c_str()));
5260 }
5261 }
5262
DumpTreeNodeCommonInfoNg(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty)5263 void JsAccessibilityManager::DumpTreeNodeCommonInfoNg(
5264 const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty)
5265 {
5266 DumpLog::GetInstance().AddDesc("ID: " + std::to_string(node->GetAccessibilityId()));
5267 auto renderContext = node->GetRenderContext();
5268 if (renderContext) {
5269 auto backgroundColor = renderContext->GetBackgroundColor();
5270 if (backgroundColor && backgroundColor->ColorToString().compare("#00000000") != 0) {
5271 DumpLog::GetInstance().AddDesc("BackgroundColor: " + backgroundColor->ColorToString());
5272 }
5273 DumpLog::GetInstance().AddDesc(std::string("PaintRectWithoutTransform: ")
5274 .append(renderContext->GetPaintRectWithoutTransform().ToString()));
5275 }
5276 NG::RectF rect = node->GetTransformRectRelativeToWindow(true);
5277 auto top = rect.Top() + commonProperty.windowTop;
5278 auto left = rect.Left() + commonProperty.windowLeft;
5279 if (!NearZero(top, 0.0) && !NearZero(left, 0.0)) {
5280 DumpLog::GetInstance().AddDesc("top: " + std::to_string(top));
5281 DumpLog::GetInstance().AddDesc("left: " + std::to_string(left));
5282 }
5283 DumpLog::GetInstance().AddDesc("width: " + std::to_string(rect.Width()));
5284 DumpLog::GetInstance().AddDesc("height: " + std::to_string(rect.Height()));
5285 auto layoutProperty = node->GetLayoutProperty();
5286 if (layoutProperty) {
5287 if (!node->IsVisible() && layoutProperty->GetVisibility().has_value()) {
5288 DumpLog::GetInstance().AddDesc(
5289 "visible: " + std::to_string(static_cast<int32_t>(layoutProperty->GetVisibility().value())));
5290 }
5291 auto& padding = layoutProperty->GetPaddingProperty();
5292 if (padding) {
5293 DumpPadding(padding, std::string("Padding: "));
5294 }
5295 auto& safeAreaPadding = layoutProperty->GetSafeAreaPaddingProperty();
5296 if (safeAreaPadding) {
5297 DumpPadding(safeAreaPadding, std::string("SafeAreaPadding: "));
5298 }
5299 auto& margin = layoutProperty->GetMarginProperty();
5300 if (margin) {
5301 DumpPadding(margin, std::string("Margin: "));
5302 }
5303 auto& border = layoutProperty->GetBorderWidthProperty();
5304 if (border) {
5305 DumpBorder(border, std::string("Border: "));
5306 }
5307 auto layoutRect = layoutProperty->GetLayoutRect();
5308 if (layoutRect) {
5309 DumpLog::GetInstance().AddDesc(std::string("LayoutRect: ").append(layoutRect.value().ToString().c_str()));
5310 }
5311 }
5312 }
5313
DumpTreeNodeSimplifyInfoNG(const RefPtr<NG::FrameNode> & node,int32_t depth,const CommonProperty & commonProperty,int32_t childSize)5314 void JsAccessibilityManager::DumpTreeNodeSimplifyInfoNG(
5315 const RefPtr<NG::FrameNode>& node, int32_t depth, const CommonProperty& commonProperty, int32_t childSize)
5316 {
5317 DumpTreeNodeCommonInfoNg(node, commonProperty);
5318 DumpTreeNodeSafeAreaInfoNg(node);
5319 DumpLog::GetInstance().Print(depth, node->GetTag(), childSize);
5320 }
5321
DumpTreeAccessibilityNodeNG(const RefPtr<NG::UINode> & uiNodeParent,int32_t depth,int64_t nodeID,const CommonProperty & commonProperty)5322 void JsAccessibilityManager::DumpTreeAccessibilityNodeNG(const RefPtr<NG::UINode>& uiNodeParent, int32_t depth,
5323 int64_t nodeID, const CommonProperty& commonProperty)
5324 {
5325 CHECK_NULL_VOID(uiNodeParent);
5326 auto virtualFrameNode = AceType::DynamicCast<NG::FrameNode>(uiNodeParent);
5327 auto uiNodeChildren = uiNodeParent->GetChildren(true);
5328 auto vNode = GetFramenodeByAccessibilityId(virtualFrameNode, nodeID);
5329 if (!vNode) {
5330 if (uiNodeChildren.size() == 0) {
5331 return;
5332 }
5333 }
5334 std::vector<std::pair<int64_t, int32_t>> childrenIdInfo;
5335 for (const auto& item : uiNodeChildren) {
5336 GetFrameNodeChildren(item, childrenIdInfo, commonProperty);
5337 }
5338 if (vNode != nullptr) {
5339 DumpTreeNodeInfoNG(vNode, depth + 1, commonProperty, childrenIdInfo.size());
5340 }
5341 for (const auto& item : uiNodeChildren) {
5342 DumpTreeAccessibilityNodeNG(item, depth + 1, item->GetAccessibilityId(), commonProperty);
5343 }
5344 }
5345
DumpTreeNG(const RefPtr<NG::FrameNode> & parent,int32_t depth,int64_t nodeID,const CommonProperty & commonProperty,bool isDumpSimplify)5346 void JsAccessibilityManager::DumpTreeNG(const RefPtr<NG::FrameNode>& parent, int32_t depth,
5347 int64_t nodeID, const CommonProperty& commonProperty, bool isDumpSimplify)
5348 {
5349 auto node = GetFramenodeByAccessibilityId(parent, nodeID);
5350 if (!node) {
5351 DumpLog::GetInstance().Print("Error: failed to get accessibility node with ID " + std::to_string(nodeID));
5352 return;
5353 }
5354 if (!node->IsActive()) {
5355 return;
5356 }
5357 std::vector<std::pair<int64_t, int32_t>> childrenIdInfo;
5358 for (const auto& item : node->GetChildren(true)) {
5359 GetFrameNodeChildren(item, childrenIdInfo, commonProperty);
5360 }
5361
5362 auto overlayNode = node->GetOverlayNode();
5363 if (overlayNode) {
5364 GetFrameNodeChildren(overlayNode, childrenIdInfo, commonProperty);
5365 }
5366
5367 if (isDumpSimplify) {
5368 DumpTreeNodeSimplifyInfoNG(node, depth, commonProperty, childrenIdInfo.size());
5369 } else if (!isUseJson_) {
5370 DumpTreeNodeInfoNG(node, depth, commonProperty, childrenIdInfo.size());
5371 } else {
5372 DumpTreeNodeInfoInJson(node, depth, commonProperty, childrenIdInfo.size());
5373 }
5374 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
5375 auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
5376 bool hasVirtualNode = false;
5377 if (uiVirtualNode != nullptr) {
5378 auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
5379 CHECK_NULL_VOID(virtualNode);
5380 hasVirtualNode = true;
5381 DumpTreeAccessibilityNodeNG(uiVirtualNode, depth+1, virtualNode->GetAccessibilityId(), commonProperty);
5382 }
5383 if (IsExtensionComponent(node) && !IsUIExtensionShowPlaceholder(node)) {
5384 std::list<AccessibilityElementInfo> extensionElementInfos;
5385 auto pipeline = context_.Upgrade();
5386 CHECK_NULL_VOID(pipeline);
5387 SearchElementInfoByAccessibilityIdNG(
5388 node->GetAccessibilityId(), PREFETCH_RECURSIVE_CHILDREN, extensionElementInfos,
5389 pipeline, NG::UI_EXTENSION_OFFSET_MAX);
5390 if (!extensionElementInfos.empty()) {
5391 DumpAccessibilityElementInfosTreeNG(extensionElementInfos, depth + 1, node->GetAccessibilityId(), true);
5392 }
5393 }
5394 if (!hasVirtualNode) {
5395 for (const auto& childIdPair : childrenIdInfo) {
5396 DumpTreeNG(node, depth + 1, childIdPair.first, commonProperty, isDumpSimplify);
5397 }
5398 }
5399 }
5400
DumpTree(int32_t depth,int64_t nodeID,bool isDumpSimplify)5401 void JsAccessibilityManager::DumpTree(int32_t depth, int64_t nodeID, bool isDumpSimplify)
5402 {
5403 auto pipeline = context_.Upgrade();
5404 CHECK_NULL_VOID(pipeline);
5405 if (!AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
5406 AccessibilityNodeManager::DumpTree(depth, nodeID, isDumpSimplify);
5407 } else {
5408 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
5409 auto rootNode = ngPipeline->GetRootElement();
5410 CHECK_NULL_VOID(rootNode);
5411 nodeID = rootNode->GetAccessibilityId();
5412 CommonProperty commonProperty;
5413 GenerateCommonProperty(ngPipeline, commonProperty, pipeline, rootNode);
5414 DumpTreeNG(rootNode, depth, nodeID, commonProperty, isDumpSimplify);
5415 for (const auto& subContext : GetSubPipelineContexts()) {
5416 auto subPipeline = subContext.Upgrade();
5417 ngPipeline = AceType::DynamicCast<NG::PipelineContext>(subPipeline);
5418 CHECK_NULL_CONTINUE(ngPipeline);
5419 rootNode = ngPipeline->GetRootElement();
5420 CHECK_NULL_CONTINUE(rootNode);
5421 nodeID = rootNode->GetAccessibilityId();
5422 commonProperty.windowId = static_cast<int32_t>(ngPipeline->GetWindowId());
5423 commonProperty.windowLeft = GetWindowLeft(ngPipeline->GetWindowId());
5424 commonProperty.windowTop = GetWindowTop(ngPipeline->GetWindowId());
5425 commonProperty.pageNodes.clear(); // empty means search all page
5426 commonProperty.pagePaths.clear();
5427 DumpTreeNG(rootNode, depth, nodeID, commonProperty, isDumpSimplify);
5428 }
5429 }
5430 }
5431
SetCardViewParams(const std::string & key,bool focus)5432 void JsAccessibilityManager::SetCardViewParams(const std::string& key, bool focus)
5433 {
5434 callbackKey_ = key;
5435 if (!callbackKey_.empty()) {
5436 InitializeCallback();
5437 }
5438 }
5439
UpdateViewScale()5440 void JsAccessibilityManager::UpdateViewScale()
5441 {
5442 auto context = GetPipelineContext().Upgrade();
5443 CHECK_NULL_VOID(context);
5444 float scaleX = 1.0;
5445 float scaleY = 1.0;
5446 if (context->GetViewScale(scaleX, scaleY)) {
5447 scaleX_ = scaleX;
5448 scaleY_ = scaleY;
5449 }
5450 }
5451
HandleComponentPostBinding()5452 void JsAccessibilityManager::HandleComponentPostBinding()
5453 {
5454 for (auto targetIter = nodeWithTargetMap_.begin(); targetIter != nodeWithTargetMap_.end();) {
5455 auto nodeWithTarget = targetIter->second.Upgrade();
5456 if (nodeWithTarget) {
5457 if (nodeWithTarget->GetTag() == ACCESSIBILITY_TAG_POPUP) {
5458 auto idNodeIter = nodeWithIdMap_.find(targetIter->first);
5459 if (idNodeIter != nodeWithIdMap_.end()) {
5460 auto nodeWithId = idNodeIter->second.Upgrade();
5461 if (nodeWithId) {
5462 nodeWithId->SetAccessibilityHint(nodeWithTarget->GetText());
5463 } else {
5464 nodeWithIdMap_.erase(idNodeIter);
5465 }
5466 }
5467 }
5468 ++targetIter;
5469 } else {
5470 // clear the disabled node in the maps
5471 targetIter = nodeWithTargetMap_.erase(targetIter);
5472 }
5473 }
5474
5475 // clear the disabled node in the maps
5476 for (auto idItem = nodeWithIdMap_.begin(); idItem != nodeWithIdMap_.end();) {
5477 if (!idItem->second.Upgrade()) {
5478 idItem = nodeWithIdMap_.erase(idItem);
5479 } else {
5480 ++idItem;
5481 }
5482 }
5483 }
5484
Create()5485 RefPtr<AccessibilityNodeManager> AccessibilityNodeManager::Create()
5486 {
5487 return AceType::MakeRefPtr<JsAccessibilityManager>();
5488 }
5489
GetPipelineByWindowId(const int32_t windowId)5490 RefPtr<PipelineBase> JsAccessibilityManager::GetPipelineByWindowId(const int32_t windowId)
5491 {
5492 auto context = context_.Upgrade();
5493 CHECK_NULL_RETURN(context, nullptr);
5494 if (AceType::InstanceOf<NG::PipelineContext>(context)) {
5495 CHECK_NULL_RETURN(context, nullptr);
5496 if (context->GetWindowId() == static_cast<uint32_t>(windowId)) {
5497 return context;
5498 }
5499 if (GetWindowId() == static_cast<uint32_t>(windowId)) {
5500 return context;
5501 }
5502 for (auto& subContext : GetSubPipelineContexts()) {
5503 context = subContext.Upgrade();
5504 CHECK_NULL_CONTINUE(context);
5505 if (context->GetWindowId() == static_cast<uint32_t>(windowId)) {
5506 return context;
5507 }
5508 }
5509 return nullptr;
5510 } else {
5511 return context;
5512 }
5513 }
5514
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t mode)5515 RetError JsAccessibilityManager::JsInteractionOperation::SearchElementInfoByAccessibilityId(const int64_t elementId,
5516 const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t mode)
5517 {
5518 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ArkUI search by id: %{public}" PRId64 ", mode: %{public}d",
5519 elementId, mode);
5520 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5521 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5522 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5523
5524 auto jsAccessibilityManager = GetHandler().Upgrade();
5525 if (!jsAccessibilityManager) {
5526 std::list<AccessibilityElementInfo> infos;
5527 callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
5528 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d",
5529 requestId);
5530 return RET_OK;
5531 }
5532 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5533 if (!context) {
5534 std::list<AccessibilityElementInfo> infos;
5535 callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
5536 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d",
5537 requestId);
5538 return RET_OK;
5539 }
5540 auto windowId = windowId_;
5541 context->GetTaskExecutor()->PostTask(
5542 [weak = GetHandler(), splitElementId, requestId, &callback, mode, windowId]() {
5543 auto jsAccessibilityManager = weak.Upgrade();
5544 if (!jsAccessibilityManager) {
5545 std::list<AccessibilityElementInfo> infos;
5546 callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
5547 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5548 "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d", requestId);
5549 return;
5550 }
5551 ACE_SCOPED_TRACE("SearchElementInfoByAccessibilityId");
5552 jsAccessibilityManager->SearchElementInfoByAccessibilityId(
5553 splitElementId, requestId, callback, mode, windowId);
5554 },
5555 TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoById");
5556 return RET_OK;
5557 }
5558
HandleSearchElementInfoCallback(AccessibilityElementOperatorCallback & callback,int32_t requestId)5559 void JsAccessibilityManager::JsInteractionOperation::HandleSearchElementInfoCallback(
5560 AccessibilityElementOperatorCallback& callback, int32_t requestId)
5561 {
5562 std::list<AccessibilityElementInfo> infos;
5563 std::list<AccessibilityElementInfo> treeInfos;
5564 callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
5565 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5566 "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d", requestId);
5567 }
5568
SearchElementInfoBySpecificProperty(const int64_t elementId,const SpecificPropertyParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback)5569 void JsAccessibilityManager::JsInteractionOperation::SearchElementInfoBySpecificProperty(const int64_t elementId,
5570 const SpecificPropertyParam ¶m, const int32_t requestId, AccessibilityElementOperatorCallback &callback)
5571 {
5572 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ArkUI search by id: %{public}" PRId64 ", target: %{public}s,"
5573 "type: %{public}d", elementId, param.propertyTarget.c_str(), param.propertyType);
5574
5575 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5576 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5577 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5578
5579 auto jsAccessibilityManager = GetHandler().Upgrade();
5580 if (!jsAccessibilityManager) {
5581 std::list<AccessibilityElementInfo> infos;
5582 std::list<AccessibilityElementInfo> treeInfos;
5583 callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
5584 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d",
5585 requestId);
5586 return;
5587 }
5588
5589 auto windowId = windowId_;
5590 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5591 if (!context) {
5592 std::list<AccessibilityElementInfo> infos;
5593 std::list<AccessibilityElementInfo> treeInfos;
5594 callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
5595 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d",
5596 requestId);
5597 return;
5598 }
5599 auto executor = context->GetTaskExecutor();
5600 if (!executor) {
5601 HandleSearchElementInfoCallback(callback, requestId);
5602 return;
5603 }
5604
5605 executor->PostTask(
5606 [weak = GetHandler(), splitElementId, param, requestId, &callback, windowId]() {
5607 auto jsAccessibilityManager = weak.Upgrade();
5608 if (!jsAccessibilityManager) {
5609 std::list<AccessibilityElementInfo> infos;
5610 std::list<AccessibilityElementInfo> treeInfos;
5611 callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
5612 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5613 "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d", requestId);
5614 return;
5615 }
5616 ACE_SCOPED_TRACE("SearchElementInfoBySpecificProperty");
5617 jsAccessibilityManager->SearchElementInfoBySpecificProperty(
5618 splitElementId, param, requestId, callback, windowId);
5619 },
5620 TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoByProperty");
5621 return;
5622 }
5623
5624 #ifdef WEB_SUPPORTED
5625
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback,const int32_t mode)5626 RetError JsAccessibilityManager::WebInteractionOperation::SearchElementInfoByAccessibilityId(const int64_t elementId,
5627 const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode)
5628 {
5629 uint32_t realMode = mode;
5630 if (realMode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN_REDUCED)) {
5631 realMode &= ~static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN_REDUCED);
5632 realMode |= static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN);
5633 }
5634 TAG_LOGD(AceLogTag::ACE_WEB, "search by id: %{public}" PRId64 ", mode: %{public}d",
5635 elementId, mode);
5636 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5637 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5638 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5639
5640 auto jsAccessibilityManager = GetHandler().Upgrade();
5641 CHECK_NULL_RETURN(jsAccessibilityManager, RET_OK);
5642 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5643 CHECK_NULL_RETURN(context, RET_OK);
5644 auto windowId = windowId_;
5645 auto web = webPattern_;
5646 context->GetTaskExecutor()->PostTask(
5647 [weak = GetHandler(), splitElementId, requestId, &callback, realMode, windowId, web]() {
5648 auto jsAccessibilityManager = weak.Upgrade();
5649 CHECK_NULL_VOID(jsAccessibilityManager);
5650 auto webPattern = web.Upgrade();
5651 CHECK_NULL_VOID(webPattern);
5652 ACE_SCOPED_TRACE("SearchWebElementInfoByAccessibilityId");
5653 jsAccessibilityManager->SearchWebElementInfoByAccessibilityId(
5654 splitElementId, requestId, callback, realMode, windowId, webPattern);
5655 },
5656 TaskExecutor::TaskType::UI, "ArkWebAccessibilitySearchElementInfoById");
5657 return RET_OK;
5658 }
5659
SearchElementInfoBySpecificProperty(const int64_t elementId,const SpecificPropertyParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback)5660 void JsAccessibilityManager::WebInteractionOperation::SearchElementInfoBySpecificProperty(
5661 const int64_t elementId, const SpecificPropertyParam ¶m, const int32_t requestId,
5662 AccessibilityElementOperatorCallback &callback)
5663 {
5664 std::list<AccessibilityElementInfo> infos;
5665 std::list<AccessibilityElementInfo> treeInfos;
5666 callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
5667 }
5668
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)5669 void JsAccessibilityManager::WebInteractionOperation::SearchElementInfosByText(const int64_t elementId,
5670 const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback)
5671 {
5672 }
5673
SearchDefaultFocusByWindowId(const int32_t windowId,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback,const int32_t pageId)5674 void JsAccessibilityManager::WebInteractionOperation::SearchDefaultFocusByWindowId(const int32_t windowId,
5675 const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback &callback, const int32_t pageId)
5676 {
5677 }
5678
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)5679 void JsAccessibilityManager::WebInteractionOperation::FindFocusedElementInfo(const int64_t elementId,
5680 const int32_t focusType, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback)
5681 {
5682 TAG_LOGD(AceLogTag::ACE_WEB, "find focus: %{public}" PRId64 ", focusType: %{public}d",
5683 elementId, focusType);
5684 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5685 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5686 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5687
5688 auto jsAccessibilityManager = GetHandler().Upgrade();
5689 CHECK_NULL_VOID(jsAccessibilityManager);
5690 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5691 CHECK_NULL_VOID(context);
5692 auto windowId = windowId_;
5693 auto web = webPattern_;
5694 context->GetTaskExecutor()->PostTask(
5695 [weak = GetHandler(), splitElementId, focusType, requestId, &callback, windowId, web]() {
5696 auto jsAccessibilityManager = weak.Upgrade();
5697 CHECK_NULL_VOID(jsAccessibilityManager);
5698 auto webPattern = web.Upgrade();
5699 CHECK_NULL_VOID(webPattern);
5700 ACE_SCOPED_TRACE("FindWebFocusedElementInfo");
5701 jsAccessibilityManager->FindWebFocusedElementInfo(
5702 splitElementId, focusType, requestId, callback, windowId, webPattern);
5703 },
5704 TaskExecutor::TaskType::UI, "ArkWebFindFocusedElementInfo");
5705 }
5706
FocusMoveSearch(const int64_t elementId,const int32_t direction,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)5707 void JsAccessibilityManager::WebInteractionOperation::FocusMoveSearch(const int64_t elementId, const int32_t direction,
5708 const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback)
5709 {
5710 TAG_LOGD(AceLogTag::ACE_WEB, "move search: %{public}" PRId64 ", direction: %{public}d",
5711 elementId, direction);
5712 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5713 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5714 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5715
5716 auto jsAccessibilityManager = GetHandler().Upgrade();
5717 CHECK_NULL_VOID(jsAccessibilityManager);
5718 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5719 CHECK_NULL_VOID(context);
5720 auto windowId = windowId_;
5721 auto web = webPattern_;
5722 context->GetTaskExecutor()->PostTask(
5723 [weak = GetHandler(), splitElementId, direction, requestId, &callback, windowId, web] {
5724 auto jsAccessibilityManager = weak.Upgrade();
5725 CHECK_NULL_VOID(jsAccessibilityManager);
5726 auto webPattern = web.Upgrade();
5727 CHECK_NULL_VOID(webPattern);
5728 ACE_SCOPED_TRACE("FocusMoveSearch");
5729 jsAccessibilityManager->WebFocusMoveSearch(splitElementId, direction, requestId, callback,
5730 windowId, webPattern);
5731 },
5732 TaskExecutor::TaskType::UI, "ArkWebFocusMoveSearch");
5733 }
5734
ExecuteAction(const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)5735 void JsAccessibilityManager::WebInteractionOperation::ExecuteAction(const int64_t elementId, const int32_t action,
5736 const std::map<std::string, std::string>& actionArguments, const int32_t requestId,
5737 Accessibility::AccessibilityElementOperatorCallback& callback)
5738 {
5739 TAG_LOGD(AceLogTag::ACE_WEB, "elementId: %{public}" PRId64 ", action: %{public}d", elementId, action);
5740 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5741 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5742 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5743
5744 auto jsAccessibilityManager = GetHandler().Upgrade();
5745 CHECK_NULL_VOID(jsAccessibilityManager);
5746 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5747 CHECK_NULL_VOID(context);
5748 auto actionInfo = static_cast<ActionType>(action);
5749 ActionParam param { actionInfo, actionArguments };
5750 auto windowId = windowId_;
5751 auto web = webPattern_;
5752 context->GetTaskExecutor()->PostTask(
5753 [weak = GetHandler(), splitElementId, param, requestId, &callback, windowId, web] {
5754 auto jsAccessibilityManager = weak.Upgrade();
5755 CHECK_NULL_VOID(jsAccessibilityManager);
5756 auto webPattern = web.Upgrade();
5757 CHECK_NULL_VOID(webPattern);
5758 ACE_SCOPED_TRACE("ExecuteAction");
5759 jsAccessibilityManager->ExecuteWebAction(splitElementId, param, requestId, callback, windowId, webPattern);
5760 },
5761 TaskExecutor::TaskType::UI, "ArkWebAccessibilityExecuteAction");
5762 }
5763
ClearFocus()5764 void JsAccessibilityManager::WebInteractionOperation::ClearFocus() {}
5765
SetChildTreeIdAndWinId(const int64_t nodeId,const int32_t treeId,const int32_t childWindowId)5766 void JsAccessibilityManager::WebInteractionOperation::SetChildTreeIdAndWinId(const int64_t nodeId, const int32_t treeId,
5767 const int32_t childWindowId) {}
5768
SetBelongTreeId(const int32_t treeId)5769 void JsAccessibilityManager::WebInteractionOperation::SetBelongTreeId(const int32_t treeId) {}
5770
GetCursorPosition(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback)5771 void JsAccessibilityManager::WebInteractionOperation::GetCursorPosition(
5772 const int64_t elementId, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
5773 {
5774 TAG_LOGD(AceLogTag::ACE_WEB, "GetCursorPosition id: %{public}" PRId64, elementId);
5775 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5776 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5777 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5778
5779 auto jsAccessibilityManager = GetHandler().Upgrade();
5780 CHECK_NULL_VOID(jsAccessibilityManager);
5781 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5782 CHECK_NULL_VOID(context);
5783 auto web = webPattern_;
5784 context->GetTaskExecutor()->PostTask(
5785 [weak = GetHandler(), splitElementId, requestId, &callback, web]() {
5786 auto jsAccessibilityManager = weak.Upgrade();
5787 CHECK_NULL_VOID(jsAccessibilityManager);
5788 auto webPattern = web.Upgrade();
5789 CHECK_NULL_VOID(webPattern);
5790 ACE_SCOPED_TRACE("GetWebCursorPosition");
5791 jsAccessibilityManager->GetWebCursorPosition(splitElementId, requestId, callback, webPattern);
5792 },
5793
5794 TaskExecutor::TaskType::UI, "GetWebCursorPosition");
5795 }
5796
OutsideTouch()5797 void JsAccessibilityManager::WebInteractionOperation::OutsideTouch() {}
5798 #endif
5799
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t mode,const int32_t windowId)5800 void JsAccessibilityManager::SearchElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId,
5801 AccessibilityElementOperatorCallback& callback, const int32_t mode, const int32_t windowId)
5802 {
5803 // set perf monitor
5804 HiviewDFX::PerfMonitorAdapter::GetInstance().OnSceneChanged(HiviewDFX::ACCESSIBLE_FEATURE, true);
5805 std::list<AccessibilityElementInfo> infos;
5806
5807 auto pipeline = GetPipelineByWindowId(windowId);
5808 if (pipeline) {
5809 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
5810 if (ngPipeline) {
5811 SearchElementInfoByAccessibilityIdNG(elementId, mode, infos, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
5812 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5813 "SearchElementInfoByAccessibilityIdNG info size: %{public}zu, elementId: %{public}" PRId64,
5814 infos.size(), elementId);
5815 SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
5816 return;
5817 }
5818 }
5819
5820 int64_t nodeId = elementId;
5821 if (elementId == -1) {
5822 nodeId = 0;
5823 }
5824 auto weak = WeakClaim(this);
5825 auto jsAccessibilityManager = weak.Upgrade();
5826 CHECK_NULL_VOID(jsAccessibilityManager);
5827 auto node = jsAccessibilityManager->GetAccessibilityNodeFromPage(nodeId);
5828 if (!node) {
5829 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5830 "SearchElementInfoByAccessibilityIdNG info size: %{public}zu, elementId: %{public}" PRId64,
5831 infos.size(), elementId);
5832 SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
5833 return;
5834 }
5835
5836 AccessibilityElementInfo nodeInfo;
5837 UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager, jsAccessibilityManager->windowId_);
5838 infos.push_back(nodeInfo);
5839 // cache parent/siblings/children infos
5840 UpdateCacheInfo(infos, mode, node, jsAccessibilityManager, jsAccessibilityManager->windowId_);
5841 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5842 "SearchElementInfoByAccessibilityIdNG info size: %{public}zu, elementId: %{public}" PRId64,
5843 infos.size(), elementId);
5844 SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
5845 }
5846
SearchElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,std::list<AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)5847 void JsAccessibilityManager::SearchElementInfoByAccessibilityIdNG(int64_t elementId, int32_t mode,
5848 std::list<AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context, int64_t uiExtensionOffset)
5849 {
5850 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", treeId: %{public}d, mode: %{public}d",
5851 elementId, treeId_, mode);
5852 auto mainContext = context_.Upgrade();
5853 CHECK_NULL_VOID(mainContext);
5854
5855 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5856 CHECK_NULL_VOID(ngPipeline);
5857 auto rootNode = ngPipeline->GetRootElement();
5858 CHECK_NULL_VOID(rootNode);
5859
5860 AccessibilityElementInfo nodeInfo;
5861 int64_t nodeId = elementId;
5862 if (elementId == -1) {
5863 nodeId = rootNode->GetAccessibilityId();
5864 }
5865
5866 #ifdef WINDOW_SCENE_SUPPORTED
5867 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
5868 CHECK_NULL_VOID(uiExtensionManager);
5869 if (uiExtensionManager->IsWrapExtensionAbilityId(nodeId)) {
5870 SearchParameter param {nodeId, "", mode, uiExtensionOffset};
5871 return SearchExtensionElementInfoByAccessibilityIdNG(param, rootNode, infos, context, ngPipeline);
5872 }
5873 #endif
5874
5875 auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
5876 CHECK_NULL_VOID(node);
5877 CommonProperty commonProperty;
5878 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, node);
5879 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
5880 "windowId: %{public}d, windowLeft: %{public}d, "
5881 "windowTop: %{public}d",
5882 commonProperty.windowId, commonProperty.windowLeft, commonProperty.windowTop);
5883 UpdateAccessibilityElementInfo(node, commonProperty, nodeInfo, ngPipeline);
5884 SetRootAccessibilityVisible(node, nodeInfo);
5885 SetRootAccessibilityNextFocusId(node, rootNode, nodeInfo);
5886 SetRootAccessibilityPreFocusId(node, rootNode, nodeInfo,
5887 nextFocusMapWithSubWindow_[context->GetInstanceId()]);
5888 if (IsExtensionComponent(node) && !IsUIExtensionShowPlaceholder(node)) {
5889 SearchParameter param {-1, "", mode, uiExtensionOffset};
5890 SearchExtensionElementInfoNG(param, node, infos, nodeInfo);
5891 }
5892 infos.push_back(nodeInfo);
5893 SearchParameter param {nodeId, "", mode, uiExtensionOffset};
5894 UpdateCacheInfoNG(infos, node, commonProperty, ngPipeline, param);
5895 SortExtensionAccessibilityInfo(infos, nodeInfo.GetAccessibilityId());
5896 if ((infos.size() > 0) && (uiExtensionOffset != NG::UI_EXTENSION_OFFSET_MAX) &&
5897 (infos.front().GetComponentType() != V2::ROOT_ETS_TAG) &&
5898 (infos.front().GetParentNodeId() == rootNode->GetAccessibilityId())) {
5899 infos.front().SetParent(NG::UI_EXTENSION_ROOT_ID);
5900 }
5901 UpdateWebEmbedParent(infos, node, commonProperty);
5902 }
5903
SetAccessibilityCustomId(RefPtr<NG::FrameNode> checkNode,const std::string & customId,CommonProperty & commonProperty,std::list<AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context)5904 bool JsAccessibilityManager::SetAccessibilityCustomId(RefPtr<NG::FrameNode> checkNode, const std::string &customId,
5905 CommonProperty &commonProperty, std::list<AccessibilityElementInfo> &infos, const RefPtr<PipelineBase>& context)
5906 {
5907 if (checkNode->GetInspectorId().value_or("") == customId) {
5908 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5909 CHECK_NULL_RETURN(ngPipeline, false);
5910 auto rootNode = ngPipeline->GetRootElement();
5911 CHECK_NULL_RETURN(rootNode, false);
5912 AccessibilityElementInfo nodeInfo;
5913 UpdateAccessibilityElementInfo(checkNode, commonProperty, nodeInfo, ngPipeline);
5914 SetRootAccessibilityVisible(checkNode, nodeInfo);
5915 SetRootAccessibilityNextFocusId(checkNode, rootNode, nodeInfo);
5916 SetRootAccessibilityPreFocusId(checkNode, rootNode, nodeInfo,
5917 nextFocusMapWithSubWindow_[context->GetInstanceId()]);
5918 infos.emplace_back(nodeInfo);
5919 return true;
5920 }
5921 return false;
5922 }
5923
FindUIExtensionAccessibilityElement(const RefPtr<NG::FrameNode> & checkNode,const std::string & customId,const CommonProperty & commonProperty,std::list<AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context)5924 bool JsAccessibilityManager::FindUIExtensionAccessibilityElement(const RefPtr<NG::FrameNode>& checkNode,
5925 const std::string &customId, const CommonProperty& commonProperty,
5926 std::list<AccessibilityElementInfo> &infos, const RefPtr<PipelineBase>& context)
5927 {
5928 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5929 CHECK_NULL_RETURN(ngPipeline, false);
5930 auto rootNode = ngPipeline->GetRootElement();
5931 CHECK_NULL_RETURN(rootNode, false);
5932 if (!((checkNode->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
5933 (checkNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX))) {
5934 return false;
5935 }
5936
5937 SearchParameter searchParam {
5938 .nodeId = NG::UI_EXTENSION_ROOT_ID,
5939 .mode = static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN),
5940 .uiExtensionOffset = NG::UI_EXTENSION_OFFSET_MAX,
5941 };
5942
5943 AccessibilityElementInfo parentInfo;
5944 UpdateAccessibilityElementInfo(checkNode, commonProperty, parentInfo, ngPipeline);
5945 SetRootAccessibilityVisible(checkNode, parentInfo);
5946 SetRootAccessibilityNextFocusId(checkNode, rootNode, parentInfo);
5947 SetRootAccessibilityPreFocusId(checkNode, rootNode, parentInfo,
5948 nextFocusMapWithSubWindow_[ngPipeline->GetInstanceId()]);
5949
5950 std::list<Accessibility::AccessibilityElementInfo> extensionElementInfos;
5951 NG::SearchExtensionElementInfoNG(searchParam, checkNode, extensionElementInfos, parentInfo);
5952
5953 for (auto& ueaInfo : extensionElementInfos) {
5954 if (ueaInfo.GetInspectorKey() == customId) {
5955 infos.emplace_back(ueaInfo);
5956 break;
5957 }
5958 }
5959 if (!infos.empty()) {
5960 return true;
5961 }
5962 return false;
5963 }
5964
SearchElementInfoByCustomIdNG(const int64_t elementId,const std::string & customId,std::list<AccessibilityElementInfo> & infos,std::list<AccessibilityElementInfo> & treeInfos,const RefPtr<PipelineBase> & context)5965 void JsAccessibilityManager::SearchElementInfoByCustomIdNG(const int64_t elementId, const std::string &customId,
5966 std::list<AccessibilityElementInfo> &infos, std::list<AccessibilityElementInfo> &treeInfos,
5967 const RefPtr<PipelineBase>& context)
5968 {
5969 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", customId: %{public}s",
5970 elementId, customId.c_str());
5971 auto mainContext = context_.Upgrade();
5972 CHECK_NULL_VOID(mainContext);
5973
5974 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5975 CHECK_NULL_VOID(ngPipeline);
5976 auto rootNode = ngPipeline->GetRootElement();
5977 CHECK_NULL_VOID(rootNode);
5978
5979 CommonProperty commonProperty;
5980 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, rootNode);
5981 int64_t nodeId = elementId;
5982 if (elementId == -1) {
5983 nodeId = rootNode->GetAccessibilityId();
5984 }
5985 auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
5986 CHECK_NULL_VOID(node);
5987 std::list<RefPtr<NG::FrameNode>> children { node };
5988 while (!children.empty()) {
5989 auto checkNode = children.front();
5990 children.pop_front();
5991 if (SetAccessibilityCustomId(checkNode, customId, commonProperty, infos, context)) {
5992 treeInfos.clear();
5993 break;
5994 }
5995 #ifdef WINDOW_SCENE_SUPPORTED
5996 auto isFind = FindUIExtensionAccessibilityElement(checkNode, customId, commonProperty, infos, context);
5997 if (isFind) {
5998 treeInfos.clear();
5999 break;
6000 }
6001 #endif
6002 auto accessibilityProperty = checkNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
6003 if (accessibilityProperty && accessibilityProperty->GetChildTreeId() != -1) {
6004 AccessibilityElementInfo nodeInfo;
6005 UpdateAccessibilityElementInfo(checkNode, commonProperty, nodeInfo, ngPipeline);
6006 SetRootAccessibilityVisible(checkNode, nodeInfo);
6007 SetRootAccessibilityNextFocusId(checkNode, rootNode, nodeInfo);
6008 SetRootAccessibilityPreFocusId(checkNode, rootNode, nodeInfo,
6009 nextFocusMapWithSubWindow_[context->GetInstanceId()]);
6010 treeInfos.emplace_back(nodeInfo);
6011 }
6012 GetChildrenFromFrameNode(checkNode, children, commonProperty);
6013 }
6014 }
6015
SearchExtensionElementInfoByAccessibilityIdNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,const RefPtr<NG::PipelineContext> & ngPipeline)6016 void JsAccessibilityManager::SearchExtensionElementInfoByAccessibilityIdNG(const SearchParameter& searchParam,
6017 const RefPtr<NG::FrameNode>& node, std::list<Accessibility::AccessibilityElementInfo>& infos,
6018 const RefPtr<PipelineBase>& context, const RefPtr<NG::PipelineContext>& ngPipeline)
6019 {
6020 #ifdef WINDOW_SCENE_SUPPORTED
6021 auto mainContext = context_.Upgrade();
6022 CHECK_NULL_VOID(mainContext);
6023 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6024 CHECK_NULL_VOID(uiExtensionManager);
6025 auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset, searchParam.nodeId);
6026 int64_t childWrapId = unWrapIdPair.second;
6027 int64_t uiExtensionId = unWrapIdPair.first;
6028 auto uiExtensionNode = FindNodeFromRootByExtensionId(node, uiExtensionId);
6029 CHECK_NULL_VOID(uiExtensionNode);
6030 SearchParameter param {childWrapId, "", searchParam.mode, searchParam.uiExtensionOffset};
6031 AccessibilityElementInfo nodeInfo;
6032 CommonProperty commonProperty;
6033 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, uiExtensionNode);
6034 UpdateAccessibilityElementInfo(uiExtensionNode, commonProperty, nodeInfo, ngPipeline);
6035 SearchExtensionElementInfoNG(param, uiExtensionNode, infos, nodeInfo);
6036 #endif
6037 }
6038
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,const RefPtr<NG::FrameNode> & node,int64_t offset)6039 std::list<AccessibilityElementInfo> JsAccessibilityManager::SearchElementInfosByTextNG(
6040 int64_t elementId, const std::string& text, const RefPtr<NG::FrameNode>& node, int64_t offset)
6041 {
6042 std::list<AccessibilityElementInfo> extensionElementInfo;
6043 if (NG::UI_EXTENSION_OFFSET_MIN < (offset + 1)) {
6044 node->SearchElementInfosByTextNG(elementId, text, offset, extensionElementInfo);
6045 }
6046 return extensionElementInfo;
6047 }
6048
SearchElementInfosByTextNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,const RefPtr<NG::PipelineContext> & ngPipeline)6049 void JsAccessibilityManager::SearchElementInfosByTextNG(const SearchParameter& searchParam,
6050 const RefPtr<NG::FrameNode>& node, std::list<Accessibility::AccessibilityElementInfo>& infos,
6051 const RefPtr<PipelineBase>& context, const RefPtr<NG::PipelineContext>& ngPipeline)
6052 {
6053 #ifdef WINDOW_SCENE_SUPPORTED
6054 auto mainContext = context_.Upgrade();
6055 CHECK_NULL_VOID(mainContext);
6056 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6057 CHECK_NULL_VOID(uiExtensionManager);
6058 auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset, searchParam.nodeId);
6059 int64_t childWrapId = unWrapIdPair.second;
6060 int64_t uiExtensionId = unWrapIdPair.first;
6061 std::list<AccessibilityElementInfo> extensionElementInfos;
6062 AccessibilityElementInfo nodeInfo;
6063 auto uiExtensionNode = FindNodeFromRootByExtensionId(node, uiExtensionId);
6064 CHECK_NULL_VOID(uiExtensionNode);
6065
6066 extensionElementInfos = SearchElementInfosByTextNG(
6067 childWrapId, searchParam.text, uiExtensionNode, searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
6068 if (extensionElementInfos.empty()) {
6069 return;
6070 }
6071 CommonProperty commonProperty;
6072 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, uiExtensionNode);
6073 UpdateAccessibilityElementInfo(uiExtensionNode, commonProperty, nodeInfo, ngPipeline);
6074 SetRootAccessibilityVisible(node, nodeInfo);
6075
6076 auto rootNode = ngPipeline->GetRootElement();
6077 CHECK_NULL_VOID(rootNode);
6078 SetRootAccessibilityNextFocusId(node, rootNode, nodeInfo);
6079 SetRootAccessibilityPreFocusId(node, rootNode, nodeInfo,
6080 nextFocusMapWithSubWindow_[context->GetInstanceId()]);
6081 ConvertExtensionAccessibilityNodeId(extensionElementInfos, uiExtensionNode,
6082 searchParam.uiExtensionOffset, nodeInfo);
6083 for (auto& info : extensionElementInfos) {
6084 infos.emplace_back(info);
6085 }
6086 #endif
6087 }
6088
SearchElementInfoBySpecificProperty(const int64_t elementId,const SpecificPropertyParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)6089 void JsAccessibilityManager::SearchElementInfoBySpecificProperty(const int64_t elementId,
6090 const SpecificPropertyParam ¶m, const int32_t requestId,
6091 AccessibilityElementOperatorCallback &callback, const int32_t windowId)
6092 {
6093 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", propType: %{public}d,"
6094 "propTarget: %{public}s", elementId, param.propertyType, param.propertyTarget.c_str());
6095 std::list<AccessibilityElementInfo> infos;
6096 std::list<AccessibilityElementInfo> treeInfos;
6097
6098 auto pipeline = GetPipelineByWindowId(windowId);
6099 if (pipeline) {
6100 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
6101 if (ngPipeline) {
6102 if (param.propertyType == SEARCH_TYPE::CUSTOMID) {
6103 SearchElementInfoByCustomIdNG(elementId, param.propertyTarget, infos, treeInfos, pipeline);
6104 }
6105 } else {
6106 SearchAccessibilityNodeBySpecificProperty(elementId, param, requestId, callback, windowId);
6107 }
6108 }
6109
6110 SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId);
6111 return;
6112 }
6113
FindNodeFromRootByExtensionId(const RefPtr<NG::FrameNode> & root,const int64_t uiExtensionId)6114 RefPtr<NG::FrameNode> JsAccessibilityManager::FindNodeFromRootByExtensionId(
6115 const RefPtr<NG::FrameNode>& root, const int64_t uiExtensionId)
6116 {
6117 CHECK_NULL_RETURN(root, nullptr);
6118 std::queue<RefPtr<NG::UINode>> nodes;
6119 nodes.push(root);
6120 RefPtr<NG::FrameNode> frameNode;
6121 while (!nodes.empty()) {
6122 auto current = nodes.front();
6123 nodes.pop();
6124 frameNode = AceType::DynamicCast<NG::FrameNode>(current);
6125 if (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode) &&
6126 (uiExtensionId == frameNode->GetUiExtensionId())) {
6127 return frameNode;
6128 }
6129 const auto& children = current->GetChildren(true);
6130 for (const auto& child : children) {
6131 nodes.push(child);
6132 }
6133 }
6134 return nullptr;
6135 }
6136
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)6137 void JsAccessibilityManager::SearchElementInfosByTextNG(int64_t elementId, const std::string& text,
6138 std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context,
6139 int64_t uiExtensionOffset)
6140 {
6141 auto mainContext = context_.Upgrade();
6142 CHECK_NULL_VOID(mainContext);
6143 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
6144 CHECK_NULL_VOID(ngPipeline);
6145 auto rootNode = ngPipeline->GetRootElement();
6146 CHECK_NULL_VOID(rootNode);
6147 #ifdef WINDOW_SCENE_SUPPORTED
6148 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6149 CHECK_NULL_VOID(uiExtensionManager);
6150 if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
6151 SearchParameter param {elementId, text, 0, uiExtensionOffset};
6152 SearchElementInfosByTextNG(param, rootNode, infos, context, ngPipeline);
6153 return;
6154 }
6155 #endif
6156 if (elementId == NG::UI_EXTENSION_ROOT_ID) {
6157 elementId = rootNode->GetAccessibilityId();
6158 }
6159 auto node = GetFramenodeByAccessibilityId(rootNode, elementId);
6160 CHECK_NULL_VOID(node);
6161 CommonProperty commonProperty;
6162 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, node);
6163 commonProperty.checkEmbedNode = false;
6164 nlohmann::json textJson = nlohmann::json::parse(text, nullptr, false);
6165 if (textJson.is_null() || textJson.is_discarded() || !textJson.contains("type")) {
6166 return;
6167 }
6168 if (textJson["type"] == "textType") {
6169 SearchParameter param {0, text, 0, uiExtensionOffset};
6170 FindTextByTextHint(node, infos, ngPipeline, commonProperty, param);
6171 return;
6172 }
6173 if (!textJson.contains("value")) {
6174 return;
6175 }
6176 SearchParameter param {0, textJson["value"], 0, uiExtensionOffset};
6177 FindText(node, infos, ngPipeline, commonProperty, param);
6178 }
6179
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,AccessibilityElementOperatorCallback & callback)6180 void JsAccessibilityManager::JsInteractionOperation::SearchElementInfosByText(const int64_t elementId,
6181 const std::string& text, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
6182 {
6183 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "search by text: %{public}" PRId64 ", text: %{public}s",
6184 elementId, text.c_str());
6185 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
6186 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
6187 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
6188
6189 if (text.empty()) {
6190 return;
6191 }
6192 auto jsAccessibilityManager = GetHandler().Upgrade();
6193 CHECK_NULL_VOID(jsAccessibilityManager);
6194 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
6195 CHECK_NULL_VOID(context);
6196 auto windowId = windowId_;
6197 if (context) {
6198 context->GetTaskExecutor()->PostTask(
6199 [weak = GetHandler(), splitElementId, text, requestId, &callback, windowId]() {
6200 auto jsAccessibilityManager = weak.Upgrade();
6201 CHECK_NULL_VOID(jsAccessibilityManager);
6202 ACE_SCOPED_TRACE("SearchElementInfosByText");
6203 jsAccessibilityManager->SearchElementInfosByText(
6204 splitElementId, text, requestId, callback, windowId);
6205 },
6206 TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoByText");
6207 }
6208 }
6209
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)6210 void JsAccessibilityManager::SearchElementInfosByText(const int64_t elementId, const std::string& text,
6211 const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId)
6212 {
6213 if (text.empty()) {
6214 return;
6215 }
6216
6217 if (elementId == -1) {
6218 return;
6219 }
6220
6221 std::list<AccessibilityElementInfo> infos;
6222
6223 auto pipeline = GetPipelineByWindowId(windowId);
6224 if (pipeline) {
6225 if (AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
6226 SearchElementInfosByTextNG(elementId, text, infos, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
6227 SetSearchElementInfoByTextResult(callback, std::move(infos), requestId);
6228 return;
6229 }
6230 }
6231
6232 auto weak = WeakClaim(this);
6233 auto jsAccessibilityManager = weak.Upgrade();
6234 CHECK_NULL_VOID(jsAccessibilityManager);
6235 int64_t nodeId = elementId;
6236 auto node = jsAccessibilityManager->GetAccessibilityNodeFromPage(nodeId);
6237 CHECK_NULL_VOID(node);
6238 std::list<RefPtr<AccessibilityNode>> nodeList;
6239 OHOS::Ace::Framework::FindText(node, text, nodeList);
6240 if (!nodeList.empty()) {
6241 for (const auto& node : nodeList) {
6242 AccessibilityElementInfo nodeInfo;
6243 UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager, jsAccessibilityManager->windowId_);
6244 infos.emplace_back(nodeInfo);
6245 }
6246 }
6247
6248 SetSearchElementInfoByTextResult(callback, std::move(infos), requestId);
6249 }
6250
SearchDefaultFocusByWindowId(const int32_t windowId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t pageId)6251 void JsAccessibilityManager::JsInteractionOperation::SearchDefaultFocusByWindowId(const int32_t windowId,
6252 const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t pageId)
6253 {
6254 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "search by windowId: %{public}d, pageId: %{public}d.", windowId, pageId);
6255
6256 auto jsAccessibilityManager = GetHandler().Upgrade();
6257 CHECK_NULL_VOID(jsAccessibilityManager);
6258 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
6259 CHECK_NULL_VOID(context);
6260 context->GetTaskExecutor()->PostTask(
6261 [weak = GetHandler(), windowId, pageId, requestId, &callback]() {
6262 auto jsAccessibilityManager = weak.Upgrade();
6263 CHECK_NULL_VOID(jsAccessibilityManager);
6264 ACE_SCOPED_TRACE("SearchDefaultFocusByWindowId");
6265 jsAccessibilityManager->SearchDefaultFocusByWindowId(
6266 windowId, pageId, requestId, callback);
6267 },
6268 TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchDefaultFocusByWindowId");
6269 }
6270
SearchDefaultFocusByWindowId(const int32_t windowId,int32_t pageId,const int32_t requestId,AccessibilityElementOperatorCallback & callback)6271 void JsAccessibilityManager::SearchDefaultFocusByWindowId(const int32_t windowId, int32_t pageId,
6272 const int32_t requestId, AccessibilityElementOperatorCallback& callback)
6273 {
6274 std::list<AccessibilityElementInfo> infos;
6275
6276 auto pipeline = GetPipelineByWindowId(windowId);
6277 if (pipeline) {
6278 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
6279 if (ngPipeline) {
6280 SearchDefaultFocusByWindowIdNG(pageId, infos, pipeline);
6281 SetSearchDefaultFocusByWindowIdResult(callback, std::move(infos), requestId);
6282 return;
6283 }
6284 }
6285
6286 auto defaultFocusNodeList = GetDefaultFocusList();
6287 for (const auto& defaultFocusNode : defaultFocusNodeList) {
6288 auto frameNode = defaultFocusNode.Upgrade();
6289 if (frameNode && frameNode->GetPageId() == pageId) {
6290 auto node = GetAccessibilityNodeFromPage(frameNode->GetAccessibilityId());
6291 CHECK_NULL_CONTINUE(node);
6292 AccessibilityElementInfo nodeInfo;
6293 UpdateAccessibilityNodeInfo(node, nodeInfo, Claim(this), windowId_);
6294 infos.emplace_back(nodeInfo);
6295 }
6296 }
6297 SetSearchDefaultFocusByWindowIdResult(callback, std::move(infos), requestId);
6298 }
6299
SearchDefaultFocusByWindowIdNG(const int32_t pageId,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context)6300 void JsAccessibilityManager::SearchDefaultFocusByWindowIdNG(const int32_t pageId,
6301 std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context)
6302 {
6303 auto mainContext = context_.Upgrade();
6304 CHECK_NULL_VOID(mainContext);
6305 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
6306 CHECK_NULL_VOID(ngPipeline);
6307
6308 for (const auto& defaultFocusNode : defaultFocusList_) {
6309 auto node = defaultFocusNode.Upgrade();
6310 if (node && node->GetPageId() == pageId) {
6311 AccessibilityElementInfo nodeInfo;
6312
6313 CommonProperty commonProperty;
6314 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, node);
6315 UpdateAccessibilityElementInfo(node, commonProperty, nodeInfo, ngPipeline);
6316 infos.emplace_back(nodeInfo);
6317 }
6318 }
6319 }
6320
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,AccessibilityElementOperatorCallback & callback)6321 void JsAccessibilityManager::JsInteractionOperation::FindFocusedElementInfo(const int64_t elementId,
6322 const int32_t focusType, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
6323 {
6324 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "find focus: %{public}" PRId64 ", focusType: %{public}d",
6325 elementId, focusType);
6326 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
6327 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
6328 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
6329
6330 auto jsAccessibilityManager = GetHandler().Upgrade();
6331 CHECK_NULL_VOID(jsAccessibilityManager);
6332 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
6333 CHECK_NULL_VOID(context);
6334 auto windowId = windowId_;
6335 context->GetTaskExecutor()->PostTask(
6336 [weak = GetHandler(), splitElementId, focusType, requestId, &callback, windowId]() {
6337 auto jsAccessibilityManager = weak.Upgrade();
6338 CHECK_NULL_VOID(jsAccessibilityManager);
6339 ACE_SCOPED_TRACE("FindFocusedElementInfo");
6340 jsAccessibilityManager->FindFocusedElementInfo(splitElementId, focusType, requestId, callback, windowId);
6341 },
6342 TaskExecutor::TaskType::UI, "ArkUIAccessibilityFindFocusedElementInfo");
6343 }
6344
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)6345 void JsAccessibilityManager::FindFocusedElementInfo(const int64_t elementId, const int32_t focusType,
6346 const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId)
6347 {
6348 AccessibilityElementInfo nodeInfo;
6349 if (focusType != FOCUS_TYPE_INPUT && focusType != FOCUS_TYPE_ACCESSIBILITY) {
6350 nodeInfo.SetValidElement(false);
6351 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
6352 return;
6353 }
6354
6355 auto context = GetPipelineByWindowId(windowId);
6356 if (!context) {
6357 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
6358 return;
6359 }
6360
6361 if (AceType::InstanceOf<NG::PipelineContext>(context)) {
6362 FindFocusedElementInfoNG(elementId, focusType, nodeInfo, context, NG::UI_EXTENSION_OFFSET_MAX);
6363 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
6364 return;
6365 }
6366
6367 int64_t nodeId = static_cast<int64_t>(elementId);
6368 if (elementId == -1) {
6369 nodeId = 0;
6370 }
6371
6372 auto node = GetAccessibilityNodeFromPage(nodeId);
6373 if (!node) {
6374 nodeInfo.SetValidElement(false);
6375 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
6376 return;
6377 }
6378
6379 RefPtr<AccessibilityNode> resultNode = nullptr;
6380 bool status = false;
6381 if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
6382 status = FindAccessibilityFocus(node, resultNode);
6383 }
6384 if (focusType == FOCUS_TYPE_INPUT) {
6385 status = FindInputFocus(node, resultNode);
6386 }
6387
6388 if ((status) && (resultNode != nullptr)) {
6389 UpdateAccessibilityNodeInfo(resultNode, nodeInfo, Claim(this), windowId_);
6390 }
6391
6392 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
6393 }
6394
FindFocusedElementInfoNG(int64_t elementId,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const int64_t uiExtensionOffset)6395 void JsAccessibilityManager::FindFocusedElementInfoNG(int64_t elementId, int32_t focusType,
6396 Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
6397 const int64_t uiExtensionOffset)
6398 {
6399 auto mainContext = context_.Upgrade();
6400 CHECK_NULL_VOID(mainContext);
6401 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
6402 CHECK_NULL_VOID(ngPipeline);
6403 auto rootNode = ngPipeline->GetRootElement();
6404 CHECK_NULL_VOID(rootNode);
6405 #ifdef WINDOW_SCENE_SUPPORTED
6406 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6407 CHECK_NULL_VOID(uiExtensionManager);
6408 if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
6409 SearchParameter param {elementId, "", focusType, uiExtensionOffset};
6410 return FindFocusedExtensionElementInfoNG(param, info, context, rootNode);
6411 }
6412 #endif
6413 int64_t nodeId = elementId;
6414 if (elementId == -1) {
6415 nodeId = rootNode->GetAccessibilityId();
6416 }
6417 auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
6418 if (!node) {
6419 return info.SetValidElement(false);
6420 }
6421 if (IsExtensionComponent(node) && !IsUIExtensionShowPlaceholder(node)) {
6422 SearchParameter transferSearchParam {NG::UI_EXTENSION_ROOT_ID, "", focusType, uiExtensionOffset};
6423 OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(transferSearchParam, node, info);
6424 return SetUiExtensionAbilityParentIdForFocus(node, uiExtensionOffset, info);
6425 }
6426 RefPtr<NG::FrameNode> resultNode;
6427 if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
6428 resultNode = FindAccessibilityFocus(node, focusType, info, uiExtensionOffset, context, currentFocusNodeId_);
6429 }
6430 if (focusType == FOCUS_TYPE_INPUT) {
6431 resultNode = FindInputFocus(node, focusType, info, uiExtensionOffset, context);
6432 }
6433 if ((!resultNode) || (IsExtensionComponent(resultNode) && !IsUIExtensionShowPlaceholder(resultNode))) {
6434 return;
6435 }
6436 CommonProperty commonProperty;
6437 GenerateCommonProperty(ngPipeline, commonProperty, mainContext, resultNode);
6438 UpdateAccessibilityElementInfo(resultNode, commonProperty, info, ngPipeline);
6439 SetRootAccessibilityVisible(resultNode, info);
6440 SetRootAccessibilityNextFocusId(resultNode, rootNode, info);
6441 SetRootAccessibilityPreFocusId(resultNode, rootNode, info,
6442 nextFocusMapWithSubWindow_[context->GetInstanceId()]);
6443 UpdateUiExtensionParentIdForFocus(rootNode, uiExtensionOffset, info);
6444 }
6445
FindFocusedExtensionElementInfoNG(const SearchParameter & searchParam,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::FrameNode> & root)6446 void JsAccessibilityManager::FindFocusedExtensionElementInfoNG(const SearchParameter& searchParam,
6447 Accessibility::AccessibilityElementInfo& info,
6448 const RefPtr<PipelineBase>& context, const RefPtr<NG::FrameNode>& root)
6449 {
6450 #ifdef WINDOW_SCENE_SUPPORTED
6451 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
6452 CHECK_NULL_VOID(ngPipeline);
6453 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6454 CHECK_NULL_VOID(uiExtensionManager);
6455 auto elementIdPair = uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset,
6456 searchParam.nodeId);
6457 auto uiExtensionNode = uiExtensionManager->GetFocusUiExtensionNode();
6458 CHECK_NULL_VOID(uiExtensionNode);
6459 SearchParameter transferSearchParam {elementIdPair.second, "",
6460 searchParam.mode, searchParam.uiExtensionOffset};
6461 OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(transferSearchParam, uiExtensionNode, info);
6462 SetUiExtensionAbilityParentIdForFocus(uiExtensionNode, searchParam.uiExtensionOffset, info);
6463 #endif
6464 }
6465
FindNodeFromPipeline(const WeakPtr<PipelineBase> & context,const int64_t elementId)6466 RefPtr<NG::FrameNode> JsAccessibilityManager::FindNodeFromPipeline(
6467 const WeakPtr<PipelineBase>& context, const int64_t elementId)
6468 {
6469 auto pipeline = context.Upgrade();
6470 CHECK_NULL_RETURN(pipeline, nullptr);
6471
6472 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
6473 CHECK_NULL_RETURN(ngPipeline, nullptr);
6474 auto rootNode = ngPipeline->GetRootElement();
6475 CHECK_NULL_RETURN(rootNode, nullptr);
6476
6477 int64_t nodeId = elementId;
6478 // accessibility use -1 for first search to get root node
6479 if (elementId == -1) {
6480 nodeId = rootNode->GetAccessibilityId();
6481 }
6482
6483 auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
6484 if (node) {
6485 return node;
6486 }
6487 return nullptr;
6488 }
6489
FindPipelineByElementId(const int64_t elementId,RefPtr<NG::FrameNode> & node)6490 RefPtr<NG::PipelineContext> JsAccessibilityManager::FindPipelineByElementId(
6491 const int64_t elementId, RefPtr<NG::FrameNode>& node)
6492 {
6493 node = FindNodeFromPipeline(context_, elementId);
6494 if (node) {
6495 auto context = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
6496 return context;
6497 }
6498 for (auto subContext : GetSubPipelineContexts()) {
6499 node = FindNodeFromPipeline(subContext, elementId);
6500 if (node) {
6501 auto context = AceType::DynamicCast<NG::PipelineContext>(subContext.Upgrade());
6502 return context;
6503 }
6504 }
6505 return nullptr;
6506 }
6507
ExecuteAction(const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,AccessibilityElementOperatorCallback & callback)6508 void JsAccessibilityManager::JsInteractionOperation::ExecuteAction(const int64_t elementId, const int32_t action,
6509 const std::map<std::string, std::string>& actionArguments, const int32_t requestId,
6510 AccessibilityElementOperatorCallback& callback)
6511 {
6512 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction elementId: %{public}" PRId64 ", action: %{public}d",
6513 elementId, action);
6514 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
6515 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
6516 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
6517
6518 auto jsAccessibilityManager = GetHandler().Upgrade();
6519 if (!jsAccessibilityManager) {
6520 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId);
6521 callback.SetExecuteActionResult(false, requestId);
6522 return;
6523 }
6524 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
6525 if (!context) {
6526 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId);
6527 callback.SetExecuteActionResult(false, requestId);
6528 return;
6529 }
6530 auto actionInfo = static_cast<ActionType>(action);
6531 ActionParam param { actionInfo, actionArguments };
6532 auto windowId = windowId_;
6533 context->GetTaskExecutor()->PostTask(
6534 [weak = GetHandler(), splitElementId, param, requestId, &callback, windowId] {
6535 auto jsAccessibilityManager = weak.Upgrade();
6536 if (!jsAccessibilityManager) {
6537 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId);
6538 callback.SetExecuteActionResult(false, requestId);
6539 return;
6540 }
6541 ACE_SCOPED_TRACE("ExecuteAction");
6542 jsAccessibilityManager->ExecuteAction(splitElementId, param, requestId, callback, windowId);
6543 },
6544 TaskExecutor::TaskType::UI, "ArkUIAccessibilityExecuteAction");
6545 }
6546
AccessibilityActionEvent(const ActionType & action,const std::map<std::string,std::string> & actionArguments,const RefPtr<AccessibilityNode> & node,const RefPtr<PipelineContext> & context)6547 bool JsAccessibilityManager::AccessibilityActionEvent(const ActionType& action,
6548 const std::map<std::string, std::string>& actionArguments, const RefPtr<AccessibilityNode>& node,
6549 const RefPtr<PipelineContext>& context)
6550 {
6551 if (!node || !context) {
6552 return false;
6553 }
6554 ContainerScope scope(context->GetInstanceId());
6555 switch (action) {
6556 case ActionType::ACCESSIBILITY_ACTION_CLICK: {
6557 node->SetClicked(true);
6558 if (!node->GetClickEventMarker().IsEmpty()) {
6559 #ifndef NG_BUILD
6560 context->SendEventToFrontend(node->GetClickEventMarker());
6561 #endif
6562 node->ActionClick();
6563 return true;
6564 }
6565 return node->ActionClick();
6566 }
6567 case ActionType::ACCESSIBILITY_ACTION_LONG_CLICK: {
6568 if (!node->GetLongPressEventMarker().IsEmpty()) {
6569 #ifndef NG_BUILD
6570 context->SendEventToFrontend(node->GetLongPressEventMarker());
6571 #endif
6572 node->ActionLongClick();
6573 return true;
6574 }
6575 return node->ActionLongClick();
6576 }
6577 case ActionType::ACCESSIBILITY_ACTION_SET_TEXT: {
6578 if (!node->GetSetTextEventMarker().IsEmpty()) {
6579 #ifndef NG_BUILD
6580 context->SendEventToFrontend(node->GetSetTextEventMarker());
6581 #endif
6582 node->ActionSetText(actionArguments.find(ACTION_ARGU_SET_TEXT)->second);
6583 return true;
6584 }
6585 return node->ActionSetText(actionArguments.find(ACTION_ARGU_SET_TEXT)->second);
6586 }
6587 case ActionType::ACCESSIBILITY_ACTION_FOCUS: {
6588 #ifndef NG_BUILD
6589 context->AccessibilityRequestFocus(std::to_string(node->GetNodeId()));
6590 #endif
6591 if (!node->GetFocusEventMarker().IsEmpty()) {
6592 #ifndef NG_BUILD
6593 context->SendEventToFrontend(node->GetFocusEventMarker());
6594 #endif
6595 node->ActionFocus();
6596 return true;
6597 }
6598 return node->ActionFocus();
6599 }
6600 case ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS: {
6601 return RequestAccessibilityFocus(node);
6602 }
6603 case ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
6604 return ClearAccessibilityFocus(node);
6605 }
6606 case ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD:
6607 return node->ActionScrollForward();
6608 case ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD:
6609 return node->ActionScrollBackward();
6610 default:
6611 return false;
6612 }
6613 }
6614
SendActionEvent(const Accessibility::ActionType & action,int64_t nodeId)6615 void JsAccessibilityManager::SendActionEvent(const Accessibility::ActionType& action, int64_t nodeId)
6616 {
6617 static std::unordered_map<Accessibility::ActionType, std::string> actionToStr {
6618 { Accessibility::ActionType::ACCESSIBILITY_ACTION_CLICK, DOM_CLICK },
6619 { Accessibility::ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, DOM_LONG_PRESS },
6620 { Accessibility::ActionType::ACCESSIBILITY_ACTION_FOCUS, DOM_FOCUS },
6621 { Accessibility::ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, ACCESSIBILITY_FOCUSED_EVENT },
6622 { Accessibility::ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, ACCESSIBILITY_CLEAR_FOCUS_EVENT },
6623 { Accessibility::ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, SCROLL_END_EVENT },
6624 { Accessibility::ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, SCROLL_END_EVENT },
6625 };
6626 if (actionToStr.find(action) == actionToStr.end()) {
6627 return;
6628 }
6629 AccessibilityEvent accessibilityEvent;
6630 accessibilityEvent.eventType = actionToStr[action];
6631 accessibilityEvent.nodeId = static_cast<int64_t>(nodeId);
6632 SendAccessibilityAsyncEvent(accessibilityEvent);
6633 }
6634
6635 namespace {
stringToLower(std::string & str)6636 void stringToLower(std::string &str)
6637 {
6638 std::transform(str.begin(), str.end(), str.begin(), [](char &c) {
6639 return std::tolower(c);
6640 });
6641 }
6642
conversionDirection(std::string dir)6643 bool conversionDirection(std::string dir)
6644 {
6645 stringToLower(dir);
6646 if (dir.compare(STRING_DIR_FORWARD) == 0) {
6647 return true;
6648 }
6649
6650 return false;
6651 }
6652
getArgumentByKey(const std::map<std::string,std::string> & actionArguments,const std::string & checkKey)6653 int32_t getArgumentByKey(const std::map<std::string, std::string>& actionArguments, const std::string& checkKey)
6654 {
6655 auto iter = actionArguments.find(checkKey);
6656 int32_t argument = -1; // -1:default value
6657 if (iter != actionArguments.end()) {
6658 std::stringstream strArguments;
6659 strArguments << iter->second;
6660 strArguments >> argument;
6661 }
6662 return argument;
6663 }
6664
GetUnsignedLongArgumentByKey(const std::map<std::string,std::string> & actionArguments,const std::string & checkKey)6665 uint64_t GetUnsignedLongArgumentByKey(const std::map<std::string, std::string>& actionArguments,
6666 const std::string& checkKey)
6667 {
6668 auto iter = actionArguments.find(checkKey);
6669 uint64_t argument = 0; // 0:default value
6670 if (iter != actionArguments.end()) {
6671 std::stringstream strArguments;
6672 strArguments << iter->second;
6673 strArguments >> argument;
6674 }
6675 return argument;
6676 }
6677
GetStrArgumentByKey(const std::map<std::string,std::string> & actionArguments,const std::string & checkKey)6678 std::string GetStrArgumentByKey(const std::map<std::string, std::string>& actionArguments, const std::string& checkKey)
6679 {
6680 std::string result;
6681 auto iter = actionArguments.find(checkKey);
6682 if (iter != actionArguments.end()) {
6683 result = iter->second;
6684 }
6685 return result;
6686 }
6687
findAccessibilityScrollType(int32_t accessibilityScrollTypeValue)6688 AccessibilityScrollType findAccessibilityScrollType(int32_t accessibilityScrollTypeValue)
6689 {
6690 switch (accessibilityScrollTypeValue) {
6691 case 0:
6692 return AccessibilityScrollType::SCROLL_HALF;
6693 case 1:
6694 return AccessibilityScrollType::SCROLL_FULL;
6695 default:
6696 return AccessibilityScrollType::SCROLL_DEFAULT;
6697 }
6698 }
6699
GetAccessibilitySecCompEnhanceEvent(const std::map<std::string,std::string> & actionArguments)6700 NG::SecCompEnhanceEvent GetAccessibilitySecCompEnhanceEvent(const std::map<std::string, std::string>& actionArguments)
6701 {
6702 NG::SecCompEnhanceEvent secEvent;
6703 auto hmac = GetStrArgumentByKey(actionArguments, ACTION_ARGU_CLICK_ENHANCE_DATA);
6704 if (hmac.empty()) {
6705 return secEvent;
6706 }
6707 auto time = GetUnsignedLongArgumentByKey(actionArguments, ACTION_ARGU_CLICK_TIMESTAMP);
6708 secEvent.dataBuffer.assign(hmac.begin(), hmac.end());
6709 std::chrono::microseconds microseconds(time);
6710 secEvent.time = TimeStamp { microseconds };
6711 return secEvent;
6712 }
6713
getAccessibilityScrollType(const std::map<std::string,std::string> & actionArguments,const std::string & checkKey)6714 AccessibilityScrollType getAccessibilityScrollType(const std::map<std::string, std::string>& actionArguments,
6715 const std::string& checkKey)
6716 {
6717 auto argument = getArgumentByKey(actionArguments, checkKey);
6718 return findAccessibilityScrollType(argument);
6719 }
6720
6721
ActAccessibilityAction(Accessibility::ActionType action,const std::map<std::string,std::string> & actionArguments,RefPtr<NG::AccessibilityProperty> accessibilityProperty)6722 bool ActAccessibilityAction(Accessibility::ActionType action, const std::map<std::string, std::string>& actionArguments,
6723 RefPtr<NG::AccessibilityProperty> accessibilityProperty)
6724 {
6725 AccessibilityActionParam param;
6726 if (action == ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) {
6727 std::string dir = STRING_DIR_BACKWARD;
6728 auto iter = actionArguments.find(ACTION_ARGU_SELECT_TEXT_INFORWARD);
6729 if (iter != actionArguments.end()) {
6730 dir = iter->second;
6731 }
6732 param.setSelectionStart = getArgumentByKey(actionArguments, ACTION_ARGU_SELECT_TEXT_START);
6733 param.setSelectionEnd = getArgumentByKey(actionArguments, ACTION_ARGU_SELECT_TEXT_END);
6734 param.setSelectionDir = conversionDirection(dir);
6735 }
6736 if (action == ActionType::ACCESSIBILITY_ACTION_SET_TEXT) {
6737 auto iter = actionArguments.find(ACTION_ARGU_SET_TEXT);
6738 if (iter != actionArguments.end()) {
6739 param.setTextArgument = iter->second;
6740 }
6741 }
6742 if (action == ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT ||
6743 action == ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT) {
6744 int moveUnit = TextMoveUnit::STEP_CHARACTER;
6745 auto iter = actionArguments.find(ACTION_ARGU_MOVE_UNIT);
6746 if (iter != actionArguments.end()) {
6747 std::stringstream str_moveUnit;
6748 str_moveUnit << iter->second;
6749 str_moveUnit >> moveUnit;
6750 }
6751 param.moveUnit = static_cast<TextMoveUnit>(moveUnit);
6752 }
6753 if (action == ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION) {
6754 param.setCursorIndex = getArgumentByKey(actionArguments, ACTION_ARGU_SET_OFFSET);
6755 }
6756 if ((action == ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD) ||
6757 (action == ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD)) {
6758 param.scrollType = getAccessibilityScrollType(actionArguments, ACTION_ARGU_SCROLL_STUB);
6759 }
6760 if (action == ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK) {
6761 param.spanId = getArgumentByKey(actionArguments, ACTION_ARGU_SPAN_ID);
6762 }
6763 auto accessibiltyAction = ACTIONS.find(action);
6764 if (accessibiltyAction != ACTIONS.end()) {
6765 param.accessibilityProperty = accessibilityProperty;
6766 return accessibiltyAction->second(param);
6767 }
6768 return false;
6769 }
6770 }
6771
ExecuteExtensionActionNG(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)6772 bool JsAccessibilityManager::ExecuteExtensionActionNG(int64_t elementId,
6773 const std::map<std::string, std::string>& actionArguments, int32_t action, const RefPtr<PipelineBase>& context,
6774 int64_t uiExtensionOffset)
6775 {
6776 return ExecuteActionNG(
6777 elementId, actionArguments, static_cast<ActionType>(action), context, uiExtensionOffset);
6778 }
6779
ExecuteActionNG(int64_t elementId,const std::map<std::string,std::string> & actionArguments,ActionType action,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)6780 bool JsAccessibilityManager::ExecuteActionNG(int64_t elementId,
6781 const std::map<std::string, std::string>& actionArguments, ActionType action, const RefPtr<PipelineBase>& context,
6782 int64_t uiExtensionOffset)
6783 {
6784 if (GetIsIgnoreAllAction() && !(action == ActionType::ACCESSIBILITY_ACTION_FOCUS ||
6785 action == ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS)) {
6786 return false;
6787 }
6788 bool result = false;
6789 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
6790 CHECK_NULL_RETURN(ngPipeline, result);
6791 #ifdef WINDOW_SCENE_SUPPORTED
6792 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6793 CHECK_NULL_RETURN(uiExtensionManager, result);
6794 if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
6795 auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(uiExtensionOffset, elementId);
6796 int64_t childWrapId = unWrapIdPair.second;
6797 int64_t uiExtensionId = unWrapIdPair.first;
6798 auto rootNode = ngPipeline->GetRootElement();
6799 CHECK_NULL_RETURN(rootNode, result);
6800 auto uiExtensionNode = FindNodeFromRootByExtensionId(rootNode, uiExtensionId);
6801 CHECK_NULL_RETURN(uiExtensionNode, result);
6802 return OHOS::Ace::Framework::TransferExecuteAction(
6803 childWrapId, uiExtensionNode, actionArguments, action, uiExtensionOffset);
6804 }
6805 #endif
6806 ContainerScope instance(ngPipeline->GetInstanceId());
6807 auto frameNode = GetFramenodeByAccessibilityId(ngPipeline->GetRootElement(), elementId);
6808
6809 if (!frameNode && elementId == lastElementId_) {
6810 frameNode = lastFrameNode_.Upgrade();
6811 }
6812
6813
6814 CHECK_NULL_RETURN(frameNode, result);
6815
6816 auto enabled = frameNode->GetFocusHub() ? frameNode->GetFocusHub()->IsEnabled() : true;
6817 if (!enabled && action != ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS &&
6818 action != ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS) {
6819 return result;
6820 }
6821 result = ConvertActionTypeToBoolen(action, frameNode, elementId, ngPipeline, actionArguments);
6822 if (!result) {
6823 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
6824 CHECK_NULL_RETURN(accessibilityProperty, false);
6825 result = ActAccessibilityAction(action, actionArguments, accessibilityProperty);
6826 if (!result) {
6827 EventReport::ReportAccessibilityFailEvent(ConvertActionTypeToString(action));
6828 }
6829 }
6830 return result;
6831 }
6832
ConvertActionTypeToBoolen(ActionType action,RefPtr<NG::FrameNode> & frameNode,int64_t elementId,RefPtr<NG::PipelineContext> & context,const std::map<std::string,std::string> & actionArguments)6833 bool JsAccessibilityManager::ConvertActionTypeToBoolen(ActionType action, RefPtr<NG::FrameNode>& frameNode,
6834 int64_t elementId, RefPtr<NG::PipelineContext>& context, const std::map<std::string, std::string>& actionArguments)
6835 {
6836 bool result = false;
6837 NG::SecCompEnhanceEvent secEvent;
6838 switch (action) {
6839 case ActionType::ACCESSIBILITY_ACTION_FOCUS: {
6840 result = RequestFocus(frameNode);
6841 break;
6842 }
6843 case ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS: {
6844 result = LostFocus(frameNode);
6845 break;
6846 }
6847 case ActionType::ACCESSIBILITY_ACTION_CLICK: {
6848 secEvent = GetAccessibilitySecCompEnhanceEvent(actionArguments);
6849 result = ActClick(frameNode, secEvent);
6850 break;
6851 }
6852 case ActionType::ACCESSIBILITY_ACTION_LONG_CLICK: {
6853 result = ActLongClick(frameNode);
6854 break;
6855 }
6856 case ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS: {
6857 SaveLast(elementId, frameNode);
6858 SaveCurrentFocusNodeSize(frameNode);
6859 AccessibilityFocusInfo focusInfo{ currentFocusNodeId_, currentFocusVirtualNodeParentId_ };
6860 result = ActAccessibilityFocus(elementId, frameNode, context, focusInfo, false);
6861 currentFocusNodeId_ = focusInfo.currentFocusNodeId;
6862 currentFocusVirtualNodeParentId_ = focusInfo.currentFocusVirtualNodeParentId;
6863 break;
6864 }
6865 case ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
6866 SaveLast(elementId, frameNode);
6867 AccessibilityFocusInfo focusInfo{ currentFocusNodeId_, currentFocusVirtualNodeParentId_ };
6868 result = ActAccessibilityFocus(elementId, frameNode, context, focusInfo, true);
6869 currentFocusNodeId_ = focusInfo.currentFocusNodeId;
6870 currentFocusVirtualNodeParentId_ = focusInfo.currentFocusVirtualNodeParentId;
6871 break;
6872 }
6873 default:
6874 break;
6875 }
6876 return result;
6877 }
6878
ExecuteAction(const int64_t elementId,const ActionParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)6879 void JsAccessibilityManager::ExecuteAction(const int64_t elementId, const ActionParam& param, const int32_t requestId,
6880 AccessibilityElementOperatorCallback& callback, const int32_t windowId)
6881 {
6882 auto action = param.action;
6883 auto actionArguments = param.actionArguments;
6884
6885 bool actionResult = false;
6886 auto context = GetPipelineByWindowId(windowId);
6887 if (!context) {
6888 SetExecuteActionResult(callback, actionResult, requestId);
6889 return;
6890 }
6891
6892 if (AceType::InstanceOf<NG::PipelineContext>(context)) {
6893 actionResult = ExecuteActionNG(elementId, actionArguments, action, context, NG::UI_EXTENSION_OFFSET_MAX);
6894 } else {
6895 auto node = GetAccessibilityNodeFromPage(elementId);
6896 if (!node) {
6897 SetExecuteActionResult(callback, false, requestId);
6898 return;
6899 }
6900
6901 actionResult =
6902 AccessibilityActionEvent(action, actionArguments, node, AceType::DynamicCast<PipelineContext>(context));
6903 }
6904 SetExecuteActionResult(callback, actionResult, requestId);
6905 if (actionResult && AceType::InstanceOf<PipelineContext>(context)) {
6906 SendActionEvent(action, elementId);
6907 }
6908 }
6909
GetCursorPosition(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback)6910 void JsAccessibilityManager::JsInteractionOperation::GetCursorPosition(const int64_t elementId,
6911 const int32_t requestId, AccessibilityElementOperatorCallback &callback)
6912 {
6913 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
6914 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
6915 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
6916
6917 auto jsAccessibilityManager = GetHandler().Upgrade();
6918 CHECK_NULL_VOID(jsAccessibilityManager);
6919 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
6920 CHECK_NULL_VOID(context);
6921 RefPtr<NG::FrameNode> node;
6922 auto ngPipeline = jsAccessibilityManager->FindPipelineByElementId(splitElementId, node);
6923 CHECK_NULL_VOID(ngPipeline);
6924 #ifdef WINDOW_SCENE_SUPPORTED
6925 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
6926 CHECK_NULL_VOID(uiExtensionManager);
6927 if (uiExtensionManager->IsWrapExtensionAbilityId(splitElementId)) {
6928 auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(NG::UI_EXTENSION_OFFSET_MAX, elementId);
6929 int64_t uiExtensionId = unWrapIdPair.first;
6930 auto rootNode = ngPipeline->GetRootElement();
6931 CHECK_NULL_VOID(rootNode);
6932 auto uiExtensionNode = jsAccessibilityManager->FindNodeFromRootByExtensionId(rootNode, uiExtensionId);
6933 CHECK_NULL_VOID(uiExtensionNode);
6934 auto accessibilityProperty = uiExtensionNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
6935 CHECK_NULL_VOID(accessibilityProperty);
6936 auto callNumber = accessibilityProperty->ActActionGetIndex();
6937 callback.SetCursorPositionResult(callNumber, requestId);
6938 return;
6939 }
6940 #endif
6941 auto frameNode = GetFramenodeByAccessibilityId(ngPipeline->GetRootElement(), splitElementId);
6942 CHECK_NULL_VOID(frameNode);
6943 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
6944 CHECK_NULL_VOID(accessibilityProperty);
6945 auto callNumber = accessibilityProperty->ActActionGetIndex();
6946 callback.SetCursorPositionResult(callNumber, requestId);
6947 }
6948
ClearFocus()6949 void JsAccessibilityManager::JsInteractionOperation::ClearFocus()
6950 {
6951 auto jsAccessibilityManager = GetHandler().Upgrade();
6952 CHECK_NULL_VOID(jsAccessibilityManager);
6953 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
6954 CHECK_NULL_VOID(context);
6955 context->GetTaskExecutor()->PostTask(
6956 [weak = GetHandler()] {
6957 auto jsAccessibilityManager = weak.Upgrade();
6958 CHECK_NULL_VOID(jsAccessibilityManager);
6959 ACE_SCOPED_TRACE("ClearCurrentFocus");
6960 jsAccessibilityManager->ClearCurrentFocus();
6961 },
6962 TaskExecutor::TaskType::UI, "ArkUIAccessibilityClearCurrentFocus");
6963 }
6964
OutsideTouch()6965 void JsAccessibilityManager::JsInteractionOperation::OutsideTouch() {}
6966 #ifdef WEB_SUPPORTED
6967
GetChildrenFromWebNode(int64_t nodeId,std::list<int64_t> & children,const RefPtr<NG::PipelineContext> & ngPipeline,const RefPtr<NG::WebPattern> & webPattern)6968 std::shared_ptr<NG::TransitionalNodeInfo> GetChildrenFromWebNode(
6969 int64_t nodeId, std::list<int64_t>& children,
6970 const RefPtr<NG::PipelineContext>& ngPipeline, const RefPtr<NG::WebPattern>& webPattern)
6971 {
6972 std::shared_ptr<NG::TransitionalNodeInfo> node = nullptr;
6973 std::list<int64_t> webNodeChildren;
6974 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
6975 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
6976 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
6977 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(nodeId, splitElementId, splitTreeId);
6978 node = webPattern->GetTransitionalNodeById(splitElementId);
6979 CHECK_NULL_RETURN(node, nullptr);
6980 auto treeId = webPattern->GetTreeId();
6981 for (auto& childIdConst : node->GetChildIds()) {
6982 int64_t mutableChildId = childIdConst;
6983 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, mutableChildId);
6984 webNodeChildren.emplace_back(mutableChildId);
6985 }
6986 }
6987 while (!webNodeChildren.empty()) {
6988 children.emplace_back(webNodeChildren.front());
6989 webNodeChildren.pop_front();
6990 }
6991 return node;
6992 }
6993
SearchWebElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t mode,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)6994 void JsAccessibilityManager::SearchWebElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId,
6995 AccessibilityElementOperatorCallback& callback, const int32_t mode, const int32_t windowId,
6996 const RefPtr<NG::WebPattern>& webPattern)
6997 {
6998 std::list<AccessibilityElementInfo> infos;
6999
7000 auto pipeline = GetPipelineByWindowId(windowId);
7001 CHECK_NULL_VOID(pipeline);
7002 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
7003 CHECK_NULL_VOID(ngPipeline);
7004
7005 if (!ngPipeline->GetOnFocus() && (SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE)) {
7006 TAG_LOGD(AceLogTag::ACE_WEB,
7007 "SearchWebElementInfo GetOnFocus, elementId: %{public}" PRId64
7008 ", requestId: %{public}d, mode: %{public}d, windowId: %{public}d",
7009 elementId, requestId, mode, windowId);
7010 SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId, true);
7011 return;
7012 }
7013 CHECK_NULL_VOID(webPattern);
7014
7015 if (elementId == -1) {
7016 auto webNode = webPattern->GetHost();
7017 AccessibilityElementInfo webInfo;
7018 SetRootAccessibilityVisible(webNode, webInfo);
7019 if (!webInfo.GetAccessibilityVisible()) {
7020 TAG_LOGD(AceLogTag::ACE_WEB,
7021 "SearchWebElementinfo accessibility visible false, elementId: %{public}" PRId64
7022 ", requestId: %{public}d, mode: %{public}d, windowId: %{public}d",
7023 elementId, requestId, mode, windowId);
7024 SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId, true);
7025 return;
7026 }
7027 }
7028
7029 SearchWebElementInfoByAccessibilityIdNG(elementId, mode, infos, ngPipeline, webPattern);
7030 SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId, true);
7031 }
7032
SearchWebElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,std::list<AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,const RefPtr<NG::WebPattern> & webPattern)7033 void JsAccessibilityManager::SearchWebElementInfoByAccessibilityIdNG(int64_t elementId, int32_t mode,
7034 std::list<AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context,
7035 const RefPtr<NG::WebPattern>& webPattern)
7036 {
7037 TAG_LOGD(AceLogTag::ACE_WEB, "elementId: %{public}" PRId64 ", treeId: %{public}d, mode: %{public}d",
7038 elementId, treeId_, mode);
7039 auto mainContext = context_.Upgrade();
7040 CHECK_NULL_VOID(mainContext);
7041
7042 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
7043 CHECK_NULL_VOID(ngPipeline);
7044
7045 AccessibilityElementInfo nodeInfo;
7046
7047 CHECK_NULL_VOID(webPattern);
7048 auto webNode = webPattern->GetHost();
7049 CHECK_NULL_VOID(webNode);
7050 CommonProperty commonProperty;
7051 GenerateCommonPropertyForWeb(ngPipeline, commonProperty, mainContext, webNode);
7052
7053 auto node = webPattern->GetTransitionalNodeById(elementId);
7054 CHECK_NULL_VOID(node);
7055 UpdateWebAccessibilityElementInfo(node, commonProperty, nodeInfo, webPattern);
7056 nodeInfo.SetAccessibilityVisible(webPattern->GetAccessibilityVisible(elementId));
7057 infos.push_back(nodeInfo);
7058 SearchParameter param {elementId, "", mode, 0};
7059 UpdateWebCacheInfo(infos, elementId, commonProperty, ngPipeline, param, webPattern);
7060 }
7061
FindWebFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)7062 void JsAccessibilityManager::FindWebFocusedElementInfo(const int64_t elementId, const int32_t focusType,
7063 const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId,
7064 const RefPtr<NG::WebPattern>& webPattern)
7065 {
7066 AccessibilityElementInfo nodeInfo;
7067 if (focusType != FOCUS_TYPE_INPUT && focusType != FOCUS_TYPE_ACCESSIBILITY) {
7068 nodeInfo.SetValidElement(false);
7069 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
7070 return;
7071 }
7072
7073 auto context = GetPipelineByWindowId(windowId);
7074 if (!context || AceType::InstanceOf<NG::PipelineContext>(context)) {
7075 nodeInfo.SetValidElement(false);
7076 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
7077 return;
7078 }
7079
7080 FindWebFocusedElementInfoNG(elementId, focusType, nodeInfo, context, webPattern);
7081 SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
7082 }
7083
FindWebFocusedElementInfoNG(int64_t elementId,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::WebPattern> & webPattern)7084 void JsAccessibilityManager::FindWebFocusedElementInfoNG(int64_t elementId, int32_t focusType,
7085 Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
7086 const RefPtr<NG::WebPattern>& webPattern)
7087 {
7088 CHECK_NULL_VOID(webPattern);
7089 auto mainContext = context_.Upgrade();
7090 CHECK_NULL_VOID(mainContext);
7091 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
7092 CHECK_NULL_VOID(ngPipeline);
7093 auto node = webPattern->GetFocusedAccessibilityNode(elementId, focusType == FOCUS_TYPE_ACCESSIBILITY);
7094 if (!node) {
7095 info.SetValidElement(false);
7096 return;
7097 }
7098 CHECK_NULL_VOID(node);
7099
7100 auto webNode = webPattern->GetHost();
7101 CHECK_NULL_VOID(webNode);
7102 CommonProperty commonProperty;
7103 GenerateCommonPropertyForWeb(ngPipeline, commonProperty, mainContext, webNode);
7104 UpdateWebAccessibilityElementInfo(node, commonProperty, info, webPattern);
7105 }
7106
WebFocusMoveSearch(const int64_t elementId,const int32_t direction,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)7107 void JsAccessibilityManager::WebFocusMoveSearch(const int64_t elementId, const int32_t direction,
7108 const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId,
7109 const RefPtr<NG::WebPattern>& webPattern)
7110 {
7111 AccessibilityElementInfo nodeInfo;
7112 auto context = GetPipelineByWindowId(windowId);
7113 if (!context) {
7114 nodeInfo.SetValidElement(false);
7115 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
7116 return;
7117 }
7118
7119 WebFocusMoveSearchNG(elementId, direction, nodeInfo, context, webPattern);
7120 WebFocusMoveSearchByComponent(nodeInfo, webPattern, direction, context);
7121 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
7122 }
7123
WebFocusMoveSearchByComponent(AccessibilityElementInfo & nodeInfo,const RefPtr<NG::WebPattern> & webPattern,const int32_t direction,RefPtr<PipelineBase> context)7124 void JsAccessibilityManager::WebFocusMoveSearchByComponent(AccessibilityElementInfo& nodeInfo,
7125 const RefPtr<NG::WebPattern>& webPattern, const int32_t direction, RefPtr<PipelineBase> context)
7126 {
7127 if (!IsTagInEmbedComponent(nodeInfo.GetComponentType())) {
7128 return;
7129 }
7130 int64_t accessibilityId = nodeInfo.GetAccessibilityId();
7131 CHECK_NULL_VOID(webPattern);
7132 std::shared_ptr<NG::TransitionalNodeInfo> transitionalNodeInfo =
7133 webPattern->GetTransitionalNodeById(accessibilityId);
7134 CHECK_NULL_VOID(transitionalNodeInfo);
7135 std::string surfaceId = webPattern->GetSurfaceIdByHtmlElementId(transitionalNodeInfo->GetHtmlElementId());
7136 if (surfaceId == "") {
7137 return;
7138 }
7139 std::list<AccessibilityElementInfo> embedNodeTreeInfo;
7140 int32_t windowId = nodeInfo.GetWindowId();
7141 SearchSurfaceIdRet searchSurfaceIdRet = SearchSurfaceIdRet::NO_MATCH_NODE;
7142 if (direction == FocusMoveDirection::FORWARD) {
7143 searchSurfaceIdRet =
7144 SearchElementInfoBySurfaceId(surfaceId, windowId, SearchSurfaceIdType::SEARCH_HEAD, embedNodeTreeInfo);
7145 } else if (direction == FocusMoveDirection::BACKWARD) {
7146 searchSurfaceIdRet =
7147 SearchElementInfoBySurfaceId(surfaceId, windowId, SearchSurfaceIdType::SEARCH_TAIL, embedNodeTreeInfo);
7148 }
7149 if (searchSurfaceIdRet != SearchSurfaceIdRet::SEARCH_SUCCESS || embedNodeTreeInfo.empty()) {
7150 WebFocusMoveSearchNG(accessibilityId, direction, nodeInfo, context, webPattern);
7151 } else {
7152 nodeInfo = embedNodeTreeInfo.front();
7153 }
7154 }
7155
WebFocusMoveSearchNG(int64_t elementId,int32_t direction,AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::WebPattern> & webPattern)7156 void JsAccessibilityManager::WebFocusMoveSearchNG(int64_t elementId, int32_t direction,
7157 AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
7158 const RefPtr<NG::WebPattern>& webPattern)
7159 {
7160 auto mainContext = context_.Upgrade();
7161 CHECK_NULL_VOID(mainContext);
7162 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
7163 CHECK_NULL_VOID(ngPipeline);
7164
7165 CHECK_NULL_VOID(webPattern);
7166 auto webNode = webPattern->GetHost();
7167 CHECK_NULL_VOID(webNode);
7168 CommonProperty commonProperty;
7169 GenerateCommonPropertyForWeb(ngPipeline, commonProperty, mainContext, webNode);
7170
7171 auto node = webPattern->GetAccessibilityNodeByFocusMove(elementId, direction);
7172 if (node) {
7173 UpdateWebAccessibilityElementInfo(node, commonProperty, info, webPattern);
7174 } else {
7175 auto webNode = webPattern->GetHost();
7176 CHECK_NULL_VOID(webNode);
7177 UpdateAccessibilityElementInfo(webNode, commonProperty, info, ngPipeline);
7178 }
7179 }
7180
ExecuteWebActionNG(int64_t elementId,ActionType action,const std::map<std::string,std::string> & actionArguments,const RefPtr<NG::WebPattern> & webPattern)7181 bool JsAccessibilityManager::ExecuteWebActionNG(int64_t elementId, ActionType action,
7182 const std::map<std::string, std::string>& actionArguments, const RefPtr<NG::WebPattern>& webPattern)
7183 {
7184 CHECK_NULL_RETURN(webPattern, false);
7185 return webPattern->ExecuteAction(elementId, ConvertAccessibilityAction(action), actionArguments);
7186 }
7187
ExecuteWebAction(const int64_t elementId,const ActionParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)7188 void JsAccessibilityManager::ExecuteWebAction(const int64_t elementId, const ActionParam& param,
7189 const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId,
7190 const RefPtr<NG::WebPattern>& webPattern)
7191 {
7192 auto action = param.action;
7193 auto actionArguments = param.actionArguments;
7194
7195 bool actionResult = false;
7196 auto context = GetPipelineByWindowId(windowId);
7197 if (!context || !AceType::InstanceOf<NG::PipelineContext>(context)) {
7198 SetExecuteActionResult(callback, actionResult, requestId);
7199 return;
7200 }
7201
7202 actionResult = ExecuteWebActionNG(elementId, action, actionArguments, webPattern);
7203 SetExecuteActionResult(callback, actionResult, requestId);
7204 }
7205
RegisterWebInteractionOperationAsChildTree(int64_t accessibilityId,const WeakPtr<NG::WebPattern> & webPattern)7206 bool JsAccessibilityManager::RegisterWebInteractionOperationAsChildTree(int64_t accessibilityId,
7207 const WeakPtr<NG::WebPattern>& webPattern)
7208 {
7209 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
7210 CHECK_NULL_RETURN(instance, false);
7211 auto pipelineContext = GetPipelineContext().Upgrade();
7212 CHECK_NULL_RETURN(pipelineContext, false);
7213 auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
7214 if (container != nullptr && container->IsUIExtensionWindow()) {
7215 windowId_ = pipelineContext->GetRealHostWindowId();
7216 }
7217
7218 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId_, accessibilityId);
7219
7220 uint32_t parentWindowId = GetWindowId();
7221 auto pattern = webPattern.Upgrade();
7222 CHECK_NULL_RETURN(pattern, false);
7223 auto frameNode = pattern->GetHost();
7224 CHECK_NULL_RETURN(frameNode, false);
7225 auto pipeline = frameNode->GetContextRefPtr();
7226 CHECK_NULL_RETURN(pipeline, false);
7227 uint32_t windowId = static_cast<uint32_t>(pipeline->GetRealHostWindowId());
7228 auto interactionOperation = std::make_shared<WebInteractionOperation>(windowId);
7229 interactionOperation->SetHandler(WeakClaim(this));
7230 interactionOperation->SetWebPattern(webPattern);
7231
7232 Accessibility::Registration registration {
7233 .windowId = static_cast<int32_t>(windowId),
7234 .parentWindowId = static_cast<int32_t>(parentWindowId),
7235 .parentTreeId = treeId_,
7236 .elementId = accessibilityId,
7237 };
7238 parentWebWindowId_ = parentWindowId;
7239 TAG_LOGI(AceLogTag::ACE_WEB, "windowId: %{public}u, parentWindowId: %{public}u, "
7240 "parentTreeId: %{public}d, elementId %{public}" PRId64,
7241 windowId, parentWindowId, treeId_, accessibilityId);
7242 Accessibility::RetError retReg = instance->RegisterElementOperator(registration, interactionOperation);
7243 TAG_LOGI(AceLogTag::ACE_WEB,
7244 "RegisterWebInteractionOperationAsChildTree result: %{public}d, accessibilityId: %{public}" PRId64, retReg,
7245 accessibilityId);
7246 return retReg == RET_OK;
7247 }
7248
DeregisterWebInteractionOperationAsChildTree(int32_t treeId,const WeakPtr<NG::WebPattern> & webPattern)7249 bool JsAccessibilityManager::DeregisterWebInteractionOperationAsChildTree(int32_t treeId,
7250 const WeakPtr<NG::WebPattern>& webPattern)
7251 {
7252 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
7253 CHECK_NULL_RETURN(instance, false);
7254 auto pattern = webPattern.Upgrade();
7255 CHECK_NULL_RETURN(pattern, false);
7256 auto frameNode = pattern->GetHost();
7257 CHECK_NULL_RETURN(frameNode, false);
7258 auto pipeline = frameNode->GetContextRefPtr();
7259 CHECK_NULL_RETURN(pipeline, false);
7260 uint32_t windowId = static_cast<uint32_t>(pipeline->GetRealHostWindowId());
7261 Accessibility::RetError retReg = instance->DeregisterElementOperator(windowId, treeId);
7262 TAG_LOGI(AceLogTag::ACE_WEB,
7263 "DeregisterWebInteractionOperationAsChildTree result: %{public}d, accessibilityId: %{public}" PRId64, retReg,
7264 frameNode->GetAccessibilityId());
7265 return retReg == RET_OK;
7266 }
7267
UpdateWebCacheInfo(std::list<AccessibilityElementInfo> & infos,int64_t nodeId,const CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline,const SearchParameter & searchParam,const RefPtr<NG::WebPattern> & webPattern)7268 void JsAccessibilityManager::UpdateWebCacheInfo(std::list<AccessibilityElementInfo>& infos,
7269 int64_t nodeId, const CommonProperty& commonProperty, const RefPtr<NG::PipelineContext>& ngPipeline,
7270 const SearchParameter& searchParam, const RefPtr<NG::WebPattern>& webPattern)
7271 {
7272 uint32_t umode = searchParam.mode;
7273 std::unordered_map<int64_t, AccessibilityElementInfo> allEmbedNodeTreeInfosMap;
7274 std::list<int64_t> children;
7275 // get all children
7276 if (!(umode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN))) {
7277 return;
7278 }
7279 GetChildrenFromWebNode(nodeId, children, ngPipeline, webPattern);
7280 // The application needs to insert node information in the order of BFS
7281 while (!children.empty()) {
7282 int64_t parent = children.front();
7283 children.pop_front();
7284 AccessibilityElementInfo nodeInfo;
7285 if (GetChildrenFromEmbedNode(nodeInfo, parent, children, allEmbedNodeTreeInfosMap)) {
7286 PushElementsIntoInfos(nodeInfo, infos, webPattern, children, allEmbedNodeTreeInfosMap);
7287 continue;
7288 }
7289
7290 auto node = GetChildrenFromWebNode(parent, children, ngPipeline, webPattern);
7291 if (node) {
7292 UpdateWebAccessibilityElementInfo(node, commonProperty, nodeInfo, webPattern);
7293 PushElementsIntoInfos(nodeInfo, infos, webPattern, children, allEmbedNodeTreeInfosMap);
7294 }
7295 }
7296 }
7297
GetChildrenFromEmbedNode(AccessibilityElementInfo & nodeInfo,int64_t nodeId,std::list<int64_t> & children,std::unordered_map<int64_t,AccessibilityElementInfo> & allEmbedNodeTreeInfosMap)7298 bool JsAccessibilityManager::GetChildrenFromEmbedNode(AccessibilityElementInfo& nodeInfo, int64_t nodeId,
7299 std::list<int64_t>& children, std::unordered_map<int64_t, AccessibilityElementInfo>& allEmbedNodeTreeInfosMap)
7300 {
7301 auto it = allEmbedNodeTreeInfosMap.find(nodeId);
7302 if (it == allEmbedNodeTreeInfosMap.end()) {
7303 return false;
7304 }
7305 nodeInfo = it->second;
7306 allEmbedNodeTreeInfosMap.erase(it);
7307
7308 for (auto& childId : nodeInfo.GetChildIds()) {
7309 children.emplace_back(childId);
7310 }
7311 return true;
7312 }
7313
PushElementsIntoInfos(AccessibilityElementInfo & nodeInfo,std::list<AccessibilityElementInfo> & infos,const RefPtr<NG::WebPattern> & webPattern,std::list<int64_t> & children,std::unordered_map<int64_t,AccessibilityElementInfo> & allEmbedNodeTreeInfosMap)7314 void JsAccessibilityManager::PushElementsIntoInfos(AccessibilityElementInfo& nodeInfo,
7315 std::list<AccessibilityElementInfo>& infos, const RefPtr<NG::WebPattern>& webPattern, std::list<int64_t>& children,
7316 std::unordered_map<int64_t, AccessibilityElementInfo>& allEmbedNodeTreeInfosMap)
7317 {
7318 if (!IsTagInEmbedComponent(nodeInfo.GetComponentType())) {
7319 infos.push_back(nodeInfo);
7320 return;
7321 }
7322 int64_t accessibilityId = nodeInfo.GetAccessibilityId();
7323 CHECK_NULL_VOID(webPattern);
7324 std::shared_ptr<NG::TransitionalNodeInfo> node = webPattern->GetTransitionalNodeById(accessibilityId);
7325 CHECK_NULL_VOID(node);
7326 std::string surfaceId = webPattern->GetSurfaceIdByHtmlElementId(node->GetHtmlElementId());
7327 if (surfaceId == "") {
7328 infos.push_back(nodeInfo);
7329 return;
7330 }
7331 std::list<AccessibilityElementInfo> embedNodeTreeInfo;
7332 int32_t windowId = nodeInfo.GetWindowId();
7333 SearchSurfaceIdRet searchSurfaceIdRet =
7334 SearchElementInfoBySurfaceId(surfaceId, windowId, SearchSurfaceIdType::SEARCH_ALL, embedNodeTreeInfo);
7335 if (searchSurfaceIdRet != SearchSurfaceIdRet::SEARCH_SUCCESS) {
7336 infos.push_back(nodeInfo);
7337 return;
7338 }
7339 AccessibilityElementInfo& root = embedNodeTreeInfo.front();
7340 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(webPattern->GetTreeId(), accessibilityId);
7341 root.SetParent(accessibilityId);
7342 nodeInfo.AddChild(root.GetAccessibilityId());
7343 infos.push_back(nodeInfo);
7344 children.emplace_back(root.GetAccessibilityId());
7345 for (const auto& info : embedNodeTreeInfo) {
7346 allEmbedNodeTreeInfosMap[info.GetAccessibilityId()] = info;
7347 }
7348 }
7349
GetWebAccessibilityIdBySurfaceId(const std::string & surfaceId)7350 int64_t JsAccessibilityManager::GetWebAccessibilityIdBySurfaceId(const std::string& surfaceId)
7351 {
7352 WeakPtr<NG::WebPattern> weakWebPattern = GetWebPatternBySurfaceId(surfaceId);
7353 if (weakWebPattern.Invalid()) {
7354 TAG_LOGI(
7355 AceLogTag::ACE_WEB, "JsAccessibilityManager GetWebAccessibilityIdBySurfaceId weakWebPattern is Invalid");
7356 return INVALID_NODE_ID;
7357 }
7358 auto webPattern = weakWebPattern.Upgrade();
7359 CHECK_NULL_RETURN(webPattern, INVALID_NODE_ID);
7360 int64_t webAccessibilityId = webPattern->GetWebAccessibilityIdBySurfaceId(surfaceId);
7361 if (webAccessibilityId == INVALID_NODE_ID) {
7362 TAG_LOGD(AceLogTag::ACE_WEB, "JsAccessibilityManager GetWebAccessibilityIdBySurfaceId node is Invalid");
7363 return INVALID_NODE_ID;
7364 }
7365 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(webPattern->GetTreeId(), webAccessibilityId);
7366 TAG_LOGD(AceLogTag::ACE_WEB,
7367 "JsAccessibilityManager GetWebAccessibilityIdBySurfaceId return webAccessibilityId: %{public}" PRId64,
7368 webAccessibilityId);
7369 return webAccessibilityId;
7370 }
7371 #endif //WEB_SUPPORTED
7372
RegisterInteractionOperationAsChildTree(const Registration & registration)7373 bool JsAccessibilityManager::RegisterInteractionOperationAsChildTree(
7374 const Registration& registration)
7375 {
7376 bool ret = false;
7377 switch (registration.operatorType) {
7378 case OperatorType::JS_THIRD_PROVIDER:
7379 ret = RegisterThirdProviderInteractionOperationAsChildTree(registration);
7380 break;
7381 default:
7382 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY,
7383 "RegisterInteractionOperationAsChildTree operatorType: %{public}d",
7384 static_cast<int32_t>(registration.operatorType));
7385 }
7386 return ret;
7387 }
7388
RegisterThirdProviderInteractionOperationAsChildTree(const Registration & registration)7389 bool JsAccessibilityManager::RegisterThirdProviderInteractionOperationAsChildTree(
7390 const Registration& registration)
7391 {
7392 std::shared_ptr<AccessibilitySystemAbilityClient> instance =
7393 AccessibilitySystemAbilityClient::GetInstance();
7394 CHECK_NULL_RETURN(instance, false);
7395 Accessibility::Registration innerRegistration {
7396 .windowId = static_cast<int32_t>(registration.windowId),
7397 .parentWindowId = static_cast<int32_t>(registration.parentWindowId),
7398 .parentTreeId = registration.parentTreeId,
7399 .elementId = registration.elementId,
7400 };
7401
7402 auto provider = registration.accessibilityProvider.Upgrade();
7403 CHECK_NULL_RETURN(provider, false);
7404 auto interactionOperation = std::make_shared<JsThirdProviderInteractionOperation>(
7405 registration.accessibilityProvider, WeakClaim(this), registration.hostNode);
7406 provider->SendThirdAccessibilityProvider(interactionOperation);
7407 interactionOperation->Initialize();
7408 RegisterJsThirdProviderInteractionOperation(registration.elementId,
7409 interactionOperation);
7410 Accessibility::RetError retReg = instance->RegisterElementOperator(
7411 innerRegistration, interactionOperation);
7412 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
7413 "RegisterWebInteractionOperationAsChildTree result: %{public}d", retReg);
7414 return retReg == RET_OK;
7415 }
7416
DeregisterInteractionOperationAsChildTree(uint32_t windowId,int32_t treeId)7417 bool JsAccessibilityManager::DeregisterInteractionOperationAsChildTree(
7418 uint32_t windowId, int32_t treeId)
7419 {
7420 std::shared_ptr<AccessibilitySystemAbilityClient> instance =
7421 AccessibilitySystemAbilityClient::GetInstance();
7422 CHECK_NULL_RETURN(instance, false);
7423 Accessibility::RetError retReg = instance->DeregisterElementOperator(windowId, treeId);
7424 return retReg == RET_OK;
7425 }
7426
RegisterInteractionOperation(int windowId)7427 int JsAccessibilityManager::RegisterInteractionOperation(int windowId)
7428 {
7429 if (IsRegister()) {
7430 return 0;
7431 }
7432
7433 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "RegisterInteractionOperation windowId: %{public}u", windowId);
7434 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
7435 CHECK_NULL_RETURN(instance, -1);
7436 auto interactionOperation = std::make_shared<JsInteractionOperation>(windowId);
7437 interactionOperation->SetHandler(WeakClaim(this));
7438 Accessibility::RetError retReg = instance->RegisterElementOperator(windowId, interactionOperation);
7439 RefPtr<PipelineBase> context;
7440 for (const auto& subContext : GetSubPipelineContexts()) {
7441 context = subContext.Upgrade();
7442 CHECK_NULL_CONTINUE(context);
7443 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "RegisterSubPipeline windowId: %{public}u", context->GetWindowId());
7444 interactionOperation = std::make_shared<JsInteractionOperation>(context->GetWindowId());
7445 interactionOperation->SetHandler(WeakClaim(this));
7446 auto retResult = instance->RegisterElementOperator(context->GetWindowId(), interactionOperation);
7447 retReg = retResult == RET_OK ? retReg : retResult;
7448 }
7449 Register(retReg == RET_OK);
7450 if (retReg == RET_OK) {
7451 NotifyChildTreeOnRegister(treeId_);
7452 }
7453
7454 return retReg;
7455 }
7456
RegisterSubWindowInteractionOperation(int windowId)7457 void JsAccessibilityManager::RegisterSubWindowInteractionOperation(int windowId)
7458 {
7459 if (!AceApplicationInfo::GetInstance().IsAccessibilityEnabled() || !IsRegister()) {
7460 return;
7461 }
7462
7463 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
7464 CHECK_NULL_VOID(instance);
7465 auto interactionOperation = std::make_shared<JsInteractionOperation>(windowId);
7466 interactionOperation->SetHandler(WeakClaim(this));
7467 instance->RegisterElementOperator(windowId, interactionOperation);
7468 }
7469
DeregisterInteractionOperation()7470 void JsAccessibilityManager::DeregisterInteractionOperation()
7471 {
7472 if (!IsRegister()) {
7473 return;
7474 }
7475 int windowId = static_cast<int>(GetWindowId());
7476
7477 auto instance = AccessibilitySystemAbilityClient::GetInstance();
7478 CHECK_NULL_VOID(instance);
7479 Register(false);
7480 if (currentFocusNodeId_ != -1 && lastElementId_ != -1) {
7481 auto focusNode = lastFrameNode_.Upgrade();
7482 PaintAccessibilityFocusNode(focusNode, false);
7483 }
7484 lastFrameNode_.Reset();
7485 lastElementId_ = -1;
7486 currentFocusNodeId_ = -1;
7487 if (parentWindowId_ == 0) {
7488 instance->DeregisterElementOperator(windowId);
7489 } else {
7490 instance->DeregisterElementOperator(windowId, treeId_);
7491 parentElementId_ = INVALID_PARENT_ID;
7492 parentTreeId_ = 0;
7493 parentWindowId_ = 0;
7494 }
7495
7496 RefPtr<PipelineBase> context;
7497 for (const auto& subContext : GetSubPipelineContexts()) {
7498 context = subContext.Upgrade();
7499 CHECK_NULL_CONTINUE(context);
7500 instance->DeregisterElementOperator(context->GetWindowId());
7501 }
7502 NotifyChildTreeOnDeregister();
7503
7504 CHECK_EQUAL_VOID(currentFocusVirtualNodeParentId_, -1);
7505 auto pipelineContext = GetPipelineContext().Upgrade();
7506 CHECK_NULL_VOID(pipelineContext);
7507 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
7508 CHECK_NULL_VOID(ngPipeline);
7509 auto rootNode = ngPipeline->GetRootElement();
7510 CHECK_NULL_VOID(rootNode);
7511 ClearVirtualNodeAccessibilityFocus(rootNode, currentFocusVirtualNodeParentId_);
7512 }
7513
RegisterAccessibilityChildTreeCallback(int64_t elementId,const std::shared_ptr<AccessibilityChildTreeCallback> & callback)7514 void JsAccessibilityManager::RegisterAccessibilityChildTreeCallback(
7515 int64_t elementId, const std::shared_ptr<AccessibilityChildTreeCallback> &callback)
7516 {
7517 std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
7518 childTreeCallbackMap_[elementId] = callback;
7519 }
7520
DeregisterAccessibilityChildTreeCallback(int64_t elementId)7521 void JsAccessibilityManager::DeregisterAccessibilityChildTreeCallback(int64_t elementId)
7522 {
7523 std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
7524 childTreeCallbackMap_.erase(elementId);
7525 }
7526
RegisterAccessibilitySAObserverCallback(int64_t elementId,const std::shared_ptr<AccessibilitySAObserverCallback> & callback)7527 void JsAccessibilityManager::RegisterAccessibilitySAObserverCallback(
7528 int64_t elementId, const std::shared_ptr<AccessibilitySAObserverCallback> &callback)
7529 {
7530 std::lock_guard<std::mutex> lock(componentSACallbackMutex_);
7531 componentSACallbackMap_[elementId] = callback;
7532 }
7533
DeregisterAccessibilitySAObserverCallback(int64_t elementId)7534 void JsAccessibilityManager::DeregisterAccessibilitySAObserverCallback(int64_t elementId)
7535 {
7536 std::lock_guard<std::mutex> lock(componentSACallbackMutex_);
7537 componentSACallbackMap_.erase(elementId);
7538 }
7539
NotifyAccessibilitySAStateChange(bool state)7540 void JsAccessibilityManager::NotifyAccessibilitySAStateChange(bool state)
7541 {
7542 std::lock_guard<std::mutex> lock(componentSACallbackMutex_);
7543 for (auto &item : componentSACallbackMap_) {
7544 if (item.second == nullptr) {
7545 continue;
7546 }
7547 item.second->OnState(state);
7548 }
7549 }
7550
NotifyChildTreeOnRegister(int32_t treeId)7551 void JsAccessibilityManager::NotifyChildTreeOnRegister(int32_t treeId)
7552 {
7553 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "NotifyChildTreeOnRegister size: %{public}zu", childTreeCallbackMap_.size());
7554 std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
7555 for (auto &item : childTreeCallbackMap_) {
7556 if (item.second == nullptr) {
7557 continue;
7558 }
7559 item.second->OnRegister(GetWindowId(), treeId);
7560 }
7561 }
7562
NotifyChildTreeOnDeregister()7563 void JsAccessibilityManager::NotifyChildTreeOnDeregister()
7564 {
7565 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "NotifyChildTreeOnDeregister size: %{public}zu",
7566 childTreeCallbackMap_.size());
7567 std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
7568 for (auto &item : childTreeCallbackMap_) {
7569 if (item.second == nullptr) {
7570 continue;
7571 }
7572 item.second->OnDeregister();
7573 }
7574 }
7575
NotifySetChildTreeIdAndWinId(int64_t elementId,const int32_t treeId,const int32_t childWindowId)7576 void JsAccessibilityManager::NotifySetChildTreeIdAndWinId(
7577 int64_t elementId, const int32_t treeId, const int32_t childWindowId)
7578 {
7579 std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
7580 auto findResult = childTreeCallbackMap_.find(elementId);
7581 if (findResult == childTreeCallbackMap_.end()) {
7582 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "node: %{public}" PRId64 " not found, treeId: %{public}d", elementId,
7583 treeId);
7584 return;
7585 }
7586 auto callback = findResult->second;
7587 CHECK_NULL_VOID(callback);
7588 callback->SetChildTreeId(treeId);
7589 callback->OnSetChildTree(childWindowId, treeId);
7590 }
7591
CheckIsChildElement(int64_t & elementId,const std::vector<std::string> & params,std::vector<std::string> & info,DumpMode mode,int64_t & rootId)7592 bool JsAccessibilityManager::CheckIsChildElement(
7593 int64_t &elementId,
7594 const std::vector<std::string> ¶ms,
7595 std::vector<std::string> &info,
7596 DumpMode mode,
7597 int64_t &rootId)
7598 {
7599 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
7600 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
7601
7602 if (mode == DumpMode::TREE) {
7603 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(rootId, splitElementId, splitTreeId);
7604 if (splitTreeId <= 0 || splitTreeId == treeId_) {
7605 rootId = splitElementId;
7606 return false;
7607 }
7608 } else {
7609 if (elementId <= 0) {
7610 return false;
7611 }
7612
7613 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
7614 if (splitTreeId <= 0 || splitTreeId == treeId_) {
7615 elementId = splitElementId;
7616 return false;
7617 }
7618 }
7619
7620 std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
7621 for (const auto &item : childTreeCallbackMap_) {
7622 if (item.second == nullptr) {
7623 continue;
7624 }
7625 if (item.second->GetChildTreeId() != splitTreeId) {
7626 continue;
7627 }
7628 item.second->OnDumpChildInfo(params, info);
7629 for (const auto &childInfo : info) {
7630 DumpLog::GetInstance().Print(childInfo.c_str());
7631 }
7632 return true;
7633 }
7634 return false;
7635 }
7636
NeedRegisterChildTree(uint32_t parentWindowId,int32_t parentTreeId,int64_t parentElementId)7637 bool JsAccessibilityManager::NeedRegisterChildTree(
7638 uint32_t parentWindowId, int32_t parentTreeId, int64_t parentElementId)
7639 {
7640 if (!IsRegister()) {
7641 return true;
7642 }
7643
7644 if (parentWindowId_ == parentWindowId && parentTreeId_ == parentTreeId && parentElementId_ == parentElementId) {
7645 return false;
7646 }
7647 DeregisterInteractionOperationAsChildTree();
7648 return true;
7649 }
7650
RegisterInteractionOperationAsChildTree(uint32_t parentWindowId,int32_t parentTreeId,int64_t parentElementId)7651 void JsAccessibilityManager::RegisterInteractionOperationAsChildTree(
7652 uint32_t parentWindowId, int32_t parentTreeId, int64_t parentElementId)
7653 {
7654 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(parentTreeId, parentElementId);
7655 if (!NeedRegisterChildTree(parentWindowId, parentTreeId, parentElementId)) {
7656 return;
7657 }
7658
7659 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
7660 CHECK_NULL_VOID(instance);
7661 auto pipelineContext = GetPipelineContext().Upgrade();
7662 CHECK_NULL_VOID(pipelineContext);
7663 auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
7664 if (container != nullptr && container->IsUIExtensionWindow()) {
7665 windowId_ = pipelineContext->GetRealHostWindowId();
7666 } else if (pipelineContext->IsFormRender()) {
7667 windowId_ = parentWindowId;
7668 }
7669
7670 uint32_t windowId = GetWindowId();
7671 auto interactionOperation = std::make_shared<JsInteractionOperation>(windowId);
7672 interactionOperation->SetHandler(WeakClaim(this));
7673 Accessibility::Registration registration {
7674 .windowId = static_cast<int32_t>(windowId),
7675 .parentWindowId = static_cast<int32_t>(parentWindowId),
7676 .parentTreeId = parentTreeId,
7677 .elementId = parentElementId,
7678 };
7679 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "windowId: %{public}u, parentWindowId: %{public}u, "
7680 "parentTreeId: %{public}d, %{public}" PRId64,
7681 windowId, parentWindowId, parentTreeId, parentElementId);
7682 Accessibility::RetError retReg = instance->RegisterElementOperator(registration, interactionOperation);
7683 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "RegisterElementOperator result: %{public}d", retReg);
7684 Register(retReg == RET_OK);
7685 AceApplicationInfo::GetInstance().SetAccessibilityEnabled(retReg == RET_OK);
7686 bool isScreenReadEnabled = false;
7687 instance->IsScreenReaderEnabled(isScreenReadEnabled);
7688 AceApplicationInfo::GetInstance().SetAccessibilityScreenReadEnabled(isScreenReadEnabled);
7689 parentElementId_ = parentElementId;
7690 parentTreeId_ = parentTreeId;
7691 parentWindowId_ = parentWindowId;
7692
7693 for (const auto& subContext : GetSubPipelineContexts()) {
7694 auto context = subContext.Upgrade();
7695 CHECK_NULL_CONTINUE(context);
7696 interactionOperation = std::make_shared<JsInteractionOperation>(context->GetWindowId());
7697 interactionOperation->SetHandler(WeakClaim(this));
7698 instance->RegisterElementOperator(context->GetWindowId(), interactionOperation);
7699 }
7700 }
7701
SetAccessibilityGetParentRectHandler(std::function<void (int32_t &,int32_t &)> && callback)7702 void JsAccessibilityManager::SetAccessibilityGetParentRectHandler(std::function<void(int32_t &, int32_t &)> &&callback)
7703 {
7704 getParentRectHandler_ = std::move(callback);
7705 }
7706
SetAccessibilityGetParentRectHandler(std::function<void (AccessibilityParentRectInfo &)> && callback)7707 void JsAccessibilityManager::SetAccessibilityGetParentRectHandler(
7708 std::function<void(AccessibilityParentRectInfo &)> &&callback)
7709 {
7710 getParentRectHandlerNew_ = std::move(callback);
7711 }
7712
DeregisterInteractionOperationAsChildTree()7713 void JsAccessibilityManager::DeregisterInteractionOperationAsChildTree()
7714 {
7715 if (!IsRegister()) {
7716 return;
7717 }
7718 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "deregister accessibility childTree");
7719
7720 std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
7721 CHECK_NULL_VOID(instance);
7722 uint32_t windowId = GetWindowId();
7723 Register(false);
7724 currentFocusNodeId_ = -1;
7725 instance->DeregisterElementOperator(windowId, treeId_);
7726 AceApplicationInfo::GetInstance().SetAccessibilityEnabled(false);
7727 AceApplicationInfo::GetInstance().SetAccessibilityScreenReadEnabled(false);
7728 parentElementId_ = INVALID_PARENT_ID;
7729 parentTreeId_ = 0;
7730 parentWindowId_ = 0;
7731 NotifyChildTreeOnDeregister();
7732
7733 RefPtr<PipelineBase> context;
7734 for (const auto& subContext : GetSubPipelineContexts()) {
7735 context = subContext.Upgrade();
7736 CHECK_NULL_CONTINUE(context);
7737 instance->DeregisterElementOperator(context->GetWindowId());
7738 }
7739 }
7740
SendUecOnTreeEvent(int64_t splitElementId)7741 void JsAccessibilityManager::SendUecOnTreeEvent(int64_t splitElementId)
7742 {
7743 auto context = GetPipelineContext().Upgrade();
7744 CHECK_NULL_VOID(context);
7745 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
7746 CHECK_NULL_VOID(ngPipeline);
7747 auto rootNode = ngPipeline->GetRootElement();
7748 CHECK_NULL_VOID(rootNode);
7749 auto frameNode = GetFramenodeByAccessibilityId(rootNode, splitElementId);
7750 CHECK_NULL_VOID(frameNode);
7751
7752 if ((!frameNode) || (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode))) {
7753 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Register element is uec: %{public}s ", frameNode->GetTag().c_str());
7754 rootNode->OnAccessibilityEvent(AccessibilityEventType::CHANGE);
7755 } else {
7756 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Register element is not uec: %{public}s", frameNode->GetTag().c_str());
7757 }
7758 }
SetChildTreeIdAndWinId(const int64_t nodeId,const int32_t treeId,const int32_t childWindowId)7759 void JsAccessibilityManager::JsInteractionOperation::SetChildTreeIdAndWinId(
7760 const int64_t nodeId, const int32_t treeId, const int32_t childWindowId)
7761 {
7762 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
7763 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
7764 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(nodeId, splitElementId, splitTreeId);
7765 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetChildTreeId node: %{public}" PRId64 " treeId: %{public}d",
7766 splitElementId, treeId);
7767 auto jsAccessibilityManager = GetHandler().Upgrade();
7768 CHECK_NULL_VOID(jsAccessibilityManager);
7769 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
7770 CHECK_NULL_VOID(context);
7771 context->GetTaskExecutor()->PostTask(
7772 [weak = GetHandler(), splitElementId, treeId, childWindowId] {
7773 auto jsAccessibilityManager = weak.Upgrade();
7774 CHECK_NULL_VOID(jsAccessibilityManager);
7775 ACE_SCOPED_TRACE("SetChildTreeIdAndWinId");
7776 jsAccessibilityManager->NotifySetChildTreeIdAndWinId(splitElementId, treeId, childWindowId);
7777 },
7778 TaskExecutor::TaskType::UI, "ArkUISetChildTreeIdAndWinId");
7779 }
7780
SetBelongTreeId(const int32_t treeId)7781 void JsAccessibilityManager::JsInteractionOperation::SetBelongTreeId(const int32_t treeId)
7782 {
7783 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetBelongTreeId treeId: %{public}d", treeId);
7784 auto jsAccessibilityManager = GetHandler().Upgrade();
7785 CHECK_NULL_VOID(jsAccessibilityManager);
7786 jsAccessibilityManager->treeId_ = treeId;
7787 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
7788 CHECK_NULL_VOID(context);
7789 jsAccessibilityManager->SendCacheAccessibilityEvent(context->GetInstanceId());
7790 context->GetTaskExecutor()->PostTask(
7791 [weak = GetHandler(), treeId] {
7792 auto jsAccessibilityManager = weak.Upgrade();
7793 CHECK_NULL_VOID(jsAccessibilityManager);
7794 ACE_SCOPED_TRACE("SetBelongTreeId");
7795 jsAccessibilityManager->NotifyChildTreeOnRegister(treeId);
7796 },
7797 TaskExecutor::TaskType::UI, "ArkUIAccessibilityClearCurrentFocus");
7798 }
7799
UpdateElementInfoTreeId(Accessibility::AccessibilityElementInfo & info)7800 void JsAccessibilityManager::UpdateElementInfoTreeId(Accessibility::AccessibilityElementInfo& info)
7801 {
7802 int32_t treeId = info.GetBelongTreeId();
7803 if (treeId <= 0) {
7804 return;
7805 }
7806
7807 int64_t elementId = info.GetAccessibilityId();
7808 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId);
7809 info.SetAccessibilityId(elementId);
7810
7811 int64_t parentId = info.GetParentNodeId();
7812 if ((parentId != INVALID_PARENT_ID) && NeedChangeTreeId(parentId, treeId)) {
7813 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId);
7814 info.SetParent(parentId);
7815 }
7816
7817 UpdateElementInfoPageIdWithTreeId(info, treeId);
7818
7819 std::vector<int64_t> childIds = info.GetChildIds();
7820 for (int64_t child : childIds) {
7821 if (NeedChangeTreeId(child, treeId)) {
7822 info.RemoveChild(child);
7823 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, child);
7824 info.AddChild(child);
7825 }
7826 }
7827 }
7828
UpdateElementInfosTreeId(std::list<Accessibility::AccessibilityElementInfo> & infos,bool checkEmbed)7829 void JsAccessibilityManager::UpdateElementInfosTreeId(
7830 std::list<Accessibility::AccessibilityElementInfo>& infos, bool checkEmbed)
7831 {
7832 int32_t rootTreeId = INVALID_NODE_ID;
7833 for (auto& item : infos) {
7834 int32_t treeId = item.GetBelongTreeId();
7835 if (treeId <= 0) {
7836 continue;
7837 }
7838 if (rootTreeId == INVALID_NODE_ID) {
7839 rootTreeId = treeId;
7840 }
7841
7842 int64_t elementId = item.GetAccessibilityId();
7843 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId);
7844 item.SetAccessibilityId(elementId);
7845
7846 if (checkEmbed && (rootTreeId != INVALID_NODE_ID) && (rootTreeId != treeId)) {
7847 continue;
7848 }
7849
7850 int64_t parentId = item.GetParentNodeId();
7851 if (parentId != INVALID_PARENT_ID) {
7852 if (NeedChangeTreeId(parentId, treeId)) {
7853 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId);
7854 item.SetParent(parentId);
7855 }
7856 }
7857
7858 UpdateElementInfoPageIdWithTreeId(item, treeId);
7859 if (checkEmbed && IsTagInEmbedComponent(item.GetComponentType())) {
7860 continue;
7861 }
7862
7863 std::vector<int64_t> childIds = item.GetChildIds();
7864 for (int64_t child : childIds) {
7865 if (NeedChangeTreeId(child, treeId)) {
7866 item.RemoveChild(child);
7867 AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, child);
7868 item.AddChild(child);
7869 }
7870 }
7871 }
7872 }
7873
SetPipelineContext(const RefPtr<PipelineBase> & context)7874 void JsAccessibilityManager::SetPipelineContext(const RefPtr<PipelineBase>& context)
7875 {
7876 context_ = context;
7877 if (stateObserver_[AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED] != nullptr) {
7878 stateObserver_[AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED]->SetPipeline(context_);
7879 }
7880 }
7881
OnStateChanged(const bool state)7882 void JsAccessibilityManager::JsAccessibilityStateObserver::OnStateChanged(const bool state)
7883 {
7884 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "accessibility state changed:%{public}d, event type:%{public}u", state,
7885 eventType_);
7886
7887 // Do not upgrade jsAccessibilityManager on async thread, destructor will cause freeze
7888 auto pipelineRef = pipeline_.Upgrade();
7889 CHECK_NULL_VOID(pipelineRef);
7890 pipelineRef->GetTaskExecutor()->PostTask(
7891 [weak = accessibilityManager_, state, eventType = eventType_]() {
7892 auto jsAccessibilityManager = weak.Upgrade();
7893 CHECK_NULL_VOID(jsAccessibilityManager);
7894
7895 if (eventType == AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED) {
7896 auto client = AccessibilitySystemAbilityClient::GetInstance();
7897 if (client) {
7898 std::vector<uint32_t> needEvents;
7899 client->SearchNeedEvents(needEvents);
7900 jsAccessibilityManager->UpdateEventWhiteList(needEvents);
7901 }
7902 auto pipelineRef = jsAccessibilityManager->GetPipelineContext().Upgrade();
7903 if (jsAccessibilityManager->ShouldSkipAccessibilityStateChange(pipelineRef)) {
7904 return;
7905 }
7906
7907 if (state) {
7908 jsAccessibilityManager->RegisterInteractionOperation(jsAccessibilityManager->GetWindowId());
7909 } else {
7910 jsAccessibilityManager->DeregisterInteractionOperation();
7911 }
7912 AceApplicationInfo::GetInstance().SetAccessibilityEnabled(state);
7913 jsAccessibilityManager->NotifyAccessibilitySAStateChange(state);
7914 } else if (eventType == AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED) {
7915 jsAccessibilityManager->isScreenReaderEnabledInitialized_ = true;
7916 jsAccessibilityManager->isScreenReaderEnabled_ = state;
7917 AceApplicationInfo::GetInstance().SetAccessibilityScreenReadEnabled(state);
7918 } else if (eventType == AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED) {
7919 std::vector<uint32_t> needEvents;
7920 auto client = AccessibilitySystemAbilityClient::GetInstance();
7921 CHECK_NULL_VOID(client);
7922 client->SearchNeedEvents(needEvents);
7923 jsAccessibilityManager->UpdateEventWhiteList(needEvents);
7924 }
7925 },
7926 TaskExecutor::TaskType::UI, "ArkUIAccessibilityStateChanged");
7927 }
7928
FocusMoveSearch(int64_t elementId,const int32_t direction,const int32_t requestId,AccessibilityElementOperatorCallback & callback)7929 void JsAccessibilityManager::JsInteractionOperation::FocusMoveSearch(
7930 int64_t elementId, const int32_t direction, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
7931 {
7932 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "move search: %{public}" PRId64 ", direction: %{public}d",
7933 elementId, direction);
7934 int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
7935 int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
7936 AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
7937
7938 auto jsAccessibilityManager = GetHandler().Upgrade();
7939 CHECK_NULL_VOID(jsAccessibilityManager);
7940 auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
7941 CHECK_NULL_VOID(context);
7942 auto windowId = windowId_;
7943 context->GetTaskExecutor()->PostTask(
7944 [weak = GetHandler(), splitElementId, direction, requestId, &callback, windowId] {
7945 auto jsAccessibilityManager = weak.Upgrade();
7946 CHECK_NULL_VOID(jsAccessibilityManager);
7947 ACE_SCOPED_TRACE("FocusMoveSearch");
7948 jsAccessibilityManager->FocusMoveSearch(splitElementId, direction, requestId, callback, windowId);
7949 },
7950 TaskExecutor::TaskType::UI, "ArkUIAccessibilityFocusMoveSearch");
7951 }
7952
ShouldSkipAccessibilityStateChange(const RefPtr<PipelineBase> & pipelineRef)7953 bool JsAccessibilityManager::ShouldSkipAccessibilityStateChange(const RefPtr<PipelineBase>& pipelineRef)
7954 {
7955 CHECK_NULL_RETURN(pipelineRef, false);
7956 auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(pipelineRef);
7957 CHECK_NULL_RETURN(pipelineContext, false);
7958 auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
7959 if (container != nullptr && container->IsDynamicRender()) {
7960 return true;
7961 }
7962 if (pipelineContext->IsFormRender() || pipelineContext->IsJsCard() || pipelineContext->IsJsPlugin()) {
7963 return true;
7964 }
7965 if (container != nullptr && container->IsUIExtensionWindow()) {
7966 return true;
7967 }
7968 return false;
7969 }
7970
FocusMoveSearch(const int64_t elementId,const int32_t direction,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback,const int32_t windowId)7971 void JsAccessibilityManager::FocusMoveSearch(const int64_t elementId, const int32_t direction, const int32_t requestId,
7972 Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId)
7973 {
7974 AccessibilityElementInfo nodeInfo;
7975 auto context = GetPipelineByWindowId(windowId);
7976 if (!context) {
7977 nodeInfo.SetValidElement(false);
7978 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
7979 return;
7980 }
7981
7982 if (AceType::InstanceOf<NG::PipelineContext>(context)) {
7983 FocusMoveSearchNG(elementId, direction, nodeInfo, context, NG::UI_EXTENSION_OFFSET_MAX);
7984 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
7985 return;
7986 }
7987
7988 auto node = GetAccessibilityNodeFromPage(elementId);
7989 if (!node) {
7990 nodeInfo.SetValidElement(false);
7991 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
7992 return;
7993 }
7994
7995 // get root node.
7996 auto rootNode = node;
7997 while (rootNode->GetParentNode()) {
7998 rootNode = rootNode->GetParentNode();
7999 if (!rootNode->GetParentNode()) {
8000 break;
8001 }
8002 }
8003
8004 std::list<RefPtr<AccessibilityNode>> nodeList;
8005 AddFocusableNode(nodeList, rootNode);
8006 RefPtr<AccessibilityNode> resultNode;
8007
8008 switch (direction) {
8009 case FocusMoveDirection::FORWARD:
8010 case FocusMoveDirection::BACKWARD:
8011 // forward and backward
8012 resultNode = FindNodeInRelativeDirection(nodeList, node, direction);
8013 break;
8014 case FocusMoveDirection::UP:
8015 case FocusMoveDirection::DOWN:
8016 case FocusMoveDirection::LEFT:
8017 case FocusMoveDirection::RIGHT:
8018 // up, down, left and right
8019 resultNode = FindNodeInAbsoluteDirection(nodeList, node, direction);
8020 break;
8021 default:
8022 break;
8023 }
8024
8025 if (resultNode) {
8026 auto jsAccessibilityManager = Claim(this);
8027 UpdateAccessibilityNodeInfo(resultNode, nodeInfo, jsAccessibilityManager, windowId_);
8028 }
8029
8030 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
8031 }
8032
AddFocusableNode(std::list<RefPtr<AccessibilityNode>> & nodeList,const RefPtr<AccessibilityNode> & node)8033 void JsAccessibilityManager::AddFocusableNode(
8034 std::list<RefPtr<AccessibilityNode>>& nodeList, const RefPtr<AccessibilityNode>& node)
8035 {
8036 const std::string importance = node->GetImportantForAccessibility();
8037 if (CanAccessibilityFocused(node)) {
8038 nodeList.push_back(node);
8039 }
8040 if (!node->GetAccessible() && importance != "no-hide-descendants") {
8041 for (auto& child : node->GetChildList()) {
8042 AddFocusableNode(nodeList, child);
8043 }
8044 }
8045 }
8046
CanAccessibilityFocused(const RefPtr<AccessibilityNode> & node)8047 bool JsAccessibilityManager::CanAccessibilityFocused(const RefPtr<AccessibilityNode>& node)
8048 {
8049 return node != nullptr && !node->IsRootNode() && node->GetVisible() &&
8050 node->GetImportantForAccessibility() != "no" &&
8051 node->GetImportantForAccessibility() != "no-hide-descendants";
8052 }
8053
FindNodeInRelativeDirection(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node,const int direction)8054 RefPtr<AccessibilityNode> JsAccessibilityManager::FindNodeInRelativeDirection(
8055 const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node, const int direction)
8056 {
8057 switch (direction) {
8058 case FocusMoveDirection::FORWARD:
8059 return GetNextFocusableNode(nodeList, node);
8060 case FocusMoveDirection::BACKWARD:
8061 return GetPreviousFocusableNode(nodeList, node);
8062 default:
8063 break;
8064 }
8065
8066 return nullptr;
8067 }
8068
FindNodeInAbsoluteDirection(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node,const int direction)8069 RefPtr<AccessibilityNode> JsAccessibilityManager::FindNodeInAbsoluteDirection(
8070 const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node, const int direction)
8071 {
8072 auto tempBest = node->GetRect();
8073 auto nodeRect = node->GetRect();
8074
8075 switch (direction) {
8076 case FocusMoveDirection::LEFT:
8077 tempBest.SetLeft(node->GetLeft() + node->GetWidth() + 1);
8078 break;
8079 case FocusMoveDirection::RIGHT:
8080 tempBest.SetLeft(node->GetLeft() - node->GetWidth() - 1);
8081 break;
8082 case FocusMoveDirection::UP:
8083 tempBest.SetTop(node->GetTop() + node->GetHeight() + 1);
8084 break;
8085 case FocusMoveDirection::DOWN:
8086 tempBest.SetTop(node->GetTop() - node->GetHeight() - 1);
8087 break;
8088 default:
8089 break;
8090 }
8091
8092 RefPtr<AccessibilityNode> nearestNode = nullptr;
8093 for (auto nodeItem = nodeList.begin(); nodeItem != nodeList.end(); nodeItem++) {
8094 if ((*nodeItem)->GetNodeId() == node->GetNodeId() || (*nodeItem)->IsRootNode()) {
8095 continue;
8096 }
8097 auto itemRect = (*nodeItem)->GetRect();
8098 if (CheckBetterRect(nodeRect, direction, itemRect, tempBest)) {
8099 tempBest = itemRect;
8100 nearestNode = (*nodeItem);
8101 }
8102 }
8103
8104 return nearestNode;
8105 }
8106
GetNextFocusableNode(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node)8107 RefPtr<AccessibilityNode> JsAccessibilityManager::GetNextFocusableNode(
8108 const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node)
8109 {
8110 auto nodeItem = nodeList.begin();
8111 for (; nodeItem != nodeList.end(); nodeItem++) {
8112 if ((*nodeItem)->GetNodeId() == node->GetNodeId()) {
8113 break;
8114 }
8115 }
8116
8117 if (nodeItem != nodeList.end() && ++nodeItem != nodeList.end()) {
8118 return (*nodeItem);
8119 }
8120 if (!nodeList.empty()) {
8121 return (*nodeList.begin());
8122 }
8123
8124 return nullptr;
8125 }
8126
GetPreviousFocusableNode(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node)8127 RefPtr<AccessibilityNode> JsAccessibilityManager::GetPreviousFocusableNode(
8128 const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node)
8129 {
8130 auto nodeItem = nodeList.rbegin();
8131 for (; nodeItem != nodeList.rend(); nodeItem++) {
8132 if ((*nodeItem)->GetNodeId() == node->GetNodeId()) {
8133 break;
8134 }
8135 }
8136
8137 if (nodeItem != nodeList.rend() && ++nodeItem != nodeList.rend()) {
8138 return (*nodeItem);
8139 }
8140
8141 if (!nodeList.empty()) {
8142 return (*nodeList.rbegin());
8143 }
8144 return nullptr;
8145 }
8146
RequestAccessibilityFocus(const RefPtr<AccessibilityNode> & node)8147 bool JsAccessibilityManager::RequestAccessibilityFocus(const RefPtr<AccessibilityNode>& node)
8148 {
8149 auto requestNodeId = node->GetNodeId();
8150 if (currentFocusNodeId_ == requestNodeId) {
8151 return false;
8152 }
8153
8154 ClearCurrentFocus();
8155 currentFocusNodeId_ = requestNodeId;
8156 node->SetAccessibilityFocusedState(true);
8157 return node->ActionAccessibilityFocus(true);
8158 }
8159
ClearAccessibilityFocus(const RefPtr<AccessibilityNode> & node)8160 bool JsAccessibilityManager::ClearAccessibilityFocus(const RefPtr<AccessibilityNode>& node)
8161 {
8162 auto requestNodeId = node->GetNodeId();
8163 if (currentFocusNodeId_ != requestNodeId) {
8164 return false;
8165 }
8166
8167 currentFocusNodeId_ = -1;
8168 node->SetAccessibilityFocusedState(false);
8169 return node->ActionAccessibilityFocus(false);
8170 }
8171
ClearCurrentFocus()8172 bool JsAccessibilityManager::ClearCurrentFocus()
8173 {
8174 auto currentFocusNode = GetAccessibilityNodeFromPage(currentFocusNodeId_);
8175 CHECK_NULL_RETURN(currentFocusNode, false);
8176 currentFocusNodeId_ = -1;
8177 currentFocusNode->SetFocusedState(false);
8178 currentFocusNode->SetAccessibilityFocusedState(false);
8179 return currentFocusNode->ActionAccessibilityFocus(false);
8180 }
8181
FocusExtensionElementMoveSearchNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,Accessibility::AccessibilityElementInfo & info)8182 void FocusExtensionElementMoveSearchNG(const SearchParameter& searchParam,
8183 const RefPtr<NG::FrameNode>& node, Accessibility::AccessibilityElementInfo& info)
8184 {
8185 if (NG::UI_EXTENSION_OFFSET_MIN < (searchParam.uiExtensionOffset + 1)) {
8186 node->FocusMoveSearchNG(searchParam.nodeId, searchParam.mode,
8187 searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR, info);
8188 } else {
8189 info.SetValidElement(false);
8190 }
8191 }
8192
GetExtensionNextFocusableNode(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node)8193 void GetExtensionNextFocusableNode(const AccessibilityElementInfo& focusElement,
8194 const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node)
8195 {
8196 auto nodeItem = nodeList.begin();
8197 for (; nodeItem != nodeList.end(); nodeItem++) {
8198 if ((*nodeItem).GetAccessibilityId() == focusElement.GetAccessibilityId()) {
8199 break;
8200 }
8201 }
8202
8203 if (nodeItem != nodeList.end() && ++nodeItem != nodeList.end()) {
8204 node = (*nodeItem);
8205 }
8206 if (!nodeList.empty()) {
8207 node = (*nodeList.begin());
8208 }
8209 }
8210
GetExtensionPreviousFocusableNode(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node)8211 void GetExtensionPreviousFocusableNode(const AccessibilityElementInfo& focusElement,
8212 const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node)
8213 {
8214 auto nodeItem = nodeList.rbegin();
8215 for (; nodeItem != nodeList.rend(); nodeItem++) {
8216 if ((*nodeItem).GetAccessibilityId() == focusElement.GetAccessibilityId()) {
8217 break;
8218 }
8219 }
8220
8221 if (nodeItem != nodeList.rend() && ++nodeItem != nodeList.rend()) {
8222 node = (*nodeItem);
8223 }
8224
8225 if (!nodeList.empty()) {
8226 node = (*nodeList.rbegin());
8227 }
8228 }
8229
FindExtensionNodeInAbsoluteDirection(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node,int32_t direction)8230 void FindExtensionNodeInAbsoluteDirection(const AccessibilityElementInfo& focusElement,
8231 const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node, int32_t direction)
8232 {
8233 auto left = focusElement.GetRectInScreen().GetLeftTopXScreenPostion();
8234 auto top = focusElement.GetRectInScreen().GetLeftTopYScreenPostion();
8235 auto width = focusElement.GetRectInScreen().GetRightBottomXScreenPostion() -
8236 focusElement.GetRectInScreen().GetLeftTopXScreenPostion();
8237 auto height = focusElement.GetRectInScreen().GetRightBottomYScreenPostion() -
8238 focusElement.GetRectInScreen().GetLeftTopYScreenPostion();
8239 Rect rect(left, top, width, height);
8240 Rect tempBest(left, top, width, height);
8241 auto nodeRect = tempBest;
8242 switch (direction) {
8243 case FocusMoveDirection::LEFT:
8244 tempBest.SetLeft(left + width + 1);
8245 break;
8246 case FocusMoveDirection::RIGHT:
8247 tempBest.SetLeft(left - width - 1);
8248 break;
8249 case FocusMoveDirection::UP:
8250 tempBest.SetTop(top + height + 1);
8251 break;
8252 case FocusMoveDirection::DOWN:
8253 tempBest.SetTop(top - height - 1);
8254 break;
8255 default:
8256 break;
8257 }
8258 for (const auto& nodeItem : nodeList) {
8259 if (nodeItem.GetAccessibilityId() == focusElement.GetAccessibilityId() ||
8260 V2::ROOT_ETS_TAG == nodeItem.GetComponentType()) {
8261 continue;
8262 }
8263 left = nodeItem.GetRectInScreen().GetLeftTopXScreenPostion();
8264 top = nodeItem.GetRectInScreen().GetLeftTopYScreenPostion();
8265 width = nodeItem.GetRectInScreen().GetRightBottomXScreenPostion() -
8266 nodeItem.GetRectInScreen().GetLeftTopXScreenPostion();
8267 height = nodeItem.GetRectInScreen().GetRightBottomYScreenPostion() -
8268 nodeItem.GetRectInScreen().GetLeftTopYScreenPostion();
8269 Rect itemRect(left, top, width, height);
8270 if (CheckBetterRect(nodeRect, direction, itemRect, tempBest)) {
8271 tempBest = itemRect;
8272 node = nodeItem;
8273 }
8274 }
8275 }
8276
FindExtensionNodeInRelativeDirection(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node,int direction)8277 void FindExtensionNodeInRelativeDirection(const AccessibilityElementInfo& focusElement,
8278 const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node, int direction)
8279 {
8280 switch (direction) {
8281 case FocusMoveDirection::FORWARD:
8282 GetExtensionNextFocusableNode(focusElement, nodeList, node);
8283 break;
8284 case FocusMoveDirection::BACKWARD:
8285 GetExtensionPreviousFocusableNode(focusElement, nodeList, node);
8286 break;
8287 default:
8288 break;
8289 }
8290 }
8291
FilterAccessibilityElementByFocusable(std::list<AccessibilityElementInfo> & elementList,AccessibilityElementInfo & focusElement,int64_t elementId)8292 void FilterAccessibilityElementByFocusable(std::list<AccessibilityElementInfo>& elementList,
8293 AccessibilityElementInfo& focusElement, int64_t elementId)
8294 {
8295 auto input = elementList;
8296 elementList.clear();
8297 std::set<int64_t> filterIds;
8298 for (auto& element : input) {
8299 if (filterIds.find(element.GetParentNodeId()) != filterIds.end()) {
8300 filterIds.insert(element.GetAccessibilityId());
8301 continue;
8302 }
8303 auto width = element.GetRectInScreen().GetRightBottomXScreenPostion() -
8304 element.GetRectInScreen().GetLeftTopXScreenPostion();
8305 auto height = element.GetRectInScreen().GetRightBottomYScreenPostion() -
8306 element.GetRectInScreen().GetLeftTopYScreenPostion();
8307 if (width == 0 || height == 0) {
8308 filterIds.insert(element.GetAccessibilityId());
8309 continue;
8310 }
8311 elementList.emplace_back(element);
8312 if (element.GetAccessibilityId() == elementId) {
8313 focusElement = element;
8314 }
8315 }
8316 }
8317
GetResultOfFocusMoveSearchNG(int64_t elementId,int32_t direction,AccessibilityElementInfo & info)8318 void JsAccessibilityManager::GetResultOfFocusMoveSearchNG(
8319 int64_t elementId, int32_t direction, AccessibilityElementInfo& info)
8320 {
8321 auto pipeline = context_.Upgrade();
8322 CHECK_NULL_VOID(pipeline);
8323 std::list<AccessibilityElementInfo> nodeList;
8324 SearchElementInfoByAccessibilityIdNG(NG::UI_EXTENSION_ROOT_ID,
8325 PREFETCH_RECURSIVE_CHILDREN, nodeList, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
8326 AccessibilityElementInfo focusElement;
8327 FilterAccessibilityElementByFocusable(nodeList, focusElement, elementId);
8328 switch (direction) {
8329 case FocusMoveDirection::FORWARD:
8330 case FocusMoveDirection::BACKWARD:
8331 Framework::FindExtensionNodeInRelativeDirection(focusElement, nodeList, info, direction);
8332 break;
8333 case FocusMoveDirection::UP:
8334 case FocusMoveDirection::DOWN:
8335 case FocusMoveDirection::LEFT:
8336 case FocusMoveDirection::RIGHT:
8337 Framework::FindExtensionNodeInAbsoluteDirection(focusElement, nodeList, info, direction);
8338 break;
8339 default:
8340 break;
8341 }
8342 }
8343
FocusMoveSearchNG(int64_t elementId,int32_t direction,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const int64_t uiExtensionOffset)8344 void JsAccessibilityManager::FocusMoveSearchNG(int64_t elementId, int32_t direction,
8345 Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
8346 const int64_t uiExtensionOffset)
8347 {
8348 auto mainContext = context_.Upgrade();
8349 CHECK_NULL_VOID(mainContext);
8350 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
8351 CHECK_NULL_VOID(ngPipeline);
8352 auto rootNode = ngPipeline->GetRootElement();
8353 CHECK_NULL_VOID(rootNode);
8354 auto node = GetFramenodeByAccessibilityId(rootNode, elementId);
8355 info.SetValidElement(false);
8356 GetResultOfFocusMoveSearchNG(elementId, direction, info);
8357 }
8358
FocusExtensionElementMoveSearchNG(const SearchParameter & searchParam,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::FrameNode> & root,RefPtr<NG::FrameNode> & outputExtensionNode)8359 void JsAccessibilityManager::FocusExtensionElementMoveSearchNG(const SearchParameter& searchParam,
8360 Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
8361 const RefPtr<NG::FrameNode>& root, RefPtr<NG::FrameNode>& outputExtensionNode)
8362 {
8363 #ifdef WINDOW_SCENE_SUPPORTED
8364 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
8365 CHECK_NULL_VOID(ngPipeline);
8366 auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
8367 CHECK_NULL_VOID(uiExtensionManager);
8368 auto elementIdPair =
8369 uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset, searchParam.nodeId);
8370 outputExtensionNode = uiExtensionManager->GetFocusUiExtensionNode();
8371 CHECK_NULL_VOID(outputExtensionNode);
8372 SearchParameter transferSearchParam {elementIdPair.second, "",
8373 searchParam.mode, searchParam.uiExtensionOffset};
8374 OHOS::Ace::Framework::FocusExtensionElementMoveSearchNG(transferSearchParam, outputExtensionNode, info);
8375 AccessibilityElementInfo parentInfo;
8376 ConvertExtensionAccessibilityId(info, outputExtensionNode, searchParam.uiExtensionOffset, parentInfo);
8377 #endif
8378 }
8379
8380 // AccessibilitySystemAbilityClient will release callback after DeregisterElementOperator
SetSearchElementInfoByAccessibilityIdResult(AccessibilityElementOperatorCallback & callback,std::list<AccessibilityElementInfo> && infos,const int32_t requestId,bool checkEmbed)8381 void JsAccessibilityManager::SetSearchElementInfoByAccessibilityIdResult(AccessibilityElementOperatorCallback& callback,
8382 std::list<AccessibilityElementInfo>&& infos, const int32_t requestId, bool checkEmbed)
8383 {
8384 if (!IsRegister()) {
8385 return;
8386 }
8387 auto context = GetPipelineContext().Upgrade();
8388 CHECK_NULL_VOID(context);
8389 context->GetTaskExecutor()->PostTask(
8390 [weak = WeakClaim(this), infos = std::move(infos), &callback, requestId, checkEmbed] () mutable {
8391 auto jsAccessibilityManager = weak.Upgrade();
8392 CHECK_NULL_VOID(jsAccessibilityManager);
8393 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "winId: %{public}d, treeId: %{public}d, reqId: %{public}d",
8394 jsAccessibilityManager->windowId_, jsAccessibilityManager->treeId_, requestId);
8395 if (!jsAccessibilityManager->IsRegister()) {
8396 return;
8397 }
8398 jsAccessibilityManager->UpdateElementInfosTreeId(infos, checkEmbed);
8399 callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
8400 }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoById");
8401 }
8402
SetSearchElementInfoByCustomIdResult(AccessibilityElementOperatorCallback & callback,std::list<AccessibilityElementInfo> & infos,const std::list<AccessibilityElementInfo> & treeInfos,const int32_t requestId)8403 void JsAccessibilityManager::SetSearchElementInfoByCustomIdResult(AccessibilityElementOperatorCallback& callback,
8404 std::list<AccessibilityElementInfo> &infos, const std::list<AccessibilityElementInfo> &treeInfos,
8405 const int32_t requestId)
8406 {
8407 if (!IsRegister()) {
8408 return;
8409 }
8410 auto context = GetPipelineContext().Upgrade();
8411 CHECK_NULL_VOID(context);
8412 context->GetTaskExecutor()->PostTask(
8413 [weak = WeakClaim(this), infos = std::move(infos), treeInfos = std::move(treeInfos),
8414 &callback, requestId] () mutable {
8415 auto jsAccessibilityManager = weak.Upgrade();
8416 CHECK_NULL_VOID(jsAccessibilityManager);
8417 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "winId: %{public}d, treeId: %{public}d, reqId: %{public}d",
8418 jsAccessibilityManager->windowId_, jsAccessibilityManager->treeId_, requestId);
8419 if (!jsAccessibilityManager->IsRegister()) {
8420 return;
8421 }
8422 jsAccessibilityManager->UpdateElementInfosTreeId(infos);
8423 callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
8424 }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoById");
8425 return;
8426 }
8427
SetSearchElementInfoByTextResult(AccessibilityElementOperatorCallback & callback,std::list<AccessibilityElementInfo> && infos,const int32_t requestId)8428 void JsAccessibilityManager::SetSearchElementInfoByTextResult(AccessibilityElementOperatorCallback& callback,
8429 std::list<AccessibilityElementInfo>&& infos, const int32_t requestId)
8430 {
8431 if (!IsRegister()) {
8432 return;
8433 }
8434 auto context = GetPipelineContext().Upgrade();
8435 CHECK_NULL_VOID(context);
8436 context->GetTaskExecutor()->PostTask(
8437 [weak = WeakClaim(this), infos = std::move(infos), &callback, requestId] () mutable {
8438 auto jsAccessibilityManager = weak.Upgrade();
8439 CHECK_NULL_VOID(jsAccessibilityManager);
8440 if (!jsAccessibilityManager->IsRegister()) {
8441 return;
8442 }
8443 jsAccessibilityManager->UpdateElementInfosTreeId(infos);
8444 callback.SetSearchElementInfoByTextResult(infos, requestId);
8445 }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoByText");
8446 }
8447
SetSearchDefaultFocusByWindowIdResult(AccessibilityElementOperatorCallback & callback,std::list<AccessibilityElementInfo> && infos,const int32_t requestId)8448 void JsAccessibilityManager::SetSearchDefaultFocusByWindowIdResult(AccessibilityElementOperatorCallback& callback,
8449 std::list<AccessibilityElementInfo>&& infos, const int32_t requestId)
8450 {
8451 if (!IsRegister()) {
8452 return;
8453 }
8454 auto context = GetPipelineContext().Upgrade();
8455 CHECK_NULL_VOID(context);
8456 context->GetTaskExecutor()->PostTask(
8457 [weak = WeakClaim(this), infos = std::move(infos), &callback, requestId] () mutable {
8458 auto jsAccessibilityManager = weak.Upgrade();
8459 CHECK_NULL_VOID(jsAccessibilityManager);
8460 if (!jsAccessibilityManager->IsRegister()) {
8461 return;
8462 }
8463 jsAccessibilityManager->UpdateElementInfosTreeId(infos);
8464 callback.SetSearchDefaultFocusByWindowIdResult(infos, requestId);
8465 }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchDefaultFocusByWindowId");
8466 }
8467
SetFindFocusedElementInfoResult(AccessibilityElementOperatorCallback & callback,AccessibilityElementInfo & info,const int32_t requestId)8468 void JsAccessibilityManager::SetFindFocusedElementInfoResult(
8469 AccessibilityElementOperatorCallback& callback, AccessibilityElementInfo& info, const int32_t requestId)
8470 {
8471 if (IsRegister()) {
8472 UpdateElementInfoTreeId(info);
8473 callback.SetFindFocusedElementInfoResult(info, requestId);
8474 }
8475 }
8476
SetFocusMoveSearchResult(AccessibilityElementOperatorCallback & callback,AccessibilityElementInfo & info,const int32_t requestId)8477 void JsAccessibilityManager::SetFocusMoveSearchResult(
8478 AccessibilityElementOperatorCallback& callback, AccessibilityElementInfo& info, const int32_t requestId)
8479 {
8480 if (IsRegister()) {
8481 UpdateElementInfoTreeId(info);
8482 callback.SetFocusMoveSearchResult(info, requestId);
8483 }
8484 }
8485
SetFocusMoveResultWithNode(const WeakPtr<NG::FrameNode> & hostNode,AccessibilityElementOperatorCallback & callback,const int32_t requestId)8486 void JsAccessibilityManager::SetFocusMoveResultWithNode(
8487 const WeakPtr<NG::FrameNode>& hostNode, AccessibilityElementOperatorCallback& callback, const int32_t requestId)
8488 {
8489 if (!IsRegister()) {
8490 return;
8491 }
8492 AccessibilityElementInfo nodeInfo;
8493 auto host = hostNode.Upgrade();
8494 if (host) {
8495 auto context = host->GetContextRefPtr();
8496 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
8497 CommonProperty commonProperty;
8498 GenerateCommonProperty(ngPipeline, commonProperty, ngPipeline, host);
8499 UpdateAccessibilityElementInfo(host, commonProperty, nodeInfo, ngPipeline);
8500 } else {
8501 nodeInfo.SetValidElement(false);
8502 }
8503 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
8504 "SetFocusMoveResultWithNode : %{public}" PRId64, nodeInfo.GetAccessibilityId());
8505 SetFocusMoveSearchResult(callback, nodeInfo, requestId);
8506 }
8507
SetExecuteActionResult(AccessibilityElementOperatorCallback & callback,const bool succeeded,const int32_t requestId)8508 void JsAccessibilityManager::SetExecuteActionResult(
8509 AccessibilityElementOperatorCallback& callback, const bool succeeded, const int32_t requestId)
8510 {
8511 if (IsRegister()) {
8512 callback.SetExecuteActionResult(succeeded, requestId);
8513 }
8514 }
8515
GetPagePath()8516 std::string JsAccessibilityManager::GetPagePath()
8517 {
8518 auto context = context_.Upgrade();
8519 CHECK_NULL_RETURN(context, "");
8520 auto frontend = context->GetFrontend();
8521 CHECK_NULL_RETURN(frontend, "");
8522 ContainerScope scope(context->GetInstanceId());
8523 return frontend->GetPagePath();
8524 }
8525
IsUpdateWindowSceneInfo(const RefPtr<NG::FrameNode> & node,NG::WindowSceneInfo & windowSceneInfo)8526 bool JsAccessibilityManager::IsUpdateWindowSceneInfo(const RefPtr<NG::FrameNode>& node,
8527 NG::WindowSceneInfo& windowSceneInfo)
8528 {
8529 CHECK_NULL_RETURN(node, false);
8530 // update windowScene node commonProperty left, top position and get scale data
8531 auto parent = node->GetAncestorNodeOfFrame(false);
8532 if (node->GetTag() == V2::WINDOW_SCENE_ETS_TAG) {
8533 parent = node;
8534 }
8535
8536 while (parent) {
8537 // window scene with windowboundary property, is the same as window
8538 if ((parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) || (!parent->IsWindowBoundary())) {
8539 parent = parent->GetAncestorNodeOfFrame(false);
8540 continue;
8541 }
8542 auto accessibilityProperty = parent->GetAccessibilityProperty<NG::AccessibilityProperty>();
8543 if (accessibilityProperty) {
8544 accessibilityProperty->GetWindowScenePosition(windowSceneInfo);
8545 }
8546 TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
8547 "windowScene nodeId: %{public}" PRId64
8548 ", left: %{public}d, top: %{public}d, windowSceneScale: [%{public}f, %{public}f], "
8549 "innerWindowId:%{public}d, type: %{public}d",
8550 parent->GetAccessibilityId(), windowSceneInfo.left, windowSceneInfo.top,
8551 windowSceneInfo.scaleX, windowSceneInfo.scaleY, windowSceneInfo.innerWindowId,
8552 parent->GetWindowPatternType());
8553 return true;
8554 }
8555 return false;
8556 }
8557
UpdateElementInfoInnerWindowId(Accessibility::AccessibilityElementInfo & info,const int64_t & elementId)8558 void JsAccessibilityManager::UpdateElementInfoInnerWindowId(
8559 Accessibility::AccessibilityElementInfo& info, const int64_t& elementId)
8560 {
8561 auto node = FindNodeFromPipeline(context_, elementId);
8562 if (node) {
8563 NG::WindowSceneInfo windowSceneInfo;
8564 IsUpdateWindowSceneInfo(node, windowSceneInfo);
8565 info.SetInnerWindowId(windowSceneInfo.innerWindowId);
8566 }
8567 }
8568
GetPagePathInPageNodes(int32_t pageId,const std::vector<RefPtr<NG::FrameNode>> & pageNodes,const std::vector<std::string> pagePaths)8569 const std::string JsAccessibilityManager::GetPagePathInPageNodes(
8570 int32_t pageId,
8571 const std::vector<RefPtr<NG::FrameNode>>& pageNodes,
8572 const std::vector<std::string> pagePaths)
8573 {
8574 if (pagePaths.empty()) {
8575 return GetPagePath();
8576 }
8577 if (pagePaths.size() != pageNodes.size()) {
8578 return GetPagePath();
8579 }
8580 for (std::size_t i = 0; i < pageNodes.size(); ++i) {
8581 CHECK_NULL_CONTINUE(pageNodes[i]);
8582 if (pageId != pageNodes[i]->GetPageId()) {
8583 continue;
8584 }
8585 return pagePaths[i];
8586 }
8587 return GetPagePath();
8588 }
8589
GetCurrentWindowPages(const RefPtr<NG::PipelineContext> & ngPipeline,std::vector<RefPtr<NG::FrameNode>> & pageNodes,std::vector<std::string> & pagePaths)8590 void JsAccessibilityManager::GetCurrentWindowPages(
8591 const RefPtr<NG::PipelineContext>& ngPipeline,
8592 std::vector<RefPtr<NG::FrameNode>>& pageNodes,
8593 std::vector<std::string>& pagePaths)
8594 {
8595 CHECK_NULL_VOID(ngPipeline);
8596 auto stageManager = ngPipeline->GetStageManager();
8597 CHECK_NULL_VOID(stageManager);
8598 if (stageManager->IsSplitMode()) {
8599 pageNodes = stageManager->GetTopPagesWithTransition();
8600 pagePaths = stageManager->GetTopPagePaths();
8601 if (pageNodes.empty()) {
8602 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Split mode enable, cannot get page");
8603 }
8604 return;
8605 }
8606 auto page = stageManager->GetLastPageWithTransition();
8607 CHECK_NULL_VOID(page);
8608 pageNodes.push_back(page);
8609 pagePaths.push_back(GetPagePath());
8610 }
8611
UpdateWindowInfo(AccessibilityWindowInfo & windowInfo,const RefPtr<PipelineBase> & context)8612 void JsAccessibilityManager::UpdateWindowInfo(AccessibilityWindowInfo& windowInfo, const RefPtr<PipelineBase>& context)
8613 {
8614 CHECK_NULL_VOID(context);
8615 auto container = Platform::AceContainer::GetContainer(context->GetInstanceId());
8616 CHECK_NULL_VOID(container);
8617 auto singleHandTransform = container->GetSingleHandTransform();
8618 windowInfo.top = windowInfo.top * singleHandTransform.scaleY_ + singleHandTransform.y_;
8619 windowInfo.left = windowInfo.left * singleHandTransform.scaleX_ + singleHandTransform.x_;
8620 windowInfo.scaleX *= singleHandTransform.scaleX_;
8621 windowInfo.scaleY *= singleHandTransform.scaleY_;
8622 }
8623
GenerateWindowInfo(const RefPtr<NG::FrameNode> & node,const RefPtr<PipelineBase> & context)8624 AccessibilityWindowInfo JsAccessibilityManager::GenerateWindowInfo(const RefPtr<NG::FrameNode>& node,
8625 const RefPtr<PipelineBase>& context)
8626 {
8627 AccessibilityWindowInfo windowInfo;
8628 NG::WindowSceneInfo windowSceneInfo;
8629 if (IsUpdateWindowSceneInfo(node, windowSceneInfo)) {
8630 windowInfo.left = windowSceneInfo.left;
8631 windowInfo.top = windowSceneInfo.top;
8632 windowInfo.scaleX = windowSceneInfo.scaleX;
8633 windowInfo.scaleY = windowSceneInfo.scaleY;
8634 windowInfo.innerWindowId = windowSceneInfo.innerWindowId;
8635 return windowInfo;
8636 }
8637 RefPtr<NG::PipelineContext> ngPipeline;
8638 if (context) {
8639 ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
8640 } else {
8641 ngPipeline = AceType::DynamicCast<NG::PipelineContext>(GetPipelineContext().Upgrade());
8642 }
8643 CHECK_NULL_RETURN(ngPipeline, windowInfo);
8644 auto container = Platform::AceContainer::GetContainer(ngPipeline->GetInstanceId());
8645 if (container && !container->IsSubWindow()) {
8646 // subwindow by subpipeline, donot use getParentRectHandler when it is registered in mainpipeline
8647 if (getParentRectHandler_) {
8648 getParentRectHandler_(windowInfo.top, windowInfo.left);
8649 return windowInfo;
8650 } else if (getParentRectHandlerNew_) {
8651 if (IsReentrantLimit()) {
8652 return windowInfo;
8653 }
8654 SetReentrantLimit(true);
8655 AccessibilityParentRectInfo rectInfo;
8656 getParentRectHandlerNew_(rectInfo);
8657 windowInfo.top = rectInfo.top;
8658 windowInfo.left = rectInfo.left;
8659 windowInfo.scaleX = rectInfo.scaleX;
8660 windowInfo.scaleY = rectInfo.scaleY;
8661 windowInfo.rotateTransform = rectInfo.rotateTransform;
8662 SetReentrantLimit(false);
8663 return windowInfo;
8664 }
8665 }
8666 windowInfo.left = GetWindowLeft(ngPipeline->GetWindowId());
8667 windowInfo.top = GetWindowTop(ngPipeline->GetWindowId());
8668 if (container) {
8669 auto windowScale = container->GetWindowScale();
8670 windowInfo.scaleX = windowScale;
8671 windowInfo.scaleY = windowScale;
8672 }
8673 UpdateWindowInfo(windowInfo, ngPipeline);
8674
8675 return windowInfo;
8676 }
8677
GenerateCommonProperty(const RefPtr<PipelineBase> & context,CommonProperty & output,const RefPtr<PipelineBase> & mainContext,const RefPtr<NG::FrameNode> & node)8678 void JsAccessibilityManager::GenerateCommonProperty(const RefPtr<PipelineBase>& context, CommonProperty& output,
8679 const RefPtr<PipelineBase>& mainContext, const RefPtr<NG::FrameNode>& node)
8680 {
8681 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
8682 CHECK_NULL_VOID(ngPipeline);
8683 if (!ngPipeline->IsFormRender()) {
8684 output.windowId = static_cast<int32_t>(ngPipeline->GetRealHostWindowId());
8685 } else {
8686 output.windowId = static_cast<int32_t>(GetWindowId());
8687 }
8688
8689 auto windowInfo = GenerateWindowInfo(node, context);
8690 output.windowLeft = windowInfo.left;
8691 output.windowTop = windowInfo.top;
8692 scaleX_ = windowInfo.scaleX;
8693 scaleY_ = windowInfo.scaleY;
8694 output.scaleX = windowInfo.scaleX;
8695 output.scaleY = windowInfo.scaleY;
8696 output.innerWindowId = windowInfo.innerWindowId;
8697 output.rotateTransform = windowInfo.rotateTransform;
8698 // handle this time page info
8699 GetCurrentWindowPages(ngPipeline, output.pageNodes, output.pagePaths);
8700 if (context->GetWindowId() != mainContext->GetWindowId()) {
8701 output.pageNodes.clear();
8702 output.pagePaths.clear();
8703 }
8704
8705 output.checkGetFunc = [weak = WeakClaim(this)](const RefPtr<NG::FrameNode>& node) -> int64_t {
8706 auto jsAccessibilityManager = weak.Upgrade();
8707 CHECK_NULL_RETURN(jsAccessibilityManager, INVALID_NODE_ID);
8708 return jsAccessibilityManager->CheckAndGetEmbedFrameNode(node);
8709 };
8710 }
8711
GenerateCommonPropertyForWeb(const RefPtr<PipelineBase> & context,CommonProperty & output,const RefPtr<PipelineBase> & mainContext,const RefPtr<NG::FrameNode> & node)8712 void JsAccessibilityManager::GenerateCommonPropertyForWeb(const RefPtr<PipelineBase>& context, CommonProperty& output,
8713 const RefPtr<PipelineBase>& mainContext, const RefPtr<NG::FrameNode>& node)
8714 {
8715 GenerateCommonProperty(context, output, mainContext, node);
8716 auto parentRectInfo = GetTransformRectInfoRelativeToWindow(node, context);
8717 output.windowLeft = parentRectInfo.left;
8718 output.windowTop = parentRectInfo.top;
8719 output.rotateTransform = parentRectInfo.rotateTransform;
8720 output.scaleX = parentRectInfo.scaleX;
8721 output.scaleY = parentRectInfo.scaleY;
8722 }
8723
FindText(const RefPtr<NG::UINode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<NG::PipelineContext> & context,const CommonProperty & commonProperty,const SearchParameter & searchParam)8724 void JsAccessibilityManager::FindText(const RefPtr<NG::UINode>& node,
8725 std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<NG::PipelineContext>& context,
8726 const CommonProperty& commonProperty, const SearchParameter& searchParam)
8727 {
8728 CHECK_NULL_VOID(node);
8729 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
8730 if (frameNode && !frameNode->IsInternal()) {
8731 if (frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetGroupText().find(
8732 searchParam.text) != std::string::npos) {
8733 AccessibilityElementInfo nodeInfo;
8734 UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
8735 infos.emplace_back(nodeInfo);
8736 }
8737 }
8738 if (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode)) {
8739 auto infosByIPC = SearchElementInfosByTextNG(NG::UI_EXTENSION_ROOT_ID, searchParam.text,
8740 frameNode, searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
8741 if (!infosByIPC.empty()) {
8742 AccessibilityElementInfo nodeInfo;
8743 UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
8744 ConvertExtensionAccessibilityNodeId(infosByIPC, frameNode, searchParam.uiExtensionOffset, nodeInfo);
8745 for (auto& info : infosByIPC) {
8746 infos.emplace_back(info);
8747 }
8748 }
8749 }
8750 if (!node->GetChildren(true).empty()) {
8751 for (const auto& child : node->GetChildren(true)) {
8752 FindText(child, infos, context, commonProperty, searchParam);
8753 }
8754 }
8755 }
8756
FindTextByTextHint(const RefPtr<NG::UINode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<NG::PipelineContext> & context,const CommonProperty & commonProperty,const SearchParameter & searchParam)8757 void JsAccessibilityManager::FindTextByTextHint(const RefPtr<NG::UINode>& node,
8758 std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<NG::PipelineContext>& context,
8759 const CommonProperty& commonProperty, const SearchParameter& searchParam)
8760 {
8761 CHECK_NULL_VOID(node);
8762 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
8763 if (frameNode && !frameNode->IsInternal()) {
8764 std::string text = searchParam.text;
8765 nlohmann::json textJson = nlohmann::json::parse(text, nullptr, false);
8766 std::string value = "";
8767 if (!textJson.is_null() && !textJson.is_discarded() && textJson.contains("value")) {
8768 value = textJson["value"];
8769 }
8770 std::string textType = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetTextType();
8771 nlohmann::json textTypeJson = nlohmann::json::parse(textType, nullptr, false);
8772 if (!textTypeJson.is_null() && !textTypeJson.is_discarded() &&
8773 textTypeJson.contains("type") && textTypeJson["type"] == value) {
8774 AccessibilityElementInfo nodeInfo;
8775 UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
8776 infos.emplace_back(nodeInfo);
8777 }
8778 }
8779 if (IsIsolatedComponent(frameNode)) {
8780 auto infosByIPC = SearchElementInfosByTextNG(NG::UI_EXTENSION_ROOT_ID, searchParam.text,
8781 frameNode, searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
8782 if (!infosByIPC.empty()) {
8783 AccessibilityElementInfo nodeInfo;
8784 UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
8785 ConvertExtensionAccessibilityNodeId(infosByIPC, frameNode, searchParam.uiExtensionOffset, nodeInfo);
8786 for (auto& info : infosByIPC) {
8787 infos.emplace_back(info);
8788 }
8789 }
8790 }
8791 if (!node->GetChildren(true).empty()) {
8792 for (const auto& child : node->GetChildren(true)) {
8793 FindTextByTextHint(child, infos, context, commonProperty, searchParam);
8794 }
8795 }
8796 }
8797
CreateNodeInfoJson(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,std::unique_ptr<JsonValue> & json,int32_t childSize)8798 void JsAccessibilityManager::CreateNodeInfoJson(const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty,
8799 std::unique_ptr<JsonValue>& json, int32_t childSize)
8800 {
8801 CHECK_NULL_VOID(node);
8802 auto child = JsonUtil::Create(true);
8803 child->Put("childSize", childSize);
8804 child->Put("ID", node->GetAccessibilityId());
8805 child->Put("compid", node->GetInspectorId().value_or("").c_str());
8806 auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
8807 if (accessibilityProperty) {
8808 child->Put("text", accessibilityProperty->GetGroupText().c_str());
8809 child->Put("accessibilityText", accessibilityProperty->GetAccessibilityText().c_str());
8810 child->Put("accessibilityGroup", accessibilityProperty->IsAccessibilityGroup());
8811 child->Put("accessibilityLevel", accessibilityProperty->GetAccessibilityLevel().c_str());
8812 }
8813 NG::RectF rect = node->GetTransformRectRelativeToWindow(true);
8814 child->Put("top", rect.Top() + commonProperty.windowTop);
8815 child->Put("left", rect.Left() + commonProperty.windowLeft);
8816 child->Put("width", rect.Width());
8817 child->Put("height", rect.Height());
8818 child->Put("visible", node->IsVisible());
8819 auto eventHub = node->GetOrCreateEventHub<NG::EventHub>();
8820 if (eventHub) {
8821 auto gestureEventHub = eventHub->GetGestureEventHub();
8822 child->Put("clickable", gestureEventHub ? gestureEventHub->IsAccessibilityClickable() : false);
8823 child->Put("longclickable", gestureEventHub ? gestureEventHub->IsAccessibilityLongClickable() : false);
8824 }
8825 if (accessibilityProperty) {
8826 child->Put("checkable", accessibilityProperty->IsCheckable());
8827 child->Put("scrollable", accessibilityProperty->IsScrollable());
8828 child->Put("checked", accessibilityProperty->IsChecked());
8829 child->Put("hint", accessibilityProperty->GetHintText().c_str());
8830 child->Put("childTree", accessibilityProperty->GetChildTreeId());
8831 }
8832 std::string tag =
8833 node->GetTag() == "root" ? "root" : node->GetTag() + "_" + std::to_string(node->GetAccessibilityId());
8834 json->Put(tag.c_str(), child);
8835 }
8836
DumpTreeNodeInfoInJson(const RefPtr<NG::FrameNode> & node,int32_t depth,const CommonProperty & commonProperty,int32_t childSize)8837 void JsAccessibilityManager::DumpTreeNodeInfoInJson(
8838 const RefPtr<NG::FrameNode>& node, int32_t depth, const CommonProperty& commonProperty, int32_t childSize)
8839 {
8840 auto json = JsonUtil::Create(true);
8841 CreateNodeInfoJson(node, commonProperty, json, childSize);
8842 std::string content = DumpLog::GetInstance().FormatDumpInfo(json->ToString(), depth);
8843 std::string prefix = DumpLog::GetInstance().GetPrefix(depth);
8844 std::string fulljson = prefix.append(content);
8845 DumpLog::GetInstance().PrintJson(fulljson);
8846 }
8847
8848
TransferThirdProviderHoverEvent(const WeakPtr<NG::FrameNode> & hostNode,const NG::PointF & point,SourceType source,NG::AccessibilityHoverEventType eventType,TimeStamp time)8849 void JsAccessibilityManager::TransferThirdProviderHoverEvent(
8850 const WeakPtr<NG::FrameNode>& hostNode, const NG::PointF& point, SourceType source,
8851 NG::AccessibilityHoverEventType eventType, TimeStamp time)
8852 {
8853 auto pipelineContext = GetPipelineContext().Upgrade();
8854 CHECK_NULL_VOID(pipelineContext);
8855 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
8856 CHECK_NULL_VOID(ngPipeline);
8857 auto frameNode = hostNode.Upgrade();
8858 CHECK_NULL_VOID(frameNode);
8859 AccessibilityHoverForThirdConfig config;
8860 config.hostElementId = frameNode->GetAccessibilityId();
8861 config.point = point;
8862 config.sourceType = source;
8863 config.eventType = eventType;
8864 config.time = time;
8865 config.context = ngPipeline;
8866 HandleAccessibilityHoverForThird(config);
8867 }
8868
OnDumpChildInfoForThird(int64_t hostElementId,const std::vector<std::string> & params,std::vector<std::string> & info)8869 bool JsAccessibilityManager::OnDumpChildInfoForThird(
8870 int64_t hostElementId,
8871 const std::vector<std::string>& params,
8872 std::vector<std::string>& info)
8873 {
8874 return OnDumpChildInfoForThirdRecursive(hostElementId, params, info, WeakClaim(this));
8875 }
8876
8877 #ifdef WEB_SUPPORTED
GetWebCursorPosition(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const RefPtr<NG::WebPattern> & webPattern)8878 void JsAccessibilityManager::GetWebCursorPosition(const int64_t elementId, const int32_t requestId,
8879 AccessibilityElementOperatorCallback& callback, const RefPtr<NG::WebPattern>& webPattern)
8880 {
8881 CHECK_NULL_VOID(webPattern);
8882 auto node = webPattern->GetTransitionalNodeById(elementId);
8883 CHECK_NULL_VOID(node);
8884
8885 callback.SetCursorPositionResult(node->GetSelectionStart(), requestId);
8886 }
8887 #endif // WEB_SUPPORTED
8888
FireAccessibilityEventCallback(uint32_t eventId,int64_t parameter)8889 void JsAccessibilityManager::FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter)
8890 {
8891 auto eventType = static_cast<AccessibilityCallbackEventId>(eventId);
8892 AccessibilityEvent event;
8893 switch (eventType) {
8894 case AccessibilityCallbackEventId::ON_LOAD_PAGE:
8895 event.nodeId = parameter;
8896 event.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
8897 event.type = AccessibilityEventType::CHANGE;
8898 SendAccessibilityAsyncEvent(event);
8899 break;
8900 default:
8901 break;
8902 }
8903 }
8904
GetTransformDegreeRelativeToWindow(const RefPtr<NG::FrameNode> & node,bool excludeSelf)8905 int32_t JsAccessibilityManager::GetTransformDegreeRelativeToWindow(const RefPtr<NG::FrameNode>& node, bool excludeSelf)
8906 {
8907 int32_t rotateDegree = 0;
8908 auto context = node->GetRenderContext();
8909 if (context && !excludeSelf) {
8910 rotateDegree = context->GetRotateDegree();
8911 }
8912 auto parent = node->GetAncestorNodeOfFrame(true);
8913 while (parent) {
8914 if (parent->IsWindowBoundary()) {
8915 break;
8916 }
8917 auto contextParent = parent->GetRenderContext();
8918 if (contextParent) {
8919 rotateDegree += contextParent->GetRotateDegree();
8920 }
8921 parent = parent->GetAncestorNodeOfFrame(true);
8922 }
8923 return ((rotateDegree % FULL_ANGLE + FULL_ANGLE) % FULL_ANGLE);
8924 }
8925
GetTransformRectInfoRelativeToWindow(const RefPtr<NG::FrameNode> & node,const RefPtr<PipelineBase> & context)8926 AccessibilityParentRectInfo JsAccessibilityManager::GetTransformRectInfoRelativeToWindow(
8927 const RefPtr<NG::FrameNode>& node, const RefPtr<PipelineBase>& context)
8928 {
8929 AccessibilityParentRectInfo rectInfo;
8930 CHECK_NULL_RETURN(node, rectInfo);
8931 auto finalScale = node->GetTransformScaleRelativeToWindow();
8932 rectInfo.scaleX = finalScale.x;
8933 rectInfo.scaleY = finalScale.y;
8934 CHECK_NULL_RETURN(context, rectInfo);
8935 auto windowInfo = GenerateWindowInfo(node, context);
8936 auto rectFinal = GetFinalRealRect(node);
8937 RotateTransform rotateData;
8938 RotateTransform windowRotateData = windowInfo.rotateTransform;
8939 rotateData.rotateDegree = GetTransformDegreeRelativeToWindow(node);
8940 AccessibilityRect rotateRect(rectFinal.GetX(), rectFinal.GetY(),
8941 rectFinal.Width(), rectFinal.Height());
8942 if (windowRotateData.rotateDegree) {
8943 rotateRect.Rotate(windowRotateData.innerCenterX, windowRotateData.innerCenterY,
8944 windowRotateData.rotateDegree);
8945 rotateRect.ApplyTransformation(windowRotateData, windowInfo.scaleX, windowInfo.scaleY);
8946 rotateData.rotateDegree += windowRotateData.rotateDegree;
8947 } else {
8948 RotateTransform roateDataTemp(0, windowInfo.left, windowInfo.top, 0, 0);
8949 rotateRect.ApplyTransformation(roateDataTemp, windowInfo.scaleX, windowInfo.scaleY);
8950 }
8951 rectInfo.left = rotateRect.GetX();
8952 rectInfo.top = rotateRect.GetY();
8953 rectInfo.scaleX *= windowInfo.scaleX;
8954 rectInfo.scaleY *= windowInfo.scaleY;
8955 if (rotateData.rotateDegree) {
8956 rotateData.centerX = static_cast<int32_t>(rotateRect.GetWidth()) * 0.5f + rotateRect.GetX();
8957 rotateData.centerY = static_cast<int32_t>(rotateRect.GetHeight()) * 0.5f + rotateRect.GetY();
8958 auto renderContext = node->GetRenderContext();
8959 CHECK_NULL_RETURN(renderContext, rectInfo);
8960 auto rectOrigin = renderContext->GetPaintRectWithoutTransform();
8961 rotateData.innerCenterX = rectOrigin.Width() * 0.5f;
8962 rotateData.innerCenterY = rectOrigin.Height() * 0.5f;
8963 }
8964 rectInfo.rotateTransform = rotateData;
8965 return rectInfo;
8966 }
8967
UpdateAccessibilityNodeRect(const RefPtr<NG::FrameNode> & frameNode)8968 void JsAccessibilityManager::UpdateAccessibilityNodeRect(const RefPtr<NG::FrameNode>& frameNode)
8969 {
8970 auto accessibilityWorkMode = GenerateAccessibilityWorkMode();
8971 if (!accessibilityWorkMode.isTouchExplorationEnabled) {
8972 return;
8973 }
8974 CHECK_NULL_VOID(frameNode);
8975 auto renderContext = frameNode->GetRenderContext();
8976 CHECK_NULL_VOID(renderContext);
8977 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
8978 CHECK_NULL_VOID(accessibilityProperty);
8979 auto isFocus = accessibilityProperty->GetAccessibilityFocusState();
8980 if (isFocus && !frameNode->IsAccessibilityVirtualNode() && !frameNode->IsDrawFocusOnTop()) {
8981 if (accessibilityProperty->IsMatchAccessibilityResponseRegion(false)) {
8982 auto rectInt = accessibilityProperty->GetAccessibilityResponseRegionRect(false);
8983 renderContext->UpdateAccessibilityFocusRect(rectInt);
8984 } else {
8985 renderContext->UpdateAccessibilityRoundRect();
8986 }
8987 } else {
8988 RefPtr<NG::FrameNode> focusFrameNode = nullptr;
8989 auto checkflag = CheckChildIsAccessibilityFocus(frameNode, focusFrameNode);
8990 if (checkflag && focusFrameNode && focusFrameNode->IsDrawFocusOnTop()) {
8991 UpdatePaintNodeRender(focusFrameNode);
8992 }
8993 }
8994 }
8995
OnAccessbibilityDetachFromMainTree(const RefPtr<NG::FrameNode> & focusNode)8996 void JsAccessibilityManager::OnAccessbibilityDetachFromMainTree(const RefPtr<NG::FrameNode>& focusNode)
8997 {
8998 auto paintNode = focusNode->GetPaintNode();
8999 CHECK_NULL_VOID(paintNode);
9000 auto paintNodePattern = AceType::DynamicCast<NG::AccessibilityFocusPaintNodePattern>(paintNode->GetPattern());
9001 CHECK_NULL_VOID(paintNodePattern);
9002 auto currentFocusNode = paintNodePattern->GetFocusNode().Upgrade();
9003 CHECK_NULL_VOID(currentFocusNode);
9004 if (currentFocusNode->GetId() == focusNode->GetId()) {
9005 paintNodePattern->OnDetachFromFocusNode();
9006 RemoveAccessibilityFocusPaint(focusNode);
9007 }
9008 }
9009
CheckAccessibilityVisible(const RefPtr<NG::FrameNode> & node)9010 bool JsAccessibilityManager::CheckAccessibilityVisible(const RefPtr<NG::FrameNode>& node)
9011 {
9012 UpdateAccessibilityVisibleToRoot(node);
9013 CHECK_NULL_RETURN(node, true);
9014 return node->GetAccessibilityVisible();
9015 }
9016
IsScreenReaderEnabled()9017 bool JsAccessibilityManager::IsScreenReaderEnabled()
9018 {
9019 if (!isScreenReaderEnabledInitialized_) {
9020 auto client = AccessibilitySystemAbilityClient::GetInstance();
9021 if (client) {
9022 client->IsScreenReaderEnabled(isScreenReaderEnabled_);
9023 isScreenReaderEnabledInitialized_ = true;
9024 }
9025 }
9026 return isScreenReaderEnabled_;
9027 }
9028
SearchElementInfoBySurfaceId(const std::string & surfaceId,const int32_t windowId,const SearchSurfaceIdType searchType,std::list<AccessibilityElementInfo> & infos)9029 SearchSurfaceIdRet JsAccessibilityManager::SearchElementInfoBySurfaceId(
9030 const std::string& surfaceId, const int32_t windowId,
9031 const SearchSurfaceIdType searchType, std::list<AccessibilityElementInfo>& infos)
9032 {
9033 auto pipeline = GetPipelineByWindowId(windowId);
9034 CHECK_NULL_RETURN(pipeline, SearchSurfaceIdRet::NO_MATCH_NODE);
9035 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
9036 CHECK_NULL_RETURN(ngPipeline, SearchSurfaceIdRet::NO_MATCH_NODE);
9037
9038 auto node = GetEmbedNodeBySurfaceId(surfaceId).Upgrade();
9039 CHECK_NULL_RETURN(node, SearchSurfaceIdRet::NO_MATCH_NODE);
9040
9041 if (searchType != SearchSurfaceIdType::SEARCH_TAIL) {
9042 auto mode = searchType == SearchSurfaceIdType::SEARCH_ALL ?
9043 static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN) : 0;
9044 SearchElementInfoByAccessibilityIdNG(
9045 node->GetAccessibilityId(), mode, infos, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
9046 UpdateElementInfosTreeId(infos);
9047 return SearchSurfaceIdRet::SEARCH_SUCCESS;
9048 }
9049
9050 auto mainContext = context_.Upgrade();
9051 CHECK_NULL_RETURN(mainContext, SearchSurfaceIdRet::NO_MATCH_NODE);
9052 CommonProperty commonProperty;
9053 GenerateCommonProperty(pipeline, commonProperty, mainContext, node);
9054 UpdateAccessibilityVisibleToRoot(node);
9055 commonProperty.checkEmbedNode = false;
9056 auto lastNode = GetLastChildFrameNode(node, commonProperty);
9057 CHECK_NULL_RETURN(lastNode, SearchSurfaceIdRet::NO_MATCH_NODE);
9058
9059 AccessibilityElementInfo elementInfo;
9060 UpdateAccessibilityElementInfo(lastNode, commonProperty, elementInfo, ngPipeline);
9061 SetRootAccessibilityVisible(lastNode, elementInfo);
9062 SetRootAccessibilityNextFocusId(lastNode, node, elementInfo);
9063 SetRootAccessibilityPreFocusId(lastNode, node, elementInfo, nextFocusMapWithSubWindow_[pipeline->GetInstanceId()]);
9064 infos.push_back(elementInfo);
9065 UpdateElementInfosTreeId(infos);
9066 return SearchSurfaceIdRet::SEARCH_SUCCESS;
9067 }
9068
GetWebPatternBySurfaceId(const std::string & surfaceId)9069 WeakPtr<NG::WebPattern> JsAccessibilityManager::GetWebPatternBySurfaceId(const std::string& surfaceId)
9070 {
9071 std::lock_guard<std::mutex> lock(webPatternMapMutex_);
9072 auto it = webPatternMap_.find(surfaceId);
9073 if (it != webPatternMap_.end()) {
9074 return it->second;
9075 }
9076 return WeakPtr<NG::WebPattern>();
9077 }
9078
SetWebPatternBySurfaceId(const std::string & surfaceId,WeakPtr<NG::WebPattern> pattern)9079 void JsAccessibilityManager::SetWebPatternBySurfaceId(const std::string& surfaceId, WeakPtr<NG::WebPattern> pattern)
9080 {
9081 std::lock_guard<std::mutex> lock(webPatternMapMutex_);
9082 webPatternMap_[surfaceId] = pattern;
9083 }
9084
RemoveWebPatternBySurfaceId(const std::string & surfaceId)9085 void JsAccessibilityManager::RemoveWebPatternBySurfaceId(const std::string& surfaceId)
9086 {
9087 if (!surfaceId.empty()) {
9088 std::lock_guard<std::mutex> lock(webPatternMapMutex_);
9089 auto it = webPatternMap_.find(surfaceId);
9090 if (it != webPatternMap_.end()) {
9091 webPatternMap_.erase(it);
9092 }
9093 }
9094 }
9095
CheckWhiteList(const uint32_t & eventType)9096 bool JsAccessibilityManager::CheckWhiteList(const uint32_t& eventType)
9097 {
9098 auto whiteList = eventWhiteList_;
9099 if (whiteList.size() == 0) {
9100 return true;
9101 }
9102
9103 if (whiteList.size() == 1) {
9104 if (whiteList[0] == Accessibility::EventType::TYPE_VIEW_INVALID) {
9105 return false;
9106 } else if (whiteList[0] == Accessibility::EventType::TYPES_ALL_MASK) {
9107 return true;
9108 }
9109 }
9110 return std::find(whiteList.begin(), whiteList.end(), eventType) != whiteList.end();
9111 }
9112
SearchAccessibilityNodeBySpecificProperty(const int64_t elementId,const SpecificPropertyParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)9113 void JsAccessibilityManager::SearchAccessibilityNodeBySpecificProperty(const int64_t elementId,
9114 const SpecificPropertyParam ¶m, const int32_t requestId,
9115 AccessibilityElementOperatorCallback &callback, const int32_t windowId)
9116 {
9117 std::list<AccessibilityElementInfo> infos;
9118 std::list<AccessibilityElementInfo> treeInfos;
9119
9120 if (param.propertyType != SEARCH_TYPE::CUSTOMID) {
9121 SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId);
9122 return;
9123 }
9124
9125 auto pipeline = GetPipelineByWindowId(windowId);
9126 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
9127 if (!ngPipeline) {
9128 SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId);
9129 return;
9130 }
9131 auto rootNode = ngPipeline->GetRootElement();
9132
9133 int64_t nodeId = elementId;
9134 if (elementId == -1) {
9135 nodeId = rootNode->GetAccessibilityId();
9136 }
9137 auto weak = WeakClaim(this);
9138 auto jsAccessibilityManager = weak.Upgrade();
9139 CHECK_NULL_VOID(jsAccessibilityManager);
9140 auto node = jsAccessibilityManager->GetAccessibilityNodeFromPage(nodeId);
9141 if (!node) {
9142 SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId);
9143 return;
9144 }
9145 std::list<AccessibilityElementInfo> nodeInfos;
9146 AccessibilityElementInfo nodeInfo;
9147 UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager, jsAccessibilityManager->windowId_);
9148 nodeInfos.push_back(nodeInfo);
9149 // cache parent/siblings/children infos
9150 UpdateCacheInfo(
9151 infos,
9152 static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN),
9153 node,
9154 jsAccessibilityManager,
9155 jsAccessibilityManager->windowId_);
9156
9157 for (auto& nodeInfo : nodeInfos) {
9158 if (nodeInfo.GetInspectorKey() == param.propertyTarget) {
9159 infos.emplace_back(nodeInfo);
9160 break;
9161 }
9162 }
9163 SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId);
9164 return;
9165 }
9166 } // namespace OHOS::Ace::Framework
9167