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