• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &params)
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 &param, 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 &param, 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 &param, 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> &params,
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 &param, 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