• 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 <algorithm>
19 
20 #include "accessibility_constants.h"
21 #include "accessibility_event_info.h"
22 #include "accessibility_system_ability_client.h"
23 
24 #include "adapter/ohos/entrance/ace_application_info.h"
25 #include "adapter/ohos/entrance/ace_container.h"
26 #include "base/log/ace_trace.h"
27 #include "base/log/dump_log.h"
28 #include "base/log/event_report.h"
29 #include "base/log/log.h"
30 #include "base/utils/linear_map.h"
31 #include "base/utils/string_utils.h"
32 #include "base/utils/utils.h"
33 #include "core/components_ng/base/inspector.h"
34 #include "core/components_v2/inspector/inspector_constants.h"
35 #include "core/pipeline/pipeline_context.h"
36 #include "core/pipeline_ng/pipeline_context.h"
37 #include "frameworks/bridge/common/dom/dom_type.h"
38 #include "frameworks/core/components_ng/pattern/web/web_pattern.h"
39 #include "js_third_provider_interaction_operation.h"
40 #include "nlohmann/json.hpp"
41 
42 using namespace OHOS::Accessibility;
43 using namespace OHOS::AccessibilityConfig;
44 using namespace std;
45 
46 namespace OHOS::Ace::Framework {
47 namespace {
48 const char DUMP_ORDER[] = "-accessibility";
49 const char DUMP_INSPECTOR[] = "-inspector";
50 const char ACCESSIBILITY_FOCUSED_EVENT[] = "accessibilityfocus";
51 const char ACCESSIBILITY_CLEAR_FOCUS_EVENT[] = "accessibilityclearfocus";
52 const char TEXT_CHANGE_EVENT[] = "textchange";
53 const char PAGE_CHANGE_EVENT[] = "pagechange";
54 const char SCROLL_END_EVENT[] = "scrollend";
55 const char SCROLL_START_EVENT[] = "scrollstart";
56 const char MOUSE_HOVER_ENTER[] = "mousehoverenter";
57 const char MOUSE_HOVER_EXIT[] = "mousehoverexit";
58 const char LIST_TAG[] = "List";
59 const char SIDEBARCONTAINER_TAG[] = "SideBarContainer";
60 const char STRING_DIR_FORWARD[] = "forward";
61 const char STRING_DIR_BACKWARD[] = "backward";
62 constexpr int32_t INVALID_PARENT_ID = -2100000;
63 constexpr int32_t DEFAULT_PARENT_ID = 2100000;
64 constexpr int32_t ROOT_STACK_BASE = 1100000;
65 constexpr int32_t ROOT_DECOR_BASE = 3100000;
66 constexpr int32_t CARD_NODE_ID_RATION = 10000;
67 constexpr int32_t CARD_ROOT_NODE_ID_RATION = 1000;
68 constexpr int32_t CARD_BASE = 100000;
69 constexpr int32_t DELAY_SEND_EVENT_MILLISECOND = 20;
70 constexpr uint32_t SUB_TREE_OFFSET_IN_PAGE_ID = 16;
71 constexpr int32_t MAX_PAGE_ID_WITH_SUB_TREE = (1 << SUB_TREE_OFFSET_IN_PAGE_ID);
72 
73 const std::string ACTION_ARGU_SCROLL_STUB = "scrolltype"; // wait for change
74 const std::string ACTION_DEFAULT_PARAM = "ACCESSIBILITY_ACTION_INVALID";
75 
76 const std::map<Accessibility::ActionType, std::function<bool(const AccessibilityActionParam& param)>> ACTIONS = {
77     { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD,
__anon4006d4cc0202() 78         [](const AccessibilityActionParam& param) {
79             return param.accessibilityProperty->ActActionScrollForward(param.scrollType);
80         } },
81     { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD,
__anon4006d4cc0302() 82         [](const AccessibilityActionParam& param) {
83             return param.accessibilityProperty->ActActionScrollBackward(param.scrollType);
84         } },
85     { ActionType::ACCESSIBILITY_ACTION_SET_TEXT,
__anon4006d4cc0402() 86         [](const AccessibilityActionParam& param) {
87             return param.accessibilityProperty->ActActionSetText(param.setTextArgument);
88         } },
89     { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION,
__anon4006d4cc0502() 90         [](const AccessibilityActionParam& param) {
91             return param.accessibilityProperty->ActActionSetSelection(param.setSelectionStart,
92                                                                       param.setSelectionEnd, param.setSelectionDir);
93         } },
94     { ActionType::ACCESSIBILITY_ACTION_COPY,
__anon4006d4cc0602() 95         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionCopy(); } },
96     { ActionType::ACCESSIBILITY_ACTION_CUT,
__anon4006d4cc0702() 97         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionCut(); } },
98     { ActionType::ACCESSIBILITY_ACTION_PASTE,
__anon4006d4cc0802() 99         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionPaste(); } },
100     { ActionType::ACCESSIBILITY_ACTION_CLICK,
__anon4006d4cc0902() 101         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionClick(); } },
102     { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK,
__anon4006d4cc0a02() 103         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionLongClick(); } },
104     { ActionType::ACCESSIBILITY_ACTION_SELECT,
__anon4006d4cc0b02() 105         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionSelect(); } },
106     { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION,
__anon4006d4cc0c02() 107         [](const AccessibilityActionParam& param) { return param.accessibilityProperty->ActActionClearSelection(); } },
108     { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT,
__anon4006d4cc0d02() 109         [](const AccessibilityActionParam& param) {
110             return param.accessibilityProperty->ActActionMoveText(static_cast<int32_t>(param.moveUnit), true);
111         } },
112     { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT,
__anon4006d4cc0e02() 113         [](const AccessibilityActionParam& param) {
114             return param.accessibilityProperty->ActActionMoveText(static_cast<int32_t>(param.moveUnit), false);
115         } },
116     { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION,
__anon4006d4cc0f02() 117         [](const AccessibilityActionParam& param) {
118             return param.accessibilityProperty->ActActionSetIndex(static_cast<int32_t>(param.setCursorIndex));
119         } },
120     { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK,
__anon4006d4cc1002() 121         [](const AccessibilityActionParam& param) {
122             return param.accessibilityProperty->ActActionExecSubComponent(static_cast<int32_t>(param.spanId));
123         } },
124 };
125 
IsExtensionComponent(const RefPtr<NG::UINode> & node)126 bool IsExtensionComponent(const RefPtr<NG::UINode>& node)
127 {
128     return node && (node->GetTag() == V2::UI_EXTENSION_COMPONENT_ETS_TAG
129         || node->GetTag() == V2::EMBEDDED_COMPONENT_ETS_TAG
130         || node->GetTag() == V2::ISOLATED_COMPONENT_ETS_TAG);
131 }
132 
IsIsolatedComponent(const RefPtr<NG::UINode> & node)133 bool IsIsolatedComponent(const RefPtr<NG::UINode>& node)
134 {
135     return node && (node->GetTag() == V2::ISOLATED_COMPONENT_ETS_TAG);
136 }
137 
IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode> & node)138 bool IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode>& node)
139 {
140     CHECK_NULL_RETURN(node, true);
141     if (node->GetTag() == V2::ISOLATED_COMPONENT_ETS_TAG) {
142         return false;
143     }
144 #ifdef WINDOW_SCENE_SUPPORTED
145     auto pipeline = node->GetContextRefPtr();
146     CHECK_NULL_RETURN(pipeline, true);
147     auto manager = pipeline->GetUIExtensionManager();
148     CHECK_NULL_RETURN(manager, true);
149     return manager->IsShowPlaceholder(node->GetId());
150 #endif
151     return true;
152 }
153 
ConvertStrToEventType(const std::string & type)154 Accessibility::EventType ConvertStrToEventType(const std::string& type)
155 {
156     // static linear map must be sorted by key.
157     static const LinearMapNode<Accessibility::EventType> eventTypeMap[] = {
158         { ACCESSIBILITY_CLEAR_FOCUS_EVENT, Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT },
159         { ACCESSIBILITY_FOCUSED_EVENT, Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUSED_EVENT },
160         { DOM_CLICK, Accessibility::EventType::TYPE_VIEW_CLICKED_EVENT },
161         { DOM_FOCUS, Accessibility::EventType::TYPE_VIEW_FOCUSED_EVENT },
162         { DOM_LONG_PRESS, Accessibility::EventType::TYPE_VIEW_LONG_CLICKED_EVENT },
163         { MOUSE_HOVER_ENTER, Accessibility::EventType::TYPE_VIEW_HOVER_ENTER_EVENT },
164         { MOUSE_HOVER_EXIT, Accessibility::EventType::TYPE_VIEW_HOVER_EXIT_EVENT },
165         { PAGE_CHANGE_EVENT, Accessibility::EventType::TYPE_PAGE_STATE_UPDATE },
166         { SCROLL_END_EVENT, Accessibility::EventType::TYPE_VIEW_SCROLLED_EVENT },
167         { SCROLL_START_EVENT, Accessibility::EventType::TYPE_VIEW_SCROLLED_START },
168         { DOM_SELECTED, Accessibility::EventType::TYPE_VIEW_SELECTED_EVENT },
169         { TEXT_CHANGE_EVENT, Accessibility::EventType::TYPE_VIEW_TEXT_UPDATE_EVENT },
170         { DOM_TOUCH_END, Accessibility::EventType::TYPE_TOUCH_END },
171         { DOM_TOUCH_START, Accessibility::EventType::TYPE_TOUCH_BEGIN },
172     };
173     Accessibility::EventType eventType = Accessibility::EventType::TYPE_VIEW_INVALID;
174     int64_t idx = BinarySearchFindIndex(eventTypeMap, ArraySize(eventTypeMap), type.c_str());
175     if (idx >= 0) {
176         eventType = eventTypeMap[idx].value;
177     }
178     return eventType;
179 }
180 
ConvertAceEventType(AccessibilityEventType type)181 Accessibility::EventType ConvertAceEventType(AccessibilityEventType type)
182 {
183     static const LinearEnumMapNode<AccessibilityEventType, Accessibility::EventType> eventTypeMap[] = {
184         { AccessibilityEventType::CLICK, Accessibility::EventType::TYPE_VIEW_CLICKED_EVENT },
185         { AccessibilityEventType::LONG_PRESS, Accessibility::EventType::TYPE_VIEW_LONG_CLICKED_EVENT },
186         { AccessibilityEventType::SELECTED, Accessibility::EventType::TYPE_VIEW_SELECTED_EVENT },
187         { AccessibilityEventType::FOCUS, Accessibility::EventType::TYPE_VIEW_FOCUSED_EVENT },
188         { AccessibilityEventType::TEXT_CHANGE, Accessibility::EventType::TYPE_VIEW_TEXT_UPDATE_EVENT },
189         { AccessibilityEventType::HOVER_ENTER_EVENT, Accessibility::EventType::TYPE_VIEW_HOVER_ENTER_EVENT },
190         { AccessibilityEventType::PAGE_CHANGE, Accessibility::EventType::TYPE_PAGE_STATE_UPDATE },
191         { AccessibilityEventType::HOVER_EXIT_EVENT, Accessibility::EventType::TYPE_VIEW_HOVER_EXIT_EVENT },
192         { AccessibilityEventType::CHANGE, Accessibility::EventType::TYPE_PAGE_CONTENT_UPDATE },
193         { AccessibilityEventType::COMPONENT_CHANGE, Accessibility::EventType::TYPE_VIEW_TEXT_UPDATE_EVENT },
194         { AccessibilityEventType::SCROLL_END, Accessibility::EventType::TYPE_VIEW_SCROLLED_EVENT },
195         { AccessibilityEventType::TEXT_SELECTION_UPDATE,
196             Accessibility::EventType::TYPE_VIEW_TEXT_SELECTION_UPDATE_EVENT },
197         { AccessibilityEventType::ACCESSIBILITY_FOCUSED,
198             Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUSED_EVENT },
199         { AccessibilityEventType::ACCESSIBILITY_FOCUS_CLEARED,
200             Accessibility::EventType::TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT },
201         { AccessibilityEventType::TEXT_MOVE_UNIT, Accessibility::EventType::TYPE_VIEW_TEXT_MOVE_UNIT_EVENT },
202         { AccessibilityEventType::REQUEST_FOCUS, Accessibility::EventType::TYPE_VIEW_REQUEST_FOCUS_FOR_ACCESSIBILITY },
203         { AccessibilityEventType::SCROLL_START, Accessibility::EventType::TYPE_VIEW_SCROLLED_START },
204         { AccessibilityEventType::PAGE_CLOSE, Accessibility::EventType::TYPE_PAGE_CLOSE },
205         { AccessibilityEventType::ANNOUNCE_FOR_ACCESSIBILITY,
206             Accessibility::EventType::TYPE_VIEW_ANNOUNCE_FOR_ACCESSIBILITY },
207         { AccessibilityEventType::PAGE_OPEN, Accessibility::EventType::TYPE_PAGE_OPEN },
208         { AccessibilityEventType::ELEMENT_INFO_CHANGE, Accessibility::EventType::TYPE_ELEMENT_INFO_CHANGE },
209     };
210     Accessibility::EventType eventType = Accessibility::EventType::TYPE_VIEW_INVALID;
211     int64_t idx = BinarySearchFindIndex(eventTypeMap, ArraySize(eventTypeMap), type);
212     if (idx >= 0) {
213         eventType = eventTypeMap[idx].value;
214     }
215     return eventType;
216 }
217 
ConvertAceAction(AceAction aceAction)218 ActionType ConvertAceAction(AceAction aceAction)
219 {
220     static const ActionTable actionTable[] = {
221         { AceAction::ACTION_CLICK, ActionType::ACCESSIBILITY_ACTION_CLICK },
222         { AceAction::ACTION_LONG_CLICK, ActionType::ACCESSIBILITY_ACTION_LONG_CLICK },
223         { AceAction::ACTION_SCROLL_FORWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD },
224         { AceAction::ACTION_SCROLL_BACKWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD },
225         { AceAction::ACTION_FOCUS, ActionType::ACCESSIBILITY_ACTION_FOCUS },
226         { AceAction::ACTION_CLEAR_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS },
227         { AceAction::ACTION_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS },
228         { AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS },
229         { AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT },
230         { AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT },
231         { AceAction::ACTION_SET_TEXT, ActionType::ACCESSIBILITY_ACTION_SET_TEXT },
232         { AceAction::ACTION_COPY, ActionType::ACCESSIBILITY_ACTION_COPY },
233         { AceAction::ACTION_PASTE, ActionType::ACCESSIBILITY_ACTION_PASTE },
234         { AceAction::ACTION_CUT, ActionType::ACCESSIBILITY_ACTION_CUT },
235         { AceAction::ACTION_SELECT, ActionType::ACCESSIBILITY_ACTION_SELECT },
236         { AceAction::ACTION_CLEAR_SELECTION, ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION },
237         { AceAction::ACTION_SET_SELECTION, ActionType::ACCESSIBILITY_ACTION_SET_SELECTION },
238         { AceAction::ACTION_SET_CURSOR_POSITION, ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION },
239         { AceAction::ACTION_EXEC_SUB_COMPONENT, ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK },
240     };
241     for (const auto& item : actionTable) {
242         if (aceAction == item.aceAction) {
243             return item.action;
244         }
245     }
246     return ActionType::ACCESSIBILITY_ACTION_INVALID;
247 }
248 
ConvertAccessibilityValue(const AccessibilityValue & value)249 inline RangeInfo ConvertAccessibilityValue(const AccessibilityValue& value)
250 {
251     return RangeInfo(value.min, value.max, value.current);
252 }
253 
ConvertToCardAccessibilityId(int64_t nodeId,int64_t cardId,int64_t rootNodeId)254 int64_t ConvertToCardAccessibilityId(int64_t nodeId, int64_t cardId, int64_t rootNodeId)
255 {
256     // result is integer total ten digits, top five for agp virtualViewId, end five for ace nodeId,
257     // for example agp virtualViewId is 32, ace nodeId is 1000001, convert to result is 00032 10001.
258     int64_t result = 0;
259     if (nodeId == rootNodeId + ROOT_STACK_BASE) {
260         // for example agp virtualViewId is 32 root node is 2100000, convert to result is 00032 21000.
261         result = cardId * CARD_BASE + (static_cast<int64_t>(nodeId / CARD_BASE)) * CARD_ROOT_NODE_ID_RATION +
262                  nodeId % CARD_BASE;
263     } else {
264         result = cardId * CARD_BASE + (static_cast<int64_t>(nodeId / DOM_ROOT_NODE_ID_BASE)) * CARD_NODE_ID_RATION +
265                  nodeId % DOM_ROOT_NODE_ID_BASE;
266     }
267     return result;
268 }
269 
UpdateAccessibilityNodeInfo(const RefPtr<AccessibilityNode> & node,AccessibilityElementInfo & nodeInfo,const RefPtr<JsAccessibilityManager> & manager,int windowId)270 void UpdateAccessibilityNodeInfo(const RefPtr<AccessibilityNode>& node, AccessibilityElementInfo& nodeInfo,
271     const RefPtr<JsAccessibilityManager>& manager, int windowId)
272 {
273     int leftTopX = static_cast<int>(node->GetLeft()) + manager->GetWindowLeft(node->GetWindowId());
274     int leftTopY = static_cast<int>(node->GetTop()) + manager->GetWindowTop(node->GetWindowId());
275     int rightBottomX = leftTopX + static_cast<int>(node->GetWidth());
276     int rightBottomY = leftTopY + static_cast<int>(node->GetHeight());
277     if (manager->isOhosHostCard()) {
278         int64_t id = ConvertToCardAccessibilityId(node->GetNodeId(), manager->GetCardId(), manager->GetRootNodeId());
279         nodeInfo.SetAccessibilityId(id);
280         if (node->GetParentId() == -1) {
281             nodeInfo.SetParent(-1);
282         } else {
283             nodeInfo.SetParent(
284                 ConvertToCardAccessibilityId(node->GetParentId(), manager->GetCardId(), manager->GetRootNodeId()));
285         }
286         leftTopX = static_cast<int>(node->GetLeft() + manager->GetCardOffset().GetX());
287         leftTopY = static_cast<int>(node->GetTop() + manager->GetCardOffset().GetY());
288         rightBottomX = leftTopX + static_cast<int>(node->GetWidth());
289         rightBottomY = leftTopY + static_cast<int>(node->GetHeight());
290         Accessibility::Rect bounds(leftTopX, leftTopY, rightBottomX, rightBottomY);
291         nodeInfo.SetRectInScreen(bounds);
292     } else {
293         if (node->GetTag() == SIDEBARCONTAINER_TAG) {
294             Rect sideBarRect = node->GetRect();
295             for (const auto& childNode : node->GetChildList()) {
296                 sideBarRect = sideBarRect.CombineRect(childNode->GetRect());
297             }
298             leftTopX = static_cast<int>(sideBarRect.Left()) + manager->GetWindowLeft(node->GetWindowId());
299             leftTopY = static_cast<int>(sideBarRect.Top()) + manager->GetWindowTop(node->GetWindowId());
300             rightBottomX = static_cast<int>(sideBarRect.Right()) + manager->GetWindowLeft(node->GetWindowId());
301             rightBottomY = static_cast<int>(sideBarRect.Bottom()) + manager->GetWindowTop(node->GetWindowId());
302         }
303         Accessibility::Rect bounds(leftTopX, leftTopY, rightBottomX, rightBottomY);
304         nodeInfo.SetRectInScreen(bounds);
305         nodeInfo.SetComponentId(static_cast<int64_t>(node->GetNodeId()));
306         nodeInfo.SetParent(static_cast<int64_t>(node->GetParentId()));
307     }
308 
309     if (node->GetParentId() == -1) {
310         const auto& children = node->GetChildList();
311         if (!children.empty()) {
312             auto lastChildNode = manager->GetAccessibilityNodeById(children.back()->GetNodeId());
313             if (lastChildNode) {
314                 rightBottomX = leftTopX + static_cast<int>(lastChildNode->GetWidth());
315                 rightBottomY = leftTopY + static_cast<int>(lastChildNode->GetHeight());
316                 Accessibility::Rect bounds(leftTopX, leftTopY, rightBottomX, rightBottomY);
317                 nodeInfo.SetRectInScreen(bounds);
318             }
319         }
320         nodeInfo.SetParent(INVALID_PARENT_ID);
321     }
322     if (node->GetNodeId() == 0) {
323         nodeInfo.SetParent(INVALID_PARENT_ID);
324     }
325     nodeInfo.SetPagePath(manager->GetPagePath());
326     nodeInfo.SetWindowId(windowId);
327     nodeInfo.SetChecked(node->GetCheckedState());
328     nodeInfo.SetEnabled(node->GetEnabledState());
329     nodeInfo.SetFocused(node->GetFocusedState());
330     nodeInfo.SetSelected(node->GetSelectedState());
331     nodeInfo.SetCheckable(node->GetCheckableState());
332     nodeInfo.SetClickable(node->GetClickableState());
333     nodeInfo.SetFocusable(node->GetFocusableState());
334     nodeInfo.SetScrollable(node->GetScrollableState());
335     nodeInfo.SetLongClickable(node->GetLongClickableState());
336     nodeInfo.SetEditable(node->GetEditable());
337     nodeInfo.SetPluraLineSupported(node->GetIsMultiLine());
338     nodeInfo.SetPassword(node->GetIsPassword());
339     nodeInfo.SetTextLengthLimit(node->GetMaxTextLength());
340     nodeInfo.SetSelectedBegin(node->GetTextSelectionStart());
341     nodeInfo.SetSelectedEnd(node->GetTextSelectionEnd());
342     nodeInfo.SetVisible(node->GetShown() && node->GetVisible());
343     nodeInfo.SetHint(node->GetHintText());
344     std::string accessibilityLabel = node->GetAccessibilityLabel();
345     nodeInfo.SetLabeled(atol(accessibilityLabel.c_str()));
346     nodeInfo.SetError(node->GetErrorText());
347     nodeInfo.SetComponentResourceId(node->GetJsComponentId());
348     nodeInfo.SetInspectorKey(node->GetJsComponentId());
349     RangeInfo rangeInfo = ConvertAccessibilityValue(node->GetAccessibilityValue());
350     nodeInfo.SetRange(rangeInfo);
351     nodeInfo.SetInputType(static_cast<int>(node->GetTextInputType()));
352     nodeInfo.SetComponentType(node->GetTag());
353     GridInfo gridInfo(
354         node->GetCollectionInfo().rows, node->GetCollectionInfo().columns, (nodeInfo.IsPluraLineSupported() ? 0 : 1));
355     nodeInfo.SetGrid(gridInfo);
356     nodeInfo.SetAccessibilityFocus(node->GetAccessibilityFocusedState());
357     nodeInfo.SetPageId(node->GetPageId());
358 
359     int32_t row = node->GetCollectionItemInfo().row;
360     int32_t column = node->GetCollectionItemInfo().column;
361     GridItemInfo gridItemInfo(row, row, column, column, false, nodeInfo.IsSelected());
362     nodeInfo.SetGridItem(gridItemInfo);
363     nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
364 
365     if (node->GetTag() == LIST_TAG) {
366         nodeInfo.SetItemCounts(node->GetListItemCounts());
367         nodeInfo.SetBeginIndex(node->GetListBeginIndex());
368         nodeInfo.SetEndIndex(node->GetListEndIndex());
369     }
370     if (node->GetIsPassword()) {
371         std::string strStar(node->GetText().size(), '*');
372         nodeInfo.SetContent(strStar);
373     } else {
374         nodeInfo.SetContent(node->GetText());
375     }
376 
377     auto supportAceActions = node->GetSupportAction();
378     std::vector<ActionType> actions(supportAceActions.size());
379 
380     for (auto it = supportAceActions.begin(); it != supportAceActions.end(); ++it) {
381         AccessibleAction action(ConvertAceAction(*it), "ace");
382         nodeInfo.AddAction(action);
383     }
384 
385     if (node->GetImportantForAccessibility() == NG::AccessibilityProperty::Level::YES_STR) {
386         actions.emplace_back(ActionType::ACCESSIBILITY_ACTION_FOCUS);
387         nodeInfo.SetCheckable(true);
388     } else if (node->GetImportantForAccessibility() == NG::AccessibilityProperty::Level::NO_STR ||
389                node->GetImportantForAccessibility() == NG::AccessibilityProperty::Level::NO_HIDE_DESCENDANTS) {
390         nodeInfo.SetVisible(false);
391     }
392 
393     manager->UpdateNodeChildIds(node);
394     for (const auto& child : node->GetChildIds()) {
395         nodeInfo.AddChild(child);
396     }
397 
398 #ifdef ACE_DEBUG
399     std::string actionForLog;
400     for (const auto& action : supportAceActions) {
401         if (!actionForLog.empty()) {
402             actionForLog.append(",");
403         }
404         actionForLog.append(std::to_string(static_cast<int32_t>(action)));
405     }
406 #endif
407 }
408 
UpdateCacheInfo(std::list<AccessibilityElementInfo> & infos,uint32_t mode,const RefPtr<AccessibilityNode> & node,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,int windowId)409 void UpdateCacheInfo(std::list<AccessibilityElementInfo>& infos, uint32_t mode, const RefPtr<AccessibilityNode>& node,
410     const RefPtr<JsAccessibilityManager>& jsAccessibilityManager, int windowId)
411 {
412     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}d, mode: %{public}d", node->GetNodeId(), mode);
413     // parent
414     uint32_t umode = mode;
415     if (umode & static_cast<uint32_t>(PREFETCH_PREDECESSORS)) {
416         if (node->GetParentId() != -1 && node->GetParentId() != DEFAULT_PARENT_ID) {
417             AccessibilityElementInfo parentNodeInfo;
418             UpdateAccessibilityNodeInfo(node->GetParentNode(), parentNodeInfo, jsAccessibilityManager, windowId);
419             infos.emplace_back(parentNodeInfo);
420         }
421     }
422     // sister/brothers
423     if (umode & static_cast<uint32_t>(PREFETCH_SIBLINGS)) {
424         if (node->GetParentId() != -1 && node->GetParentId() != DEFAULT_PARENT_ID) {
425             for (const auto& item : node->GetParentNode()->GetChildList()) {
426                 if (node->GetNodeId() != item->GetNodeId()) {
427                     AccessibilityElementInfo siblingNodeInfo;
428                     UpdateAccessibilityNodeInfo(item, siblingNodeInfo, jsAccessibilityManager, windowId);
429                     infos.emplace_back(siblingNodeInfo);
430                 }
431             }
432         }
433     }
434     // children
435     if (umode & static_cast<uint32_t>(PREFETCH_CHILDREN)) {
436         for (const auto& item : node->GetChildList()) {
437             AccessibilityElementInfo childNodeInfo;
438             UpdateAccessibilityNodeInfo(item, childNodeInfo, jsAccessibilityManager, windowId);
439             infos.emplace_back(childNodeInfo);
440         }
441     }
442 
443     // get all children
444     if (umode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN)) {
445         std::list<RefPtr<AccessibilityNode>> children;
446         for (const auto& item : node->GetChildList()) {
447             children.emplace_back(item);
448         }
449 
450         while (!children.empty()) {
451             auto parent = children.front();
452             children.pop_front();
453             AccessibilityElementInfo childNodeInfo;
454             UpdateAccessibilityNodeInfo(parent, childNodeInfo, jsAccessibilityManager, windowId);
455             infos.push_back(childNodeInfo);
456             for (const auto& item : parent->GetChildList()) {
457                 children.emplace_back(item);
458             }
459         }
460     }
461 }
462 
SortAccessibilityInfosByBreadth(std::list<AccessibilityElementInfo> & infos,std::list<int64_t> & accessibilityIdQueue,std::list<AccessibilityElementInfo> & output)463 void SortAccessibilityInfosByBreadth(std::list<AccessibilityElementInfo>& infos,
464     std::list<int64_t>& accessibilityIdQueue, std::list<AccessibilityElementInfo>& output)
465 {
466     while (!accessibilityIdQueue.empty()) {
467         auto accessibilityId = accessibilityIdQueue.front();
468         accessibilityIdQueue.pop_front();
469         for (std::list<AccessibilityElementInfo>::iterator info = infos.begin(); info != infos.end(); ++info) {
470             if (accessibilityId != info->GetAccessibilityId()) {
471                 continue;
472             }
473             for (auto& child : info->GetChildIds()) {
474                 accessibilityIdQueue.emplace_back(child);
475             }
476             output.emplace_back(*info);
477             infos.erase(info);
478             break;
479         }
480         SortAccessibilityInfosByBreadth(infos, accessibilityIdQueue, output);
481     }
482 }
483 
SortExtensionAccessibilityInfo(std::list<AccessibilityElementInfo> & infos,int64_t rootAccessibilityId)484 void SortExtensionAccessibilityInfo(std::list<AccessibilityElementInfo>& infos, int64_t rootAccessibilityId)
485 {
486     auto input = infos;
487     infos.clear();
488     std::list<int64_t> accessibilityIdQueue;
489     accessibilityIdQueue.emplace_back(rootAccessibilityId);
490     SortAccessibilityInfosByBreadth(input, accessibilityIdQueue, infos);
491 }
492 
ConvertExtensionAccessibilityId(AccessibilityElementInfo & info,const RefPtr<NG::FrameNode> & extensionNode,int64_t uiExtensionOffset,AccessibilityElementInfo & parentInfo)493 void ConvertExtensionAccessibilityId(AccessibilityElementInfo& info, const RefPtr<NG::FrameNode>& extensionNode,
494     int64_t uiExtensionOffset, AccessibilityElementInfo& parentInfo)
495 {
496     auto extensionAbilityId =
497             extensionNode->WrapExtensionAbilityId(uiExtensionOffset, info.GetAccessibilityId());
498     info.SetAccessibilityId(extensionAbilityId);
499     auto parentNodeId =
500         extensionNode->WrapExtensionAbilityId(uiExtensionOffset, info.GetParentNodeId());
501     info.SetParent(parentNodeId);
502     auto childIds = info.GetChildIds();
503     for (auto& child : childIds) {
504         info.RemoveChild(child);
505         info.AddChild(extensionNode->WrapExtensionAbilityId(uiExtensionOffset, child));
506     }
507     if (V2::ROOT_ETS_TAG == info.GetComponentType()) {
508         for (auto& child : info.GetChildIds()) {
509             parentInfo.AddChild(child);
510         }
511     }
512 }
513 
ConvertExtensionAccessibilityNodeId(std::list<AccessibilityElementInfo> & infos,const RefPtr<NG::FrameNode> & extensionNode,int64_t uiExtensionOffset,AccessibilityElementInfo & parentInfo)514 void ConvertExtensionAccessibilityNodeId(std::list<AccessibilityElementInfo>& infos,
515     const RefPtr<NG::FrameNode>& extensionNode, int64_t uiExtensionOffset,
516     AccessibilityElementInfo& parentInfo)
517 {
518     CHECK_NULL_VOID(extensionNode);
519     for (auto& accessibilityElementInfo : infos) {
520         ConvertExtensionAccessibilityId(accessibilityElementInfo, extensionNode, uiExtensionOffset, parentInfo);
521     }
522     for (auto& accessibilityElementInfo : infos) {
523         if (std::find(parentInfo.GetChildIds().begin(), parentInfo.GetChildIds().end(),
524             accessibilityElementInfo.GetAccessibilityId()) != parentInfo.GetChildIds().end()) {
525             accessibilityElementInfo.SetParent(extensionNode->GetAccessibilityId());
526         }
527     }
528 }
529 
BoolToString(bool tag)530 inline std::string BoolToString(bool tag)
531 {
532     return tag ? "true" : "false";
533 }
534 
ConvertInputTypeToString(AceTextCategory type)535 std::string ConvertInputTypeToString(AceTextCategory type)
536 {
537     switch (type) {
538         case AceTextCategory::INPUT_TYPE_DEFAULT:
539             return "INPUT_TYPE_DEFAULT";
540         case AceTextCategory::INPUT_TYPE_TEXT:
541             return "INPUT_TYPE_TEXT";
542         case AceTextCategory::INPUT_TYPE_EMAIL:
543             return "INPUT_TYPE_EMAIL";
544         case AceTextCategory::INPUT_TYPE_DATE:
545             return "INPUT_TYPE_DATE";
546         case AceTextCategory::INPUT_TYPE_TIME:
547             return "INPUT_TYPE_TIME";
548         case AceTextCategory::INPUT_TYPE_NUMBER:
549             return "INPUT_TYPE_NUMBER";
550         case AceTextCategory::INPUT_TYPE_PASSWORD:
551             return "INPUT_TYPE_PASSWORD";
552         case AceTextCategory::INPUT_TYPE_PHONENUMBER:
553             return "INPUT_TYPE_PHONENUMBER";
554         case AceTextCategory::INPUT_TYPE_USER_NAME:
555             return "INPUT_TYPE_USER_NAME";
556         case AceTextCategory::INPUT_TYPE_NEW_PASSWORD:
557             return "INPUT_TYPE_NEW_PASSWORD";
558         default:
559             return "illegal input type";
560     }
561 }
562 
FindAccessibilityFocus(const RefPtr<AccessibilityNode> & node,RefPtr<AccessibilityNode> & resultNode)563 bool FindAccessibilityFocus(const RefPtr<AccessibilityNode>& node, RefPtr<AccessibilityNode>& resultNode)
564 {
565     CHECK_NULL_RETURN(node, false);
566     if (node->GetAccessibilityFocusedState()) {
567         resultNode = node;
568         return true;
569     }
570     if (!node->GetChildList().empty()) {
571         for (const auto& item : node->GetChildList()) {
572             if (resultNode != nullptr) {
573                 return true;
574             }
575             if (FindAccessibilityFocus(item, resultNode)) {
576                 return true;
577             }
578         }
579     }
580 
581     return false;
582 }
583 
FindFocusedExtensionElementInfoNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,Accessibility::AccessibilityElementInfo & info)584 void FindFocusedExtensionElementInfoNG(const SearchParameter& searchParam,
585     const RefPtr<NG::FrameNode>& node, Accessibility::AccessibilityElementInfo& info)
586 {
587     if (NG::UI_EXTENSION_OFFSET_MIN < (searchParam.uiExtensionOffset + 1)) {
588         node->FindFocusedExtensionElementInfoNG(searchParam.nodeId, searchParam.mode,
589             searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR, info);
590     } else {
591         info.SetValidElement(false);
592     }
593 }
594 
SetUiExtensionAbilityParentIdForFocus(const RefPtr<NG::UINode> & uiExtensionNode,const int64_t uiExtensionOffset,Accessibility::AccessibilityElementInfo & info)595 void SetUiExtensionAbilityParentIdForFocus(const RefPtr<NG::UINode>& uiExtensionNode,
596     const int64_t uiExtensionOffset, Accessibility::AccessibilityElementInfo& info)
597 {
598     auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiExtensionNode);
599     if (frameNode) {
600         auto parentId = info.GetParentNodeId();
601         AccessibilityElementInfo parentInfo;
602         ConvertExtensionAccessibilityId(info, frameNode, uiExtensionOffset, parentInfo);
603         if (parentId == NG::UI_EXTENSION_ROOT_ID) {
604             info.SetParent(frameNode->GetAccessibilityId());
605         }
606     }
607 }
608 
609 RefPtr<NG::FrameNode> GetFramenodeByAccessibilityId(const RefPtr<NG::FrameNode>& root, int64_t id);
610 
FindAccessibilityFocus(const RefPtr<NG::UINode> & node,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const int64_t uiExtensionOffset,const RefPtr<PipelineBase> & context,int64_t currentFocusNodeId)611 RefPtr<NG::FrameNode> FindAccessibilityFocus(const RefPtr<NG::UINode>& node,
612     int32_t focusType, Accessibility::AccessibilityElementInfo& info,
613     const int64_t uiExtensionOffset, const RefPtr<PipelineBase>& context, int64_t currentFocusNodeId)
614 {
615     CHECK_NULL_RETURN(node, nullptr);
616     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
617     if (frameNode) {
618         if (frameNode->GetRenderContext()->GetAccessibilityFocus().value_or(false)) {
619             auto node = GetFramenodeByAccessibilityId(frameNode, currentFocusNodeId);
620             return node;
621         }
622     }
623     if (node->GetChildren(true).empty()) {
624         return nullptr;
625     }
626     for (const auto& child : node->GetChildren(true)) {
627         auto extensionNode = AceType::DynamicCast<NG::FrameNode>(child);
628         if (IsIsolatedComponent(child) && extensionNode &&
629             !IsUIExtensionShowPlaceholder(extensionNode) &&
630             (extensionNode->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
631             (((extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX) &&
632             (NG::UI_EXTENSION_OFFSET_MAX == uiExtensionOffset)) ||
633             (extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_OTHER_MAX))) {
634             SearchParameter transferSearchParam {NG::UI_EXTENSION_ROOT_ID, "", focusType, uiExtensionOffset};
635             OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(
636                 transferSearchParam, extensionNode, info);
637             if (info.GetAccessibilityId() < 0) {
638                 continue;
639             }
640             SetUiExtensionAbilityParentIdForFocus(extensionNode, uiExtensionOffset, info);
641             return extensionNode;
642         }
643         auto result = FindAccessibilityFocus(child, focusType, info, uiExtensionOffset, context, currentFocusNodeId);
644         if (result) {
645             return result;
646         }
647     }
648     return nullptr;
649 }
650 
FindInputFocus(const RefPtr<AccessibilityNode> & node,RefPtr<AccessibilityNode> & resultNode)651 bool FindInputFocus(const RefPtr<AccessibilityNode>& node, RefPtr<AccessibilityNode>& resultNode)
652 {
653     CHECK_NULL_RETURN(node, false);
654     if (!node->GetFocusedState() && (node->GetParentId() != -1)) {
655         return false;
656     }
657     if (node->GetFocusedState()) {
658         resultNode = node;
659     }
660     if (!node->GetChildList().empty()) {
661         for (const auto& item : node->GetChildList()) {
662             if (FindInputFocus(item, resultNode)) {
663                 return true;
664             }
665         }
666     }
667     return node->GetFocusedState();
668 }
669 
FindInputFocus(const RefPtr<NG::UINode> & node,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const int64_t uiExtensionOffset,const RefPtr<PipelineBase> & context)670 RefPtr<NG::FrameNode> FindInputFocus(const RefPtr<NG::UINode>& node, int32_t focusType,
671     Accessibility::AccessibilityElementInfo& info, const int64_t uiExtensionOffset,
672     const RefPtr<PipelineBase>& context)
673 {
674     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
675     CHECK_NULL_RETURN(frameNode, nullptr);
676     if (!(frameNode->GetFocusHub() ? frameNode->GetFocusHub()->IsCurrentFocus() : false)) {
677         return nullptr;
678     }
679     if (frameNode->GetFocusHub()->IsChild()) {
680         if (frameNode->IsInternal()) {
681             return frameNode->GetFocusParent();
682         }
683         return frameNode;
684     }
685     auto focusHub = frameNode->GetFocusHub();
686     auto focusChildren = focusHub->GetChildren();
687     for (const auto& focusChild : focusChildren) {
688         auto extensionNode = focusChild->GetFrameNode();
689         if ((extensionNode && IsIsolatedComponent(extensionNode)) &&
690             !IsUIExtensionShowPlaceholder(extensionNode) &&
691             (extensionNode->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
692             (((extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX) &&
693             (NG::UI_EXTENSION_OFFSET_MAX == uiExtensionOffset)) ||
694             (extensionNode->GetUiExtensionId() <= NG::UI_EXTENSION_ID_OTHER_MAX))) {
695             SearchParameter transferSearchParam {NG::UI_EXTENSION_ROOT_ID, "", focusType, uiExtensionOffset};
696             OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(
697                 transferSearchParam, extensionNode, info);
698             if (info.GetAccessibilityId() < 0) {
699                 continue;
700             }
701             SetUiExtensionAbilityParentIdForFocus(extensionNode, uiExtensionOffset, info);
702             return extensionNode;
703         }
704         auto childNode = FindInputFocus(focusChild->GetFrameNode(), focusType, info, uiExtensionOffset, context);
705         if (childNode) {
706             return childNode;
707         }
708     }
709     return nullptr;
710 }
711 
FindText(const RefPtr<AccessibilityNode> & node,const std::string & text,std::list<RefPtr<AccessibilityNode>> & nodeList)712 void FindText(
713     const RefPtr<AccessibilityNode>& node, const std::string& text, std::list<RefPtr<AccessibilityNode>>& nodeList)
714 {
715     CHECK_NULL_VOID(node);
716     if (node->GetText().find(text) != std::string::npos) {
717         nodeList.push_back(node);
718     }
719     if (!node->GetChildList().empty()) {
720         for (const auto& child : node->GetChildList()) {
721             FindText(child, text, nodeList);
722         }
723     }
724 }
725 
FindText(const RefPtr<NG::UINode> & node,const std::string & text,std::list<RefPtr<NG::FrameNode>> & nodeList)726 void FindText(const RefPtr<NG::UINode>& node, const std::string& text, std::list<RefPtr<NG::FrameNode>>& nodeList)
727 {
728     CHECK_NULL_VOID(node);
729 
730     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
731     if (frameNode && !frameNode->IsInternal()) {
732         if (frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetGroupText().find(text) !=
733             std::string::npos) {
734             nodeList.push_back(frameNode);
735         }
736     }
737 
738     if (!node->GetChildren(true).empty()) {
739         for (const auto& child : node->GetChildren(true)) {
740             FindText(child, text, nodeList);
741         }
742     }
743 }
744 
FindFrameNodeByAccessibilityId(int64_t id,const std::list<RefPtr<NG::UINode>> & children,std::queue<NG::UINode * > & nodes,RefPtr<NG::FrameNode> & result)745 bool FindFrameNodeByAccessibilityId(int64_t id, const std::list<RefPtr<NG::UINode>>& children,
746     std::queue<NG::UINode*>& nodes, RefPtr<NG::FrameNode>& result)
747 {
748     NG::FrameNode* frameNode = nullptr;
749     for (const auto& child : children) {
750         frameNode = AceType::DynamicCast<NG::FrameNode>(Referenced::RawPtr(child));
751         if (frameNode != nullptr && !frameNode->CheckAccessibilityLevelNo()) {
752             if (frameNode->GetAccessibilityId() == id) {
753                 result = AceType::DynamicCast<NG::FrameNode>(child);
754                 return true;
755             }
756         }
757         nodes.push(Referenced::RawPtr(child));
758     }
759     return false;
760 }
761 
GetFramenodeByAccessibilityId(const RefPtr<NG::FrameNode> & root,int64_t id)762 RefPtr<NG::FrameNode> GetFramenodeByAccessibilityId(const RefPtr<NG::FrameNode>& root, int64_t id)
763 {
764     CHECK_NULL_RETURN(root, nullptr);
765     if (root->GetAccessibilityId() == id) {
766         return root;
767     }
768     std::queue<NG::UINode*> nodes;
769     nodes.push(Referenced::RawPtr(root));
770     RefPtr<NG::FrameNode> frameNodeResult = nullptr;
771 
772     while (!nodes.empty()) {
773         auto current = nodes.front();
774         nodes.pop();
775         if (current->HasVirtualNodeAccessibilityProperty()) {
776             auto fnode = AceType::DynamicCast<NG::FrameNode>(current);
777             auto property = fnode->GetAccessibilityProperty<NG::AccessibilityProperty>();
778             const auto& children = std::list<RefPtr<NG::UINode>> { property->GetAccessibilityVirtualNode() };
779             if (FindFrameNodeByAccessibilityId(id, children, nodes, frameNodeResult)) {
780                 return frameNodeResult;
781             }
782         } else {
783             const auto& children = current->GetChildren(true);
784             if (FindFrameNodeByAccessibilityId(id, children, nodes, frameNodeResult)) {
785                 return frameNodeResult;
786             }
787         }
788         auto frameNode = AceType::DynamicCast<NG::FrameNode>(current);
789         if (!frameNode) {
790             continue;
791         }
792         auto overlayNode = frameNode->GetOverlayNode();
793         if (overlayNode) {
794             const auto& children = std::list<RefPtr<NG::UINode>> { overlayNode };
795             if (FindFrameNodeByAccessibilityId(id, children, nodes, frameNodeResult)) {
796                 return frameNodeResult;
797             }
798         }
799     }
800     return nullptr;
801 }
802 
GetFrameNodeParent(const RefPtr<NG::UINode> & uiNode,RefPtr<NG::FrameNode> & parent)803 void GetFrameNodeParent(const RefPtr<NG::UINode>& uiNode, RefPtr<NG::FrameNode>& parent)
804 {
805     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
806         auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
807         if (!frameNode->IsInternal()) {
808             parent = frameNode;
809             return;
810         }
811     }
812     CHECK_NULL_VOID(uiNode);
813     auto parentNode = uiNode->GetParent();
814     GetFrameNodeParent(parentNode, parent);
815 }
816 
CheckFrameNodeByAccessibilityLevel(const RefPtr<NG::FrameNode> & frameNode,bool isParent)817 bool CheckFrameNodeByAccessibilityLevel(const RefPtr<NG::FrameNode>& frameNode, bool isParent)
818 {
819     return true;
820 }
821 
GetFrameNodeChildren(const RefPtr<NG::UINode> & uiNode,std::vector<int64_t> & children,int32_t pageId)822 void GetFrameNodeChildren(const RefPtr<NG::UINode>& uiNode, std::vector<int64_t>& children, int32_t pageId)
823 {
824     auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
825     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
826         if (!frameNode->IsFirstVirtualNode()) {
827             CHECK_NULL_VOID(frameNode->IsActive());
828         }
829         if (uiNode->GetTag() == "stage") {
830         } else if (uiNode->GetTag() == "page") {
831             if (uiNode->GetPageId() != pageId) {
832                 return;
833             }
834         } else if (!frameNode->IsInternal() || frameNode->IsFirstVirtualNode()) {
835             if (CheckFrameNodeByAccessibilityLevel(frameNode, false)) {
836                 children.emplace_back(uiNode->GetAccessibilityId());
837                 return;
838             }
839         }
840     }
841 
842     if (frameNode) {
843         auto overlayNode = frameNode->GetOverlayNode();
844         if (overlayNode) {
845             GetFrameNodeChildren(overlayNode, children, pageId);
846         }
847     }
848 
849     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
850         auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
851         auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
852         auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
853         if (uiVirtualNode != nullptr) {
854             auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
855             if (virtualNode != nullptr) {
856                 GetFrameNodeChildren(virtualNode, children, pageId);
857                 return;
858             }
859         }
860     }
861 
862     for (const auto& frameChild : uiNode->GetChildren(true)) {
863         GetFrameNodeChildren(frameChild, children, pageId);
864     }
865 }
866 
GetFrameNodeChildren(const RefPtr<NG::UINode> & uiNode,std::list<RefPtr<NG::FrameNode>> & children,int32_t pageId=-1)867 void GetFrameNodeChildren(
868     const RefPtr<NG::UINode>& uiNode, std::list<RefPtr<NG::FrameNode>>& children, int32_t pageId = -1)
869 {
870     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
871         auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
872         CHECK_NULL_VOID(frameNode->IsActive());
873         if (uiNode->GetTag() == "page") {
874             if (pageId != -1 && uiNode->GetPageId() != pageId) {
875                 return;
876             }
877         } else if (!frameNode->IsInternal() && uiNode->GetTag() != "stage") {
878             if (CheckFrameNodeByAccessibilityLevel(frameNode, false)) {
879                 children.emplace_back(frameNode);
880                 return;
881             }
882         }
883     }
884 
885     auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
886     if (frameNode) {
887         auto overlayNode = frameNode->GetOverlayNode();
888         if (overlayNode) {
889             GetFrameNodeChildren(overlayNode, children, pageId);
890         }
891     }
892 
893     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
894         auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
895         auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
896         auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
897         if (uiVirtualNode != nullptr) {
898             auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
899             if (virtualNode != nullptr) {
900                 GetFrameNodeChildren(virtualNode, children, pageId);
901                 return;
902             }
903         }
904     }
905 
906     for (const auto& frameChild : uiNode->GetChildren(true)) {
907         GetFrameNodeChildren(frameChild, children, pageId);
908     }
909 }
910 
GetNodeAccessibilityVisible(const RefPtr<NG::FrameNode> & frameNode,bool isAllAncestorAccessibilityVisible,bool clipVisible)911 bool GetNodeAccessibilityVisible(const RefPtr<NG::FrameNode>& frameNode, bool isAllAncestorAccessibilityVisible,
912                                  bool clipVisible)
913 {
914     if (frameNode->IsFirstVirtualNode()) {
915         return frameNode->IsVisible() && isAllAncestorAccessibilityVisible && clipVisible;
916     } else {
917         return frameNode->IsActive() && frameNode->IsVisible() && isAllAncestorAccessibilityVisible && clipVisible;
918     }
919 }
920 
ProcessParentFrameNode(const RefPtr<NG::UINode> & parent,std::string & parentPath,bool & isAllAncestorAccessibilityVisible)921 bool ProcessParentFrameNode(
922     const RefPtr<NG::UINode>& parent, std::string& parentPath, bool& isAllAncestorAccessibilityVisible)
923 {
924     auto parentFrameNode = AceType::DynamicCast<NG::FrameNode>(parent);
925     if (parentFrameNode->CheckAccessibilityLevelNo()) {
926         return false;
927     }
928 
929     parentPath += "Parent ID: " + std::to_string(parent->GetAccessibilityId()) +
930                   " IsActive: " + std::to_string(parentFrameNode->IsActive()) +
931                   " IsVisible: " + std::to_string(parentFrameNode->IsVisible()) +
932                   " AccessibilityVisible: " + std::to_string(parentFrameNode->GetAccessibilityVisible()) +
933                   " Parent Tag: " + parent->GetTag() + " | ";
934 
935     if (parent->GetTag() == V2::PAGE_ETS_TAG) {
936         isAllAncestorAccessibilityVisible = parentFrameNode->GetAccessibilityVisible();
937     } else if (parentFrameNode->IsFirstVirtualNode()) {
938         isAllAncestorAccessibilityVisible = parentFrameNode->IsVisible();
939     } else {
940         isAllAncestorAccessibilityVisible = parentFrameNode->IsActive() && parentFrameNode->IsVisible();
941     }
942 
943     return !isAllAncestorAccessibilityVisible;
944 }
945 
GetInitialParent(const RefPtr<NG::UINode> & uiNode)946 RefPtr<NG::UINode> GetInitialParent(const RefPtr<NG::UINode>& uiNode)
947 {
948     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
949         auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
950         if (frameNode->IsFirstVirtualNode()) {
951             auto weakNode = frameNode->GetVirtualNodeParent();
952             return weakNode.Upgrade();
953         } else {
954             return uiNode->GetParent();
955         }
956     }
957     return nullptr;
958 }
959 
SetRootAccessibilityVisible(const RefPtr<NG::UINode> & uiNode,AccessibilityElementInfo & nodeInfo)960 void SetRootAccessibilityVisible(const RefPtr<NG::UINode>& uiNode, AccessibilityElementInfo& nodeInfo)
961 {
962     RefPtr<NG::UINode> parent = GetInitialParent(uiNode);
963     bool isAllAncestorAccessibilityVisible = true;
964     bool clipVisible = true;
965     auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
966     CHECK_NULL_VOID(frameNode);
967     OHOS::Ace::NG::RectF frameRect;
968     OHOS::Ace::NG::RectF visibleInnerRect;
969     OHOS::Ace::NG::RectF visibleRect;
970     frameNode->GetVisibleRectWithClip(visibleRect, visibleInnerRect, frameRect);
971     bool isClipCheckSkip = NearEqual(visibleRect.Width(), 0.0) && NearEqual(visibleRect.Height(), 0.0) &&
972                            NearEqual(visibleInnerRect.Width(), 0.0) && NearEqual(visibleInnerRect.Height(), 0.0);
973     clipVisible = (GreatNotEqual(visibleInnerRect.Width(), 0.0) && GreatNotEqual(visibleInnerRect.Height(), 0.0)) ||
974                   isClipCheckSkip;
975     std::string parentPath;
976     while (parent) {
977         if (AceType::InstanceOf<NG::FrameNode>(parent)) {
978             if (ProcessParentFrameNode(parent, parentPath, isAllAncestorAccessibilityVisible)) {
979                 break;
980             }
981         }
982         parent = parent->GetParent();
983     }
984     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Complete parent path:current id %{public}" PRId64 " %{public}s",
985         nodeInfo.GetAccessibilityId(), parentPath.c_str());
986 
987     bool nodeAccessibilityVisible =
988         GetNodeAccessibilityVisible(frameNode, isAllAncestorAccessibilityVisible, clipVisible);
989     if (!nodeAccessibilityVisible) {
990         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
991             "Element %{public}" PRId64 " is invisible. isActive %{public}d, isVisible %{public}d"
992             " isAllAncestorAccessibilityVisible:%{public}d clipVisible:%{public}d",
993             nodeInfo.GetAccessibilityId(), frameNode->IsActive(), frameNode->IsVisible(),
994             isAllAncestorAccessibilityVisible, clipVisible);
995     }
996 
997     if (frameNode->GetTag() != V2::PAGE_ETS_TAG) {
998         frameNode->SetAccessibilityVisible(nodeAccessibilityVisible);
999     }
1000     nodeInfo.SetAccessibilityVisible(frameNode->GetAccessibilityVisible());
1001 }
1002 
GetParentId(const RefPtr<NG::UINode> & uiNode)1003 int64_t GetParentId(const RefPtr<NG::UINode>& uiNode)
1004 {
1005     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
1006         if (AceType::DynamicCast<NG::FrameNode>(uiNode)->IsFirstVirtualNode()) {
1007             auto weakNode = AceType::DynamicCast<NG::FrameNode>(uiNode)->GetVirtualNodeParent();
1008             auto refNode = weakNode.Upgrade();
1009             return refNode == nullptr ? INVALID_PARENT_ID : refNode->GetAccessibilityId();
1010         }
1011     }
1012     auto parent = uiNode->GetParent();
1013     while (parent) {
1014         if (AceType::InstanceOf<NG::FrameNode>(parent)) {
1015             if ((parent->GetTag() == V2::PAGE_ETS_TAG) || (parent->GetTag() == V2::STAGE_ETS_TAG) ||
1016                 AceType::DynamicCast<NG::FrameNode>(parent)->CheckAccessibilityLevelNo()) {
1017                 parent = parent->GetParent();
1018                 continue;
1019             }
1020             return parent->GetAccessibilityId();
1021         }
1022         parent = parent->GetParent();
1023     }
1024     return INVALID_PARENT_ID;
1025 }
1026 
FillElementInfo(int64_t elementId,AccessibilityElementInfo & elementInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param)1027 void FillElementInfo(int64_t elementId, AccessibilityElementInfo& elementInfo, const RefPtr<PipelineBase>& context,
1028     const RefPtr<JsAccessibilityManager>& jsAccessibilityManager, const FillEventInfoParam& param)
1029 {
1030     int64_t elementIdUnwrap = elementId;
1031     int64_t uiextensionId = 0;
1032     std::list<AccessibilityElementInfo> elementInfos;
1033     int32_t mode = 0;
1034     CHECK_NULL_VOID(jsAccessibilityManager);
1035 #ifdef WINDOW_SCENE_SUPPORTED
1036     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
1037     CHECK_NULL_VOID(ngPipeline);
1038     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
1039     CHECK_NULL_VOID(uiExtensionManager);
1040     if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
1041         auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(
1042             NG::UI_EXTENSION_OFFSET_MAX, elementIdUnwrap);
1043         elementIdUnwrap = unWrapIdPair.second;
1044         uiextensionId = unWrapIdPair.first;
1045     }
1046 #endif
1047     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
1048         "start to search elementId: %{public}" PRId64, elementIdUnwrap);
1049     jsAccessibilityManager->SearchElementInfoByAccessibilityIdNG(
1050         elementIdUnwrap, mode, elementInfos, context, NG::UI_EXTENSION_OFFSET_MAX);
1051     if (elementInfos.empty()) {
1052         LOGE("Element infos is empty. Find element infos failed.");
1053         return;
1054     }
1055     elementInfo = elementInfos.front();
1056     if (uiextensionId > 0) {
1057         elementIdUnwrap = (uiextensionId * NG::UI_EXTENSION_OFFSET_MAX) + elementInfo.GetAccessibilityId();
1058         TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "elementIdUnwrap: %{public}" PRId64, elementIdUnwrap);
1059     }
1060     elementInfo.SetAccessibilityId(elementIdUnwrap);
1061     elementInfo.SetWindowId(param.windowId);
1062 }
1063 
FillEventInfo(const RefPtr<NG::FrameNode> & node,AccessibilityEventInfo & eventInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param)1064 void FillEventInfo(const RefPtr<NG::FrameNode>& node,
1065                    AccessibilityEventInfo& eventInfo,
1066                    const RefPtr<PipelineBase>& context,
1067                    const RefPtr<JsAccessibilityManager>& jsAccessibilityManager,
1068                    const FillEventInfoParam& param)
1069 {
1070     CHECK_NULL_VOID(node);
1071     eventInfo.SetComponentType(node->GetTag());
1072     eventInfo.SetPageId(node->GetPageId());
1073     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1074     CHECK_NULL_VOID(accessibilityProperty);
1075     eventInfo.AddContent(accessibilityProperty->GetGroupText());
1076     eventInfo.SetItemCounts(accessibilityProperty->GetCollectionItemCounts());
1077     eventInfo.SetBeginIndex(accessibilityProperty->GetBeginIndex());
1078     eventInfo.SetEndIndex(accessibilityProperty->GetEndIndex());
1079     AccessibilityElementInfo elementInfo;
1080     FillElementInfo(param.elementId, elementInfo, context, jsAccessibilityManager, param);
1081     if (param.stackNodeId != -1) {
1082         int64_t stackNodeId = param.stackNodeId;
1083         AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(elementInfo.GetBelongTreeId(), stackNodeId);
1084         elementInfo.SetNavDestinationId(stackNodeId);
1085     }
1086     eventInfo.SetElementInfo(elementInfo);
1087 }
1088 #ifdef WEB_SUPPORTED
1089 
FillWebElementInfo(int64_t elementId,AccessibilityElementInfo & elementInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param,const RefPtr<NG::WebPattern> & webPattern)1090 void FillWebElementInfo(int64_t elementId, AccessibilityElementInfo& elementInfo,
1091                         const RefPtr<PipelineBase>& context,
1092                         const RefPtr<JsAccessibilityManager>& jsAccessibilityManager,
1093                         const FillEventInfoParam& param,
1094                         const RefPtr<NG::WebPattern>& webPattern)
1095 {
1096     std::list<AccessibilityElementInfo> elementInfos;
1097     int32_t mode = 0;
1098     CHECK_NULL_VOID(jsAccessibilityManager);
1099     jsAccessibilityManager->SearchWebElementInfoByAccessibilityIdNG(
1100         elementId, mode, elementInfos, context, webPattern);
1101     if (elementInfos.empty()) {
1102         LOGE("Element infos is empty. Find element infos failed.");
1103         return;
1104     }
1105     elementInfo = elementInfos.front();
1106     elementInfo.SetWindowId(param.windowId);
1107 }
1108 
FillWebEventInfo(AccessibilityEventInfo & eventInfo,const RefPtr<PipelineBase> & context,const RefPtr<JsAccessibilityManager> & jsAccessibilityManager,const FillEventInfoParam & param,const RefPtr<NG::WebPattern> & webPattern)1109 void FillWebEventInfo(AccessibilityEventInfo& eventInfo,
1110                       const RefPtr<PipelineBase>& context,
1111                       const RefPtr<JsAccessibilityManager>& jsAccessibilityManager,
1112                       const FillEventInfoParam& param,
1113                       const RefPtr<NG::WebPattern>& webPattern)
1114 {
1115     CHECK_NULL_VOID(webPattern);
1116     auto webNode = webPattern->GetHost();
1117     CHECK_NULL_VOID(webNode);
1118     eventInfo.SetPageId(webNode->GetPageId());
1119     AccessibilityElementInfo elementInfo;
1120     FillWebElementInfo(param.elementId, elementInfo, context, jsAccessibilityManager, param, webPattern);
1121     eventInfo.SetComponentType(elementInfo.GetComponentType());
1122     eventInfo.AddContent(elementInfo.GetContent());
1123     eventInfo.SetItemCounts(elementInfo.GetItemCounts());
1124     eventInfo.SetBeginIndex(elementInfo.GetBeginIndex());
1125     eventInfo.SetEndIndex(elementInfo.GetEndIndex());
1126     elementInfo.SetNavDestinationId(param.stackNodeId);
1127     eventInfo.SetElementInfo(elementInfo);
1128 }
1129 #endif
1130 
FillEventInfo(const RefPtr<AccessibilityNode> & node,AccessibilityEventInfo & eventInfo)1131 void FillEventInfo(const RefPtr<AccessibilityNode>& node, AccessibilityEventInfo& eventInfo)
1132 {
1133     eventInfo.SetComponentType(node->GetTag());
1134     if (node->GetTag() == LIST_TAG) {
1135         eventInfo.SetItemCounts(node->GetListItemCounts());
1136         eventInfo.SetBeginIndex(node->GetListBeginIndex());
1137         eventInfo.SetEndIndex(node->GetListEndIndex());
1138     }
1139     eventInfo.SetPageId(node->GetPageId());
1140     eventInfo.AddContent(node->GetText());
1141     eventInfo.SetLatestContent(node->GetText());
1142 }
1143 
IsPopupSupported(const RefPtr<NG::PipelineContext> & pipeline,int64_t nodeId)1144 inline bool IsPopupSupported(const RefPtr<NG::PipelineContext>& pipeline, int64_t nodeId)
1145 {
1146     CHECK_NULL_RETURN(pipeline, false);
1147     auto overlayManager = pipeline->GetOverlayManager();
1148     if (overlayManager) {
1149         return overlayManager->HasPopupInfo(nodeId);
1150     }
1151     return false;
1152 }
1153 
SetAccessibilityFocusAction(AccessibilityElementInfo & nodeInfo,const char * tag)1154 void SetAccessibilityFocusAction(AccessibilityElementInfo& nodeInfo, const char* tag)
1155 {
1156     if (nodeInfo.HasAccessibilityFocus()) {
1157         AccessibleAction action(ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, tag);
1158         nodeInfo.AddAction(action);
1159     } else {
1160         AccessibleAction action(ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, tag);
1161         nodeInfo.AddAction(action);
1162     }
1163 }
1164 
UpdateSupportAction(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo)1165 void UpdateSupportAction(const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo)
1166 {
1167     CHECK_NULL_VOID(node);
1168     if (nodeInfo.IsFocusable()) {
1169         if (nodeInfo.IsFocused()) {
1170             AccessibleAction action(ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ace");
1171             nodeInfo.AddAction(action);
1172         } else {
1173             AccessibleAction action(ACCESSIBILITY_ACTION_FOCUS, "ace");
1174             nodeInfo.AddAction(action);
1175         }
1176     }
1177 
1178     auto eventHub = node->GetEventHub<NG::EventHub>();
1179     CHECK_NULL_VOID(eventHub);
1180     auto gestureEventHub = eventHub->GetGestureEventHub();
1181     CHECK_NULL_VOID(gestureEventHub);
1182     nodeInfo.SetClickable(gestureEventHub->IsAccessibilityClickable());
1183     if (gestureEventHub->IsAccessibilityClickable()) {
1184         AccessibleAction action(ACCESSIBILITY_ACTION_CLICK, "ace");
1185         nodeInfo.AddAction(action);
1186     }
1187     nodeInfo.SetLongClickable(gestureEventHub->IsAccessibilityLongClickable());
1188     if (gestureEventHub->IsAccessibilityLongClickable()) {
1189         AccessibleAction action(ACCESSIBILITY_ACTION_LONG_CLICK, "ace");
1190         nodeInfo.AddAction(action);
1191     }
1192 }
1193 
UpdateUserAccessibilityElementInfo(const RefPtr<NG::AccessibilityProperty> & accessibilityProperty,AccessibilityElementInfo & nodeInfo)1194 void UpdateUserAccessibilityElementInfo(
1195     const RefPtr<NG::AccessibilityProperty>& accessibilityProperty, AccessibilityElementInfo& nodeInfo)
1196 {
1197     CHECK_NULL_VOID(accessibilityProperty);
1198     if (accessibilityProperty->HasUserDisabled()) {
1199         nodeInfo.SetEnabled(!accessibilityProperty->IsUserDisabled());
1200     }
1201     if (accessibilityProperty->HasUserCheckedType()) {
1202         nodeInfo.SetChecked(accessibilityProperty->GetUserCheckedType());
1203     } else {
1204         nodeInfo.SetChecked(accessibilityProperty->IsChecked());
1205     }
1206     if (accessibilityProperty->HasUserSelected()) {
1207         nodeInfo.SetSelected(accessibilityProperty->IsUserSelected());
1208     } else {
1209         nodeInfo.SetSelected(accessibilityProperty->IsSelected());
1210     }
1211 
1212     if (nodeInfo.IsEnabled()) {
1213         if (accessibilityProperty->HasUserCheckable()) {
1214             nodeInfo.SetCheckable(accessibilityProperty->IsUserCheckable());
1215         } else {
1216             nodeInfo.SetCheckable(accessibilityProperty->IsCheckable());
1217         }
1218     }
1219 }
1220 
IsUserCheckedOrSelected(const RefPtr<NG::FrameNode> frameNode)1221 bool IsUserCheckedOrSelected(const RefPtr<NG::FrameNode> frameNode)
1222 {
1223     auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1224     CHECK_NULL_RETURN(accessibilityProperty, false);
1225     if (accessibilityProperty->HasUserCheckedType() || accessibilityProperty->HasUserSelected()) {
1226         return true;
1227     }
1228     return false;
1229 }
1230 
UpdateElementInfoPageIdWithTreeId(Accessibility::AccessibilityElementInfo & info,int32_t treeId)1231 void UpdateElementInfoPageIdWithTreeId(Accessibility::AccessibilityElementInfo& info, int32_t treeId)
1232 {
1233     int32_t pageId = info.GetPageId();
1234     if ((pageId >= MAX_PAGE_ID_WITH_SUB_TREE) || (pageId < 0)) {
1235         TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "pageId %{public}d cannot set tree id", pageId);
1236     } else {
1237         uint32_t unsignedPageId = static_cast<uint32_t>(pageId);
1238         uint32_t unsignedTreeId = static_cast<uint32_t>(treeId);
1239         info.SetPageId((unsignedTreeId << SUB_TREE_OFFSET_IN_PAGE_ID) | unsignedPageId);
1240     }
1241 }
1242 } // namespace
1243 
UpdateAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo)1244 void JsAccessibilityManager::UpdateAccessibilityElementInfo(
1245     const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo)
1246 {
1247     CHECK_NULL_VOID(node);
1248     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1249     CHECK_NULL_VOID(accessibilityProperty);
1250     if (accessibilityProperty->HasAccessibilityRole()) {
1251         nodeInfo.SetComponentType(accessibilityProperty->GetAccessibilityRole());
1252     }
1253 
1254     if (accessibilityProperty->HasUserTextValue()) {
1255         nodeInfo.SetContent(accessibilityProperty->GetUserTextValue());
1256     } else {
1257         nodeInfo.SetContent(accessibilityProperty->GetGroupText());
1258     }
1259     nodeInfo.SetAccessibilityText(accessibilityProperty->GetAccessibilityText());
1260     if (accessibilityProperty->HasRange()) {
1261         RangeInfo rangeInfo = ConvertAccessibilityValue(accessibilityProperty->GetAccessibilityValue());
1262         nodeInfo.SetRange(rangeInfo);
1263     }
1264     if (accessibilityProperty->HasSubComponent()) {
1265         std::vector<SubComponentInfo> subComponentInfos;
1266         accessibilityProperty->GetSubComponentInfo(subComponentInfos);
1267         for (const auto& subComponent : subComponentInfos) {
1268             nodeInfo.AddSpan(SpanInfo(subComponent.spanId, subComponent.spanText,
1269                 subComponent.accessibilityText, subComponent.accessibilityDescription,
1270                 subComponent.accessibilityLevel));
1271         }
1272     }
1273     nodeInfo.SetHint(accessibilityProperty->GetHintText());
1274     nodeInfo.SetAccessibilityGroup(accessibilityProperty->IsAccessibilityGroup());
1275     nodeInfo.SetAccessibilityLevel(accessibilityProperty->GetAccessibilityLevel());
1276     nodeInfo.SetTextType(accessibilityProperty->GetTextType());
1277     nodeInfo.SetTextLengthLimit(accessibilityProperty->GetTextLengthLimit());
1278     nodeInfo.SetOffset(accessibilityProperty->GetScrollOffSet());
1279     auto context = node->GetRenderContext();
1280     if (context != nullptr) {
1281         nodeInfo.SetZIndex(context->GetZIndex().value_or(0));
1282         nodeInfo.SetOpacity(context->GetOpacity().value_or(1));
1283         nodeInfo.SetBackgroundColor(context->GetBackgroundColor().value_or(Color::TRANSPARENT).ToString());
1284         nodeInfo.SetBackgroundImage(context->GetBackgroundImage().value_or(ImageSourceInfo("")).ToString());
1285         if (context->GetForeground() != nullptr) {
1286             nodeInfo.SetBlur(context->GetForeground()->propBlurRadius.value_or(Dimension(0)).ToString());
1287         }
1288     }
1289     auto eventHub = node->GetEventHub<NG::EventHub>();
1290     if (eventHub != nullptr) {
1291         auto gestureEventHub = eventHub->GetGestureEventHub();
1292         if (gestureEventHub != nullptr) {
1293             nodeInfo.SetHitTestBehavior(gestureEventHub->GetHitTestModeStr());
1294         }
1295     }
1296 
1297     UpdateUserAccessibilityElementInfo(accessibilityProperty, nodeInfo);
1298 
1299     nodeInfo.SetPassword(accessibilityProperty->IsPassword());
1300     nodeInfo.SetPluraLineSupported(accessibilityProperty->IsMultiLine());
1301     nodeInfo.SetHinting(accessibilityProperty->IsHint());
1302     nodeInfo.SetDescriptionInfo(accessibilityProperty->GetAccessibilityDescription());
1303     if (accessibilityProperty->HasUserCurrentValue()) {
1304         nodeInfo.SetCurrentIndex(accessibilityProperty->GetUserCurrentValue());
1305     } else {
1306         nodeInfo.SetCurrentIndex(accessibilityProperty->GetCurrentIndex());
1307     }
1308     if (accessibilityProperty->HasUserMinValue()) {
1309         nodeInfo.SetBeginIndex(accessibilityProperty->GetUserMinValue());
1310     } else {
1311         nodeInfo.SetBeginIndex(accessibilityProperty->GetBeginIndex());
1312     }
1313     if (accessibilityProperty->HasUserMaxValue()) {
1314         nodeInfo.SetEndIndex(accessibilityProperty->GetUserMaxValue());
1315     } else {
1316         nodeInfo.SetEndIndex(accessibilityProperty->GetEndIndex());
1317     }
1318     auto tag = node->GetTag();
1319     if (tag == V2::TOAST_ETS_TAG || tag == V2::POPUP_ETS_TAG || tag == V2::DIALOG_ETS_TAG ||
1320         tag == V2::ACTION_SHEET_DIALOG_ETS_TAG || tag == V2::ALERT_DIALOG_ETS_TAG || tag == V2::MENU_ETS_TAG ||
1321         tag == "SelectMenu") {
1322         nodeInfo.SetLiveRegion(1);
1323     }
1324     nodeInfo.SetContentInvalid(accessibilityProperty->GetContentInvalid());
1325     nodeInfo.SetError(accessibilityProperty->GetErrorText());
1326     nodeInfo.SetSelectedBegin(accessibilityProperty->GetTextSelectionStart());
1327     nodeInfo.SetSelectedEnd(accessibilityProperty->GetTextSelectionEnd());
1328     nodeInfo.SetInputType(static_cast<int>(accessibilityProperty->GetTextInputType()));
1329     nodeInfo.SetItemCounts(accessibilityProperty->GetCollectionItemCounts());
1330     nodeInfo.SetChildTreeIdAndWinId(
1331         accessibilityProperty->GetChildTreeId(), accessibilityProperty->GetChildWindowId());
1332     if (nodeInfo.GetComponentType() == "FormComponent") {
1333         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", Set: %{public}d %{public}d",
1334             nodeInfo.GetAccessibilityId(), accessibilityProperty->GetChildTreeId(),
1335             accessibilityProperty->GetChildWindowId());
1336     }
1337     if (nodeInfo.GetWindowId() == static_cast<int32_t>(windowId_)) {
1338         nodeInfo.SetBelongTreeId(treeId_);
1339         nodeInfo.SetParentWindowId(parentWindowId_);
1340     } else {
1341         nodeInfo.SetBelongTreeId(0);
1342         nodeInfo.SetParentWindowId(0);
1343     }
1344 
1345     GridInfo gridInfo(accessibilityProperty->GetCollectionInfo().rows,
1346         accessibilityProperty->GetCollectionInfo().columns, accessibilityProperty->GetCollectionInfo().selectMode);
1347     nodeInfo.SetGrid(gridInfo);
1348     ExtraElementInfo extraElementInfo {};
1349     accessibilityProperty->GetAllExtraElementInfo(extraElementInfo);
1350     nodeInfo.SetExtraElement(extraElementInfo);
1351 
1352     int32_t row = accessibilityProperty->GetCollectionItemInfo().row;
1353     int32_t column = accessibilityProperty->GetCollectionItemInfo().column;
1354     int32_t rowSpan = accessibilityProperty->GetCollectionItemInfo().rowSpan;
1355     int32_t columnSpan = accessibilityProperty->GetCollectionItemInfo().columnSpan;
1356     bool heading = accessibilityProperty->GetCollectionItemInfo().heading;
1357     GridItemInfo gridItemInfo(row, rowSpan, column, columnSpan, heading, nodeInfo.IsSelected());
1358     nodeInfo.SetGridItem(gridItemInfo);
1359 
1360     SetAccessibilityFocusAction(nodeInfo, "ace");
1361     if (nodeInfo.IsEnabled()) {
1362         nodeInfo.SetScrollable(accessibilityProperty->IsScrollable());
1363         nodeInfo.SetEditable(accessibilityProperty->IsEditable());
1364         nodeInfo.SetDeletable(accessibilityProperty->IsDeletable());
1365         UpdateSupportAction(node, nodeInfo);
1366         accessibilityProperty->ResetSupportAction();
1367         auto supportAceActions = accessibilityProperty->GetSupportAction();
1368         for (auto it = supportAceActions.begin(); it != supportAceActions.end(); ++it) {
1369             AccessibleAction action(ConvertAceAction(*it), "ace");
1370             nodeInfo.AddAction(action);
1371         }
1372     }
1373 }
1374 #ifdef WEB_SUPPORTED
1375 
UpdateWebAccessibilityElementInfo(const std::shared_ptr<NWeb::NWebAccessibilityNodeInfo> & node,AccessibilityElementInfo & nodeInfo,int32_t treeId)1376 void JsAccessibilityManager::UpdateWebAccessibilityElementInfo(
1377     const std::shared_ptr<NWeb::NWebAccessibilityNodeInfo>& node, AccessibilityElementInfo& nodeInfo, int32_t treeId)
1378 {
1379     CHECK_NULL_VOID(node);
1380     nodeInfo.SetContent(node->GetContent());
1381     nodeInfo.SetAccessibilityText(node->GetContent());
1382     RangeInfo rangeInfo(node->GetRangeInfoMin(), node->GetRangeInfoMax(), node->GetRangeInfoCurrent());
1383     nodeInfo.SetRange(rangeInfo);
1384     nodeInfo.SetHint(node->GetHint());
1385     nodeInfo.SetHinting(node->GetIsHinting());
1386     nodeInfo.SetDescriptionInfo(node->GetDescriptionInfo());
1387     nodeInfo.SetChecked(node->GetIsChecked());
1388     nodeInfo.SetSelected(node->GetIsSelected());
1389     nodeInfo.SetPassword(node->GetIsPassword());
1390     nodeInfo.SetPluraLineSupported(node->GetIsPluralLineSupported());
1391     nodeInfo.SetLiveRegion(node->GetLiveRegion());
1392     nodeInfo.SetContentInvalid(node->GetIsContentInvalid());
1393     nodeInfo.SetError(node->GetError());
1394     nodeInfo.SetSelectedBegin(node->GetSelectionStart());
1395     nodeInfo.SetSelectedEnd(node->GetSelectionEnd());
1396     nodeInfo.SetInputType(node->GetInputType());
1397     nodeInfo.SetItemCounts(node->GetItemCounts());
1398 
1399     nodeInfo.SetBelongTreeId(treeId);
1400     nodeInfo.SetParentWindowId(parentWebWindowId_);
1401 
1402     GridInfo gridInfo(node->GetGridRows(), node->GetGridColumns(), node->GetGridSelectedMode());
1403     nodeInfo.SetGrid(gridInfo);
1404 
1405     int32_t row = node->GetGridItemRow();
1406     int32_t column = node->GetGridItemColumn();
1407     int32_t rowSpan = node->GetGridItemRowSpan();
1408     int32_t columnSpan = node->GetGridItemColumnSpan();
1409     bool heading = node->GetIsHeading();
1410     GridItemInfo gridItemInfo(row, rowSpan, column, columnSpan, heading, nodeInfo.IsSelected());
1411     nodeInfo.SetGridItem(gridItemInfo);
1412 
1413     SetAccessibilityFocusAction(nodeInfo, "web");
1414     if (nodeInfo.IsEnabled()) {
1415         nodeInfo.SetCheckable(node->GetIsCheckable());
1416         nodeInfo.SetScrollable(node->GetIsScrollable());
1417         nodeInfo.SetEditable(node->GetIsEditable());
1418         nodeInfo.SetDeletable(node->GetIsDeletable());
1419         nodeInfo.SetClickable(node->GetIsClickable());
1420         auto supportAceActions = node->GetActions();
1421         for (auto it = supportAceActions.begin(); it != supportAceActions.end(); ++it) {
1422             AccessibleAction action(ConvertAceAction(static_cast<AceAction>(*it)), "web");
1423             nodeInfo.AddAction(action);
1424         }
1425     }
1426     nodeInfo.SetAccessibilityGroup(node->GetIsAccessibilityGroup());
1427 }
1428 
1429 #endif
1430 namespace {
UpdateChildrenOfAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo)1431 void UpdateChildrenOfAccessibilityElementInfo(
1432     const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty, AccessibilityElementInfo& nodeInfo)
1433 {
1434     if (!IsExtensionComponent(node) || IsUIExtensionShowPlaceholder(node)) {
1435         std::vector<int64_t> children;
1436         for (const auto& item : node->GetChildren(true)) {
1437             GetFrameNodeChildren(item, children, commonProperty.pageId);
1438         }
1439 
1440         auto overlayNode = node->GetOverlayNode();
1441         if (overlayNode != nullptr) {
1442             GetFrameNodeChildren(overlayNode, children, commonProperty.pageId);
1443         }
1444 
1445         auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1446         auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
1447         if (uiVirtualNode != nullptr) {
1448             auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
1449             if (virtualNode != nullptr) {
1450                 children.clear();
1451                 GetFrameNodeChildren(virtualNode, children, commonProperty.pageId);
1452             }
1453         }
1454         for (const auto& child : children) {
1455             nodeInfo.AddChild(child);
1456         }
1457     }
1458 }
1459 
1460 }
1461 
UpdateVirtualNodeChildAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeParentInfo,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::PipelineContext> & ngPipeline)1462 void JsAccessibilityManager::UpdateVirtualNodeChildAccessibilityElementInfo(
1463     const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty,
1464     AccessibilityElementInfo& nodeParentInfo, AccessibilityElementInfo& nodeInfo,
1465     const RefPtr<NG::PipelineContext>& ngPipeline)
1466 {
1467     CHECK_NULL_VOID(node);
1468     nodeInfo.SetParent(GetParentId(node));
1469     UpdateChildrenOfAccessibilityElementInfo(node, commonProperty, nodeInfo);
1470 
1471     nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
1472     nodeInfo.SetComponentType(node->GetTag());
1473 
1474     nodeInfo.SetEnabled(node->GetFocusHub() ? node->GetFocusHub()->IsEnabled() : true);
1475     nodeInfo.SetFocused(node->GetFocusHub() ? node->GetFocusHub()->IsCurrentFocus() : false);
1476     nodeInfo.SetAccessibilityFocus(node->GetRenderContext()->GetAccessibilityFocus().value_or(false));
1477     nodeInfo.SetInspectorKey(node->GetInspectorId().value_or(""));
1478     nodeInfo.SetVisible(node->IsVisible());
1479     if (node->IsVisible()) {
1480         auto rect = node->GetVirtualNodeTransformRectRelativeToWindow();
1481         auto left = rect.Left() + commonProperty.windowLeft;
1482         auto top = rect.Top() + commonProperty.windowTop;
1483         auto right = rect.Right() + commonProperty.windowLeft;
1484         auto bottom = rect.Bottom() + commonProperty.windowTop;
1485         Accessibility::Rect bounds { left, top, right, bottom };
1486         nodeInfo.SetRectInScreen(bounds);
1487     }
1488     nodeInfo.SetWindowId(commonProperty.windowId);
1489     nodeInfo.SetPageId(node->GetPageId());
1490     nodeInfo.SetPagePath(commonProperty.pagePath);
1491     nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
1492 
1493     if (nodeInfo.IsEnabled()) {
1494         nodeInfo.SetFocusable(node->GetFocusHub() ? node->GetFocusHub()->IsFocusable() : false);
1495         nodeInfo.SetPopupSupported(IsPopupSupported(ngPipeline, node->GetId()));
1496     }
1497     nodeInfo.SetComponentResourceId(node->GetInspectorId().value_or(""));
1498     UpdateAccessibilityElementInfo(node, nodeInfo);
1499 }
1500 
UpdateVirtualNodeAccessibilityElementInfo(const RefPtr<NG::FrameNode> & parent,const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::PipelineContext> & ngPipeline)1501 void JsAccessibilityManager::UpdateVirtualNodeAccessibilityElementInfo(
1502     const RefPtr<NG::FrameNode>& parent, const RefPtr<NG::FrameNode>& node,
1503     const CommonProperty& commonProperty, AccessibilityElementInfo& nodeInfo,
1504     const RefPtr<NG::PipelineContext>& ngPipeline)
1505 {
1506     CHECK_NULL_VOID(parent);
1507     CHECK_NULL_VOID(node);
1508     nodeInfo.SetParent(GetParentId(node));
1509     UpdateChildrenOfAccessibilityElementInfo(node, commonProperty, nodeInfo);
1510 
1511     nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
1512     nodeInfo.SetComponentType(node->GetTag());
1513 
1514     nodeInfo.SetEnabled(node->GetFocusHub() ? node->GetFocusHub()->IsEnabled() : true);
1515     nodeInfo.SetFocused(node->GetFocusHub() ? node->GetFocusHub()->IsCurrentFocus() : false);
1516     nodeInfo.SetAccessibilityFocus(node->GetRenderContext()->GetAccessibilityFocus().value_or(false));
1517     nodeInfo.SetInspectorKey(node->GetInspectorId().value_or(""));
1518     nodeInfo.SetVisible(node->IsVisible());
1519     if (node->IsVisible()) {
1520         auto virtualNodeRect = node->GetTransformRectRelativeToWindow();
1521         auto parentRect = parent->GetTransformRectRelativeToWindow();
1522         auto left = parentRect.Left() + commonProperty.windowLeft;
1523         auto top = parentRect.Top() + commonProperty.windowTop;
1524         auto right = parentRect.Left() + virtualNodeRect.Width() + commonProperty.windowLeft;
1525         if (virtualNodeRect.Width() > (parentRect.Right() - parentRect.Left())) {
1526             right = parentRect.Right() + commonProperty.windowLeft;
1527         }
1528         auto bottom = parentRect.Top() + virtualNodeRect.Height() + commonProperty.windowTop;
1529         if (virtualNodeRect.Height() > (parentRect.Bottom() - parentRect.Top())) {
1530             bottom = parentRect.Bottom() + commonProperty.windowTop;
1531         }
1532         Accessibility::Rect bounds { left, top, right, bottom };
1533         nodeInfo.SetRectInScreen(bounds);
1534     }
1535     nodeInfo.SetWindowId(commonProperty.windowId);
1536     nodeInfo.SetPageId(node->GetPageId());
1537     nodeInfo.SetPagePath(commonProperty.pagePath);
1538     nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
1539 
1540     if (nodeInfo.IsEnabled()) {
1541         nodeInfo.SetFocusable(node->GetFocusHub() ? node->GetFocusHub()->IsFocusable() : false);
1542         nodeInfo.SetPopupSupported(IsPopupSupported(ngPipeline, node->GetId()));
1543     }
1544     nodeInfo.SetComponentResourceId(node->GetInspectorId().value_or(""));
1545     UpdateAccessibilityElementInfo(node, nodeInfo);
1546 }
1547 
UpdateAccessibilityVisible(const RefPtr<NG::FrameNode> & node,AccessibilityElementInfo & nodeInfo)1548 void JsAccessibilityManager::UpdateAccessibilityVisible(
1549     const RefPtr<NG::FrameNode>& node, AccessibilityElementInfo& nodeInfo)
1550 {
1551     auto parentNode = node->GetParentFrameNode();
1552     UpdateElementInfoTreeId(nodeInfo);
1553 
1554     if (!parentNode) {
1555         if (node->GetTag() != V2::PAGE_ETS_TAG) {
1556             node->SetAccessibilityVisible(node->IsActive() && node->IsVisible());
1557         }
1558     } else {
1559         if (node->GetTag() == V2::PAGE_ETS_TAG) {
1560             nodeInfo.SetAccessibilityVisible(node->IsActive() && node->IsVisible() && node->GetAccessibilityVisible() &&
1561                                              parentNode->GetAccessibilityVisible());
1562             return;
1563         }
1564         auto nodeAccessibilityVisible = node->IsActive() && node->IsVisible() && parentNode->GetAccessibilityVisible();
1565         node->SetAccessibilityVisible(nodeAccessibilityVisible);
1566         if (!nodeAccessibilityVisible) {
1567             TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
1568                 "Element %{public}" PRId64 " is invisible. node isActive %{public}d, node isVisible %{public}d"
1569                 "parent accessibilityVisible:%{public}d.parent id %{public}" PRId64,
1570                 nodeInfo.GetAccessibilityId(), node->IsActive(), node->IsVisible(),
1571                 parentNode->GetAccessibilityVisible(), parentNode->GetAccessibilityId());
1572         }
1573     }
1574     nodeInfo.SetAccessibilityVisible(node->GetAccessibilityVisible());
1575 }
1576 
1577 namespace {
GetFinalRealRect(const RefPtr<NG::FrameNode> & node)1578     NG::RectF GetFinalRealRect(const RefPtr<NG::FrameNode>& node)
1579     {
1580         // get the node position after rotation compensation
1581         auto offset = node->GetPositionToWindowWithTransform(false);
1582         auto offsetBottom = node->GetPositionToWindowWithTransform(true);
1583         return {
1584             LessNotEqual(offset.GetX(), offsetBottom.GetX()) ? offset.GetX() : offsetBottom.GetX(),
1585             LessNotEqual(offset.GetY(), offsetBottom.GetY()) ? offset.GetY() : offsetBottom.GetY(),
1586             LessNotEqual(offset.GetX(), offsetBottom.GetX())
1587                 ? offsetBottom.GetX() - offset.GetX()
1588                 : offset.GetX() - offsetBottom.GetX(),
1589             LessNotEqual(offset.GetY(), offsetBottom.GetY())
1590                 ? offsetBottom.GetY() - offset.GetY()
1591                 : offset.GetY() - offsetBottom.GetY()
1592             };
1593     }
1594 }
1595 
UpdateAccessibilityElementInfo(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::PipelineContext> & ngPipeline)1596 void JsAccessibilityManager::UpdateAccessibilityElementInfo(
1597     const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty,
1598     AccessibilityElementInfo& nodeInfo, const RefPtr<NG::PipelineContext>& ngPipeline)
1599 {
1600     CHECK_NULL_VOID(node);
1601     nodeInfo.SetParent(GetParentId(node));
1602     UpdateChildrenOfAccessibilityElementInfo(node, commonProperty, nodeInfo);
1603 
1604     nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
1605     nodeInfo.SetComponentType(node->GetTag());
1606 
1607     nodeInfo.SetEnabled(node->GetFocusHub() ? node->GetFocusHub()->IsEnabled() : true);
1608     nodeInfo.SetFocused(node->GetFocusHub() ? node->GetFocusHub()->IsCurrentFocus() : false);
1609     nodeInfo.SetAccessibilityFocus(node->GetRenderContext()->GetAccessibilityFocus().value_or(false));
1610     nodeInfo.SetInspectorKey(node->GetInspectorId().value_or(""));
1611     nodeInfo.SetVisible(node->IsVisible());
1612     if (node->IsAccessibilityVirtualNode()) {
1613         auto rect = node->GetVirtualNodeTransformRectRelativeToWindow();
1614         auto left = rect.Left() + commonProperty.windowLeft;
1615         auto top = rect.Top() + commonProperty.windowTop;
1616         auto right = rect.Right() + commonProperty.windowLeft;
1617         auto bottom = rect.Bottom() + commonProperty.windowTop;
1618         Accessibility::Rect bounds { left, top, right, bottom };
1619         nodeInfo.SetRectInScreen(bounds);
1620     } else if (node->IsVisible()) {
1621         auto rect = GetFinalRealRect(node);
1622         auto left = rect.Left() + commonProperty.windowLeft;
1623         auto top = rect.Top() + commonProperty.windowTop;
1624         auto right = rect.Right() + commonProperty.windowLeft;
1625         auto bottom = rect.Bottom() + commonProperty.windowTop;
1626         Accessibility::Rect bounds { left, top, right, bottom };
1627         nodeInfo.SetRectInScreen(bounds);
1628     }
1629     nodeInfo.SetWindowId(commonProperty.windowId);
1630     // is abnormal that pageId equals to 0, use commonProperty.pageId to fix pageId
1631     if (node->GetPageId()) {
1632         nodeInfo.SetPageId(node->GetPageId());
1633     } else {
1634         nodeInfo.SetPageId(commonProperty.pageId);
1635     }
1636     nodeInfo.SetPagePath(commonProperty.pagePath);
1637     nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
1638 
1639     if (nodeInfo.IsEnabled()) {
1640         nodeInfo.SetFocusable(node->GetFocusHub() ? node->GetFocusHub()->IsFocusable() : false);
1641         nodeInfo.SetPopupSupported(IsPopupSupported(ngPipeline, node->GetId()));
1642     }
1643     nodeInfo.SetComponentResourceId(node->GetInspectorId().value_or(""));
1644     UpdateAccessibilityElementInfo(node, nodeInfo);
1645     UpdateAccessibilityVisible(node, nodeInfo);
1646 }
1647 #ifdef WEB_SUPPORTED
1648 
UpdateWebAccessibilityElementInfo(const std::shared_ptr<NWeb::NWebAccessibilityNodeInfo> & node,const CommonProperty & commonProperty,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::WebPattern> & webPattern)1649 void JsAccessibilityManager::UpdateWebAccessibilityElementInfo(
1650     const std::shared_ptr<NWeb::NWebAccessibilityNodeInfo>& node, const CommonProperty& commonProperty,
1651     AccessibilityElementInfo& nodeInfo, const RefPtr<NG::WebPattern>& webPattern)
1652 {
1653     if (node->GetParentId() == -1) {
1654         nodeInfo.SetParent(INVALID_PARENT_ID);
1655     } else {
1656         nodeInfo.SetParent(node->GetParentId());
1657     }
1658     for (const auto& child : node->GetChildIds()) {
1659         nodeInfo.AddChild(child);
1660     }
1661 
1662     nodeInfo.SetAccessibilityId(node->GetAccessibilityId());
1663     nodeInfo.SetComponentType(node->GetComponentType());
1664     nodeInfo.SetEnabled(node->GetIsEnabled());
1665     nodeInfo.SetFocused(node->GetIsFocused());
1666     nodeInfo.SetAccessibilityFocus(node->GetIsAccessibilityFocus());
1667 
1668     nodeInfo.SetVisible(node->GetIsVisible());
1669     if (node->GetIsVisible()) {
1670         CHECK_NULL_VOID(webPattern);
1671         auto webNode = webPattern->GetHost();
1672         CHECK_NULL_VOID(webNode);
1673         auto webRect = webNode->GetTransformRectRelativeToWindow();
1674         auto left = webRect.Left() + node->GetRectX() + commonProperty.windowLeft;
1675         auto top = webRect.Top() + node->GetRectY() + commonProperty.windowTop;
1676         auto right = webRect.Left() + node->GetRectX() + node->GetRectWidth() + commonProperty.windowLeft;
1677         auto bottom = webRect.Top() + node->GetRectY() + node->GetRectHeight() + commonProperty.windowTop;
1678         Accessibility::Rect bounds { left, top, right, bottom };
1679         nodeInfo.SetRectInScreen(bounds);
1680     }
1681 
1682     nodeInfo.SetWindowId(commonProperty.windowId);
1683     nodeInfo.SetPageId(node->GetPageId());
1684     nodeInfo.SetPagePath(commonProperty.pagePath);
1685     nodeInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
1686 
1687     if (nodeInfo.IsEnabled()) {
1688         nodeInfo.SetFocusable(node->GetIsFocusable());
1689         nodeInfo.SetPopupSupported(node->GetIsPopupSupported());
1690     }
1691     CHECK_NULL_VOID(webPattern);
1692     UpdateWebAccessibilityElementInfo(node, nodeInfo, webPattern->GetTreeId());
1693 }
1694 
1695 #endif
1696 namespace {
SearchExtensionElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,const RefPtr<NG::FrameNode> & node,int64_t offset)1697 std::list<AccessibilityElementInfo> SearchExtensionElementInfoByAccessibilityIdNG(
1698     int64_t elementId, int32_t mode, const RefPtr<NG::FrameNode>& node,  int64_t offset)
1699 {
1700     std::list<AccessibilityElementInfo> extensionElementInfo;
1701     if (NG::UI_EXTENSION_OFFSET_MIN < (offset + 1)) {
1702         node->SearchExtensionElementInfoByAccessibilityIdNG(elementId, mode,
1703             offset / NG::UI_EXTENSION_ID_FACTOR, extensionElementInfo);
1704     }
1705     return extensionElementInfo;
1706 }
1707 
UpdateUiExtensionParentIdForFocus(const RefPtr<NG::FrameNode> & rootNode,const int64_t uiExtensionOffset,Accessibility::AccessibilityElementInfo & info)1708 void UpdateUiExtensionParentIdForFocus(const RefPtr<NG::FrameNode>& rootNode, const int64_t uiExtensionOffset,
1709     Accessibility::AccessibilityElementInfo& info)
1710 {
1711     if ((uiExtensionOffset != NG::UI_EXTENSION_OFFSET_MAX) && (info.GetComponentType() != V2::ROOT_ETS_TAG) &&
1712         (info.GetParentNodeId() == rootNode->GetAccessibilityId())) {
1713             info.SetParent(NG::UI_EXTENSION_ROOT_ID);
1714     }
1715 }
1716 
GetChildrenFromFrameNode(const RefPtr<NG::FrameNode> & node,std::list<RefPtr<NG::FrameNode>> & children,int32_t pageId)1717 void GetChildrenFromFrameNode(const RefPtr<NG::FrameNode>& node,
1718     std::list<RefPtr<NG::FrameNode>>& children, int32_t pageId)
1719 {
1720     std::list<RefPtr<NG::FrameNode>> frameNodeChildren;
1721     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1722     auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
1723     if (uiVirtualNode != nullptr) {
1724         auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
1725         if (virtualNode != nullptr) {
1726             GetFrameNodeChildren(virtualNode, frameNodeChildren, pageId);
1727         }
1728     } else {
1729         for (const auto& item : node->GetChildren(true)) {
1730             GetFrameNodeChildren(item, frameNodeChildren, pageId);
1731         }
1732 
1733         auto overlayNode = node->GetOverlayNode();
1734         if (overlayNode != nullptr) {
1735             GetFrameNodeChildren(overlayNode, frameNodeChildren, pageId);
1736         }
1737     }
1738     while (!frameNodeChildren.empty()) {
1739         children.emplace_back(frameNodeChildren.front());
1740         frameNodeChildren.pop_front();
1741     }
1742 }
1743 }
1744 
UpdateVirtualNodeInfo(std::list<AccessibilityElementInfo> & infos,AccessibilityElementInfo & nodeInfo,const RefPtr<NG::UINode> & uiVirtualNode,const CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline)1745 void JsAccessibilityManager::UpdateVirtualNodeInfo(std::list<AccessibilityElementInfo>& infos,
1746     AccessibilityElementInfo& nodeInfo, const RefPtr<NG::UINode>& uiVirtualNode, const CommonProperty& commonProperty,
1747     const RefPtr<NG::PipelineContext>& ngPipeline)
1748 {
1749     for (const auto& item : uiVirtualNode->GetChildren(true)) {
1750         AccessibilityElementInfo virtualInfo;
1751         auto frameNodeChild = AceType::DynamicCast<NG::FrameNode>(item);
1752         if (frameNodeChild == nullptr) {
1753             continue;
1754         }
1755         UpdateVirtualNodeChildAccessibilityElementInfo(frameNodeChild, commonProperty,
1756             nodeInfo, virtualInfo, ngPipeline);
1757         virtualInfo.SetParent(uiVirtualNode->GetAccessibilityId());
1758         nodeInfo.AddChild(frameNodeChild->GetAccessibilityId());
1759         UpdateVirtualNodeInfo(infos, virtualInfo, item, commonProperty, ngPipeline);
1760         infos.push_back(virtualInfo);
1761     }
1762 }
1763 
1764 namespace {
SearchExtensionElementInfoNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,Accessibility::AccessibilityElementInfo & parentInfo)1765 void SearchExtensionElementInfoNG(const SearchParameter& searchParam,
1766     const RefPtr<NG::FrameNode>& node, std::list<Accessibility::AccessibilityElementInfo>& infos,
1767     Accessibility::AccessibilityElementInfo& parentInfo)
1768 {
1769     auto extensionElementInfos = SearchExtensionElementInfoByAccessibilityIdNG(
1770         searchParam.nodeId, searchParam.mode, node, searchParam.uiExtensionOffset);
1771     if (extensionElementInfos.size() > 0) {
1772         auto rootParentId = extensionElementInfos.front().GetParentNodeId();
1773         ConvertExtensionAccessibilityNodeId(extensionElementInfos, node, searchParam.uiExtensionOffset, parentInfo);
1774         if (rootParentId == NG::UI_EXTENSION_ROOT_ID) {
1775             extensionElementInfos.front().SetParent(node->GetAccessibilityId());
1776         }
1777         if (parentInfo.GetComponentType() == V2::ISOLATED_COMPONENT_ETS_TAG) {
1778             auto windowId = parentInfo.GetWindowId();
1779             for (auto& info : extensionElementInfos) {
1780                 info.SetWindowId(windowId);
1781             }
1782         }
1783         for (auto& info : extensionElementInfos) {
1784             infos.push_back(info);
1785         }
1786     }
1787 }
1788 
IsNodeInRoot(const RefPtr<NG::FrameNode> & node,const RefPtr<NG::PipelineContext> & ngPipeline)1789 bool IsNodeInRoot(const RefPtr<NG::FrameNode>& node, const RefPtr<NG::PipelineContext>& ngPipeline)
1790 {
1791     CHECK_NULL_RETURN(node, false);
1792     CHECK_NULL_RETURN(ngPipeline, false);
1793     auto rect = node->GetTransformRectRelativeToWindow();
1794     auto root = ngPipeline->GetRootElement();
1795     CHECK_NULL_RETURN(root, false);
1796     auto rootRect = root->GetTransformRectRelativeToWindow();
1797     return LessNotEqual(rect.GetX(), rootRect.GetX() + rootRect.Width());
1798 }
1799 }
1800 
UpdateCacheInfoNG(std::list<AccessibilityElementInfo> & infos,const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline,const SearchParameter & searchParam)1801 void JsAccessibilityManager::UpdateCacheInfoNG(std::list<AccessibilityElementInfo>& infos,
1802     const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty,
1803     const RefPtr<NG::PipelineContext>& ngPipeline, const SearchParameter& searchParam)
1804 {
1805     uint32_t umode = searchParam.mode;
1806     std::list<RefPtr<NG::FrameNode>> children;
1807     // get all children
1808     if (!(umode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN))) {
1809         return;
1810     }
1811     GetChildrenFromFrameNode(node, children, commonProperty.pageId);
1812     while (!children.empty()) {
1813         RefPtr<NG::FrameNode> frameNodeParent = children.front();
1814         children.pop_front();
1815         AccessibilityElementInfo nodeInfo;
1816         auto accessibilityProperty = frameNodeParent->GetAccessibilityProperty<NG::AccessibilityProperty>();
1817         auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
1818         UpdateAccessibilityElementInfo(frameNodeParent, commonProperty, nodeInfo, ngPipeline);
1819         if (uiVirtualNode != nullptr) {
1820             auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
1821             if (virtualNode == nullptr) {
1822                 continue;
1823             }
1824             AccessibilityElementInfo virtualInfo;
1825             UpdateVirtualNodeAccessibilityElementInfo(frameNodeParent, virtualNode,
1826                 commonProperty, virtualInfo, ngPipeline);
1827             virtualInfo.SetParent(frameNodeParent->GetAccessibilityId());
1828             auto childIds = nodeInfo.GetChildIds();
1829             for (auto& child : childIds) {
1830                 nodeInfo.RemoveChild(child);
1831             }
1832             nodeInfo.AddChild(virtualNode->GetAccessibilityId());
1833             auto uiParentNode = AceType::DynamicCast<NG::UINode>(frameNodeParent);
1834             if (!uiVirtualNode->GetChildren(true).empty()) {
1835                 UpdateVirtualNodeInfo(infos, virtualInfo, uiVirtualNode, commonProperty, ngPipeline);
1836             }
1837             infos.push_back(virtualInfo);
1838             infos.push_back(nodeInfo);
1839             continue;
1840         }
1841         if (!IsExtensionComponent(frameNodeParent) || IsUIExtensionShowPlaceholder(frameNodeParent)) {
1842             infos.push_back(nodeInfo);
1843             GetChildrenFromFrameNode(frameNodeParent, children, commonProperty.pageId);
1844             continue;
1845         }
1846         if (!((frameNodeParent->GetUiExtensionId() > NG::UI_EXTENSION_UNKNOW_ID) &&
1847             (((frameNodeParent->GetUiExtensionId() <= NG::UI_EXTENSION_ID_FIRST_MAX) &&
1848             (NG::UI_EXTENSION_OFFSET_MAX == searchParam.uiExtensionOffset)) ||
1849             (frameNodeParent->GetUiExtensionId() <= NG::UI_EXTENSION_ID_OTHER_MAX)))) {
1850             continue;
1851         }
1852         auto transferParam = searchParam;
1853         transferParam.nodeId = NG::UI_EXTENSION_ROOT_ID;
1854         SearchExtensionElementInfoNG(transferParam, frameNodeParent, infos, nodeInfo);
1855         infos.push_back(nodeInfo);
1856     }
1857 }
1858 
1859 namespace {
CanAccessibilityFocusedNG(const RefPtr<NG::FrameNode> & node)1860 bool CanAccessibilityFocusedNG(const RefPtr<NG::FrameNode>& node)
1861 {
1862     CHECK_NULL_RETURN(node, false);
1863     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1864     CHECK_NULL_RETURN(accessibilityProperty, false);
1865     auto level = accessibilityProperty->GetAccessibilityLevel();
1866     return !node->IsRootNode() &&
1867            node->GetLayoutProperty()->GetVisibilityValue(VisibleType::VISIBLE) == VisibleType::VISIBLE &&
1868            level != NG::AccessibilityProperty::Level::NO_STR &&
1869            level != NG::AccessibilityProperty::Level::NO_HIDE_DESCENDANTS;
1870 }
1871 // focus move search
AddFocusableNode(std::list<RefPtr<NG::FrameNode>> & nodeList,const RefPtr<NG::FrameNode> & node)1872 void AddFocusableNode(std::list<RefPtr<NG::FrameNode>>& nodeList, const RefPtr<NG::FrameNode>& node)
1873 {
1874     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
1875     CHECK_NULL_VOID(accessibilityProperty);
1876     auto level = accessibilityProperty->GetAccessibilityLevel();
1877     if (CanAccessibilityFocusedNG(node)) {
1878         nodeList.emplace_back(node);
1879     }
1880 
1881     if (!accessibilityProperty->IsAccessibilityGroup() &&
1882         level != NG::AccessibilityProperty::Level::NO_HIDE_DESCENDANTS) {
1883         std::list<RefPtr<NG::FrameNode>> children;
1884         for (const auto& child : node->GetChildren(true)) {
1885             GetFrameNodeChildren(child, children);
1886         }
1887 
1888         for (const auto& child : children) {
1889             AddFocusableNode(nodeList, child);
1890         }
1891     }
1892 }
1893 
1894 // execute action
RequestFocus(RefPtr<NG::FrameNode> & frameNode)1895 bool RequestFocus(RefPtr<NG::FrameNode>& frameNode)
1896 {
1897     auto focusHub = frameNode->GetFocusHub();
1898     CHECK_NULL_RETURN(focusHub, false);
1899     return focusHub->RequestFocusImmediately();
1900 }
1901 
LostFocus(const RefPtr<NG::FrameNode> & frameNode)1902 bool LostFocus(const RefPtr<NG::FrameNode>& frameNode)
1903 {
1904     CHECK_NULL_RETURN(frameNode, false);
1905     auto focusHub = frameNode->GetFocusHub();
1906     CHECK_NULL_RETURN(focusHub, false);
1907     focusHub->LostFocus();
1908     return true;
1909 }
1910 
ActClick(RefPtr<NG::FrameNode> & frameNode)1911 bool ActClick(RefPtr<NG::FrameNode>& frameNode)
1912 {
1913     auto gesture = frameNode->GetEventHub<NG::EventHub>()->GetGestureEventHub();
1914     CHECK_NULL_RETURN(gesture, false);
1915     bool result = gesture->ActClick();
1916     auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1917     CHECK_NULL_RETURN(accessibilityProperty, result);
1918     auto accessibilityAction = ACTIONS.find(ACCESSIBILITY_ACTION_CLICK);
1919     if (accessibilityAction == ACTIONS.end()) {
1920         return result;
1921     }
1922     AccessibilityActionParam param;
1923     param.accessibilityProperty = accessibilityProperty;
1924     result |= accessibilityAction->second(param);
1925     return result;
1926 }
1927 
ActLongClick(RefPtr<NG::FrameNode> & frameNode)1928 bool ActLongClick(RefPtr<NG::FrameNode>& frameNode)
1929 {
1930     auto gesture = frameNode->GetEventHub<NG::EventHub>()->GetGestureEventHub();
1931     CHECK_NULL_RETURN(gesture, false);
1932     return gesture->ActLongClick();
1933 }
1934 
ClearAccessibilityFocus(const RefPtr<NG::FrameNode> & root,int64_t focusNodeId)1935 void ClearAccessibilityFocus(const RefPtr<NG::FrameNode>& root, int64_t focusNodeId)
1936 {
1937     auto oldFocusNode = GetFramenodeByAccessibilityId(root, focusNodeId);
1938     CHECK_NULL_VOID(oldFocusNode);
1939     oldFocusNode->GetRenderContext()->UpdateAccessibilityFocus(false);
1940 }
1941 
ActAccessibilityFocus(int64_t elementId,RefPtr<NG::FrameNode> & frameNode,RefPtr<NG::PipelineContext> & context,int64_t & currentFocusNodeId,bool isNeedClear)1942 bool ActAccessibilityFocus(int64_t elementId, RefPtr<NG::FrameNode>& frameNode, RefPtr<NG::PipelineContext>& context,
1943     int64_t& currentFocusNodeId, bool isNeedClear)
1944 {
1945     CHECK_NULL_RETURN(frameNode, false);
1946     bool isAccessibilityVirtualNode = frameNode->IsAccessibilityVirtualNode();
1947     RefPtr<NG::RenderContext> renderContext = nullptr;
1948     if (isAccessibilityVirtualNode) {
1949         auto parentUinode = frameNode->GetVirtualNodeParent().Upgrade();
1950         CHECK_NULL_RETURN(parentUinode, false);
1951         auto parentFrame = AceType::DynamicCast<NG::FrameNode>(parentUinode);
1952         CHECK_NULL_RETURN(parentFrame, false);
1953         renderContext = parentFrame->GetRenderContext();
1954     } else {
1955         renderContext = frameNode->GetRenderContext();
1956     }
1957     CHECK_NULL_RETURN(renderContext, false);
1958     if (isNeedClear) {
1959         if (elementId != currentFocusNodeId) {
1960             return false;
1961         }
1962         renderContext->UpdateAccessibilityFocus(false);
1963         currentFocusNodeId = -1;
1964         auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1965         CHECK_NULL_RETURN(accessibilityProperty, true);
1966         accessibilityProperty->OnAccessibilityFocusCallback(false);
1967         accessibilityProperty->SetAccessibilityFocusState(false);
1968         return true;
1969     }
1970     if (elementId == currentFocusNodeId) {
1971         return false;
1972     }
1973     Framework::ClearAccessibilityFocus(context->GetRootElement(), currentFocusNodeId);
1974     if (isAccessibilityVirtualNode) {
1975         auto rect = frameNode->GetTransformRectRelativeToWindow();
1976         NG::RectT<int32_t> rectInt { static_cast<int32_t>(rect.Left()), static_cast<int32_t>(rect.Top()),
1977             static_cast<int32_t>(rect.Width()), static_cast<int32_t>(rect.Height()) };
1978         renderContext->UpdateAccessibilityFocusRect(rectInt);
1979         renderContext->UpdateAccessibilityFocus(true, frameNode->GetAccessibilityId());
1980     } else {
1981         renderContext->ResetAccessibilityFocusRect();
1982         renderContext->UpdateAccessibilityFocus(true);
1983     }
1984     currentFocusNodeId = frameNode->GetAccessibilityId();
1985     auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1986     CHECK_NULL_RETURN(accessibilityProperty, false);
1987     accessibilityProperty->OnAccessibilityFocusCallback(true);
1988     accessibilityProperty->SetAccessibilityFocusState(true);
1989     return true;
1990 }
1991 
GetSupportAction(const std::unordered_set<AceAction> & supportAceActions)1992 inline string GetSupportAction(const std::unordered_set<AceAction>& supportAceActions)
1993 {
1994     std::string actionForDump;
1995     for (const auto& action : supportAceActions) {
1996         if (!actionForDump.empty()) {
1997             actionForDump.append(",");
1998         }
1999         actionForDump.append(std::to_string(static_cast<int32_t>(action)));
2000     }
2001     return actionForDump;
2002 }
2003 
ConvertActionTypeToString(ActionType action)2004 static std::string ConvertActionTypeToString(ActionType action)
2005 {
2006     static const ActionStrTable actionStrTable[] = {
2007         { ActionType::ACCESSIBILITY_ACTION_FOCUS, "ACCESSIBILITY_ACTION_FOCUS" },
2008         { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ACCESSIBILITY_ACTION_CLEAR_FOCUS" },
2009         { ActionType::ACCESSIBILITY_ACTION_SELECT, "ACCESSIBILITY_ACTION_SELECT" },
2010         { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, "ACCESSIBILITY_ACTION_CLEAR_SELECTION" },
2011         { ActionType::ACCESSIBILITY_ACTION_CLICK, "ACCESSIBILITY_ACTION_CLICK" },
2012         { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, "ACCESSIBILITY_ACTION_LONG_CLICK" },
2013         { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, "ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS" },
2014         { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS,
2015             "ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS" },
2016         { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, "ACCESSIBILITY_ACTION_SCROLL_FORWARD" },
2017         { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, "ACCESSIBILITY_ACTION_SCROLL_BACKWARD" },
2018         { ActionType::ACCESSIBILITY_ACTION_COPY, "ACCESSIBILITY_ACTION_COPY" },
2019         { ActionType::ACCESSIBILITY_ACTION_PASTE, "ACCESSIBILITY_ACTION_PASTE" },
2020         { ActionType::ACCESSIBILITY_ACTION_CUT, "ACCESSIBILITY_ACTION_CUT" },
2021         { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, "ACCESSIBILITY_ACTION_SET_SELECTION" },
2022         { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, "ACCESSIBILITY_ACTION_SET_TEXT" },
2023         { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, "ACCESSIBILITY_ACTION_NEXT_TEXT" },
2024         { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, "ACCESSIBILITY_ACTION_PREVIOUS_TEXT" },
2025         { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, "ACCESSIBILITY_ACTION_SET_CURSOR_POSITION" },
2026         { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, "ACCESSIBILITY_ACTION_SPAN_CLICK" },
2027     };
2028     for (const auto& item : actionStrTable) {
2029         if (action == item.action) {
2030             return item.actionStr;
2031         }
2032     }
2033     return ACTION_DEFAULT_PARAM;
2034 }
2035 
ConvertAccessibilityAction(ActionType accessibilityAction)2036 static AceAction ConvertAccessibilityAction(ActionType accessibilityAction)
2037 {
2038     static const ActionTable actionTable[] = {
2039         { AceAction::ACTION_CLICK, ActionType::ACCESSIBILITY_ACTION_CLICK },
2040         { AceAction::ACTION_LONG_CLICK, ActionType::ACCESSIBILITY_ACTION_LONG_CLICK },
2041         { AceAction::ACTION_SCROLL_FORWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD },
2042         { AceAction::ACTION_SCROLL_BACKWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD },
2043         { AceAction::ACTION_FOCUS, ActionType::ACCESSIBILITY_ACTION_FOCUS },
2044         { AceAction::ACTION_CLEAR_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS },
2045         { AceAction::ACTION_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS },
2046         { AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS },
2047         { AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT },
2048         { AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT },
2049         { AceAction::ACTION_SET_TEXT, ActionType::ACCESSIBILITY_ACTION_SET_TEXT },
2050         { AceAction::ACTION_COPY, ActionType::ACCESSIBILITY_ACTION_COPY },
2051         { AceAction::ACTION_PASTE, ActionType::ACCESSIBILITY_ACTION_PASTE },
2052         { AceAction::ACTION_CUT, ActionType::ACCESSIBILITY_ACTION_CUT },
2053         { AceAction::ACTION_SELECT, ActionType::ACCESSIBILITY_ACTION_SELECT },
2054         { AceAction::ACTION_CLEAR_SELECTION, ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION },
2055         { AceAction::ACTION_SET_SELECTION, ActionType::ACCESSIBILITY_ACTION_SET_SELECTION },
2056         { AceAction::ACTION_SET_CURSOR_POSITION, ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION },
2057         { AceAction::ACTION_EXEC_SUB_COMPONENT, ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK },
2058     };
2059     for (const auto& item : actionTable) {
2060         if (accessibilityAction == item.action) {
2061             return item.aceAction;
2062         }
2063     }
2064     return AceAction::ACTION_NONE;
2065 }
2066 
DumpSupportActionNG(const AccessibilityElementInfo & nodeInfo)2067 static void DumpSupportActionNG(const AccessibilityElementInfo& nodeInfo)
2068 {
2069     DumpLog::GetInstance().AddDesc(
2070         "support action instructions: use command to make application components perform corresponding action");
2071     DumpLog::GetInstance().AddDesc(
2072         "use support action command: aa dump -i [AbilityRecord] -c -inspector [AccessibilityId] [AceAction]");
2073     std::string actionForDump;
2074     for (const auto& action : nodeInfo.GetActionList()) {
2075         if (!actionForDump.empty()) {
2076             actionForDump.append(",");
2077         }
2078         actionForDump.append(ConvertActionTypeToString(action.GetActionType()));
2079         actionForDump.append(": ");
2080         actionForDump.append(std::to_string(static_cast<int32_t>(ConvertAccessibilityAction(action.GetActionType()))));
2081     }
2082     DumpLog::GetInstance().AddDesc("support action: ", actionForDump);
2083 }
2084 
DumpContentListNG(const AccessibilityElementInfo & nodeInfo)2085 inline void DumpContentListNG(const AccessibilityElementInfo& nodeInfo)
2086 {
2087     std::vector<std::string> contentList;
2088     nodeInfo.GetContentList(contentList);
2089     std::string contents;
2090     for (auto content : contentList) {
2091         if (!contents.empty()) {
2092             contents.append(",");
2093         }
2094         contents.append(content);
2095     }
2096     DumpLog::GetInstance().AddDesc("content list: ", contents);
2097 }
2098 
DumpExtraElementInfoNG(const AccessibilityElementInfo & nodeInfo)2099 static void DumpExtraElementInfoNG(const AccessibilityElementInfo& nodeInfo)
2100 {
2101     ExtraElementInfo extraElementInfo = nodeInfo.GetExtraElement();
2102     if (!extraElementInfo.GetExtraElementInfoValueStr().empty()) {
2103         for (auto i = extraElementInfo.GetExtraElementInfoValueStr().begin();
2104              i != extraElementInfo.GetExtraElementInfoValueStr().end(); ++i) {
2105             DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second);
2106         }
2107     }
2108     if (!extraElementInfo.GetExtraElementInfoValueInt().empty()) {
2109         for (auto i = extraElementInfo.GetExtraElementInfoValueInt().begin();
2110              i != extraElementInfo.GetExtraElementInfoValueInt().end(); ++i) {
2111             DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second);
2112         }
2113     }
2114 }
2115 
UpdateSpanList(std::vector<SpanInfo> & spansInfosList,std::string & spans)2116 static void UpdateSpanList(std::vector<SpanInfo>& spansInfosList, std::string& spans)
2117 {
2118     for (const auto& span : spansInfosList) {
2119         if (!spans.empty()) {
2120             spans.append(",");
2121         }
2122         spans.append("\n\t span id: ");
2123         spans.append(std::to_string(span.GetSpanId()));
2124         spans.append(", span text: ");
2125         spans.append(span.GetSpanText());
2126         spans.append(", accessibility text: ");
2127         spans.append(span.GetAccessibilityText());
2128         spans.append(", accessibility description: ");
2129         spans.append(span.GetAccessibilityDescription());
2130         spans.append(", accessibility level: ");
2131         spans.append(span.GetAccessibilityLevel());
2132     }
2133 }
2134 
DumpSpanListNG(const AccessibilityElementInfo & nodeInfo)2135 inline void DumpSpanListNG(const AccessibilityElementInfo& nodeInfo)
2136 {
2137     std::string spans;
2138     std::vector<SpanInfo> spansInfosList = nodeInfo.GetSpanList();
2139     std::size_t spanCount = spansInfosList.size();
2140     UpdateSpanList(spansInfosList, spans);
2141     DumpLog::GetInstance().AddDesc("span list count: ", static_cast<int32_t>(spanCount));
2142     DumpLog::GetInstance().AddDesc("span list: ", spans);
2143 }
2144 
ChildrenToString(const std::vector<int64_t> & children,int32_t treeId)2145 inline std::string ChildrenToString(const std::vector<int64_t>& children, int32_t treeId)
2146 {
2147     std::string ids;
2148     for (auto child : children) {
2149         if (!ids.empty()) {
2150             ids.append(",");
2151         }
2152         int64_t childId = child;
2153         AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, childId);
2154         ids.append(std::to_string(childId));
2155     }
2156     return ids;
2157 }
2158 
DumpRectNG(const Accessibility::Rect & rect)2159 inline void DumpRectNG(const Accessibility::Rect& rect)
2160 {
2161     DumpLog::GetInstance().AddDesc(
2162         "width: ", std::to_string(rect.GetRightBottomXScreenPostion() - rect.GetLeftTopXScreenPostion()));
2163     DumpLog::GetInstance().AddDesc(
2164         "height: ", std::to_string(rect.GetRightBottomYScreenPostion() - rect.GetLeftTopYScreenPostion()));
2165     DumpLog::GetInstance().AddDesc("left: ", std::to_string(rect.GetLeftTopXScreenPostion()));
2166     DumpLog::GetInstance().AddDesc("top: ", std::to_string(rect.GetLeftTopYScreenPostion()));
2167     DumpLog::GetInstance().AddDesc("right: ", std::to_string(rect.GetRightBottomXScreenPostion()));
2168     DumpLog::GetInstance().AddDesc("bottom: ", std::to_string(rect.GetRightBottomYScreenPostion()));
2169 }
2170 
GenerateAccessibilityEventInfo(const AccessibilityEvent & accessibilityEvent,AccessibilityEventInfo & eventInfo)2171 void GenerateAccessibilityEventInfo(const AccessibilityEvent& accessibilityEvent, AccessibilityEventInfo& eventInfo)
2172 {
2173     Accessibility::EventType type = Accessibility::EventType::TYPE_VIEW_INVALID;
2174     if (accessibilityEvent.type != AccessibilityEventType::UNKNOWN) {
2175         type = ConvertAceEventType(accessibilityEvent.type);
2176     } else {
2177         type = ConvertStrToEventType(accessibilityEvent.eventType);
2178     }
2179 
2180     if (type == Accessibility::EventType::TYPE_VIEW_INVALID) {
2181         return;
2182     }
2183 
2184     eventInfo.SetTimeStamp(GetMicroTickCount());
2185     eventInfo.SetBeforeText(accessibilityEvent.beforeText);
2186     eventInfo.SetLatestContent(accessibilityEvent.latestContent);
2187     eventInfo.SetTextAnnouncedForAccessibility(accessibilityEvent.textAnnouncedForAccessibility);
2188     eventInfo.SetWindowChangeTypes(static_cast<Accessibility::WindowUpdateType>(accessibilityEvent.windowChangeTypes));
2189     eventInfo.SetWindowContentChangeTypes(
2190         static_cast<Accessibility::WindowsContentChangeTypes>(accessibilityEvent.windowContentChangeTypes));
2191     eventInfo.SetSource(accessibilityEvent.nodeId);
2192     eventInfo.SetEventType(type);
2193     eventInfo.SetCurrentIndex(static_cast<int>(accessibilityEvent.currentItemIndex));
2194     eventInfo.SetItemCounts(static_cast<int>(accessibilityEvent.itemCount));
2195     eventInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName());
2196 }
2197 } // namespace
2198 
DumpAccessibilityPropertyNG(const AccessibilityElementInfo & nodeInfo)2199 void JsAccessibilityManager::DumpAccessibilityPropertyNG(const AccessibilityElementInfo& nodeInfo)
2200 {
2201     DumpLog::GetInstance().AddDesc("checked: ", BoolToString(nodeInfo.IsChecked()));
2202     DumpLog::GetInstance().AddDesc("selected: ", BoolToString(nodeInfo.IsSelected()));
2203     DumpLog::GetInstance().AddDesc("checkable: ", BoolToString(nodeInfo.IsCheckable()));
2204     DumpLog::GetInstance().AddDesc("scrollable: ", BoolToString(nodeInfo.IsScrollable()));
2205     DumpLog::GetInstance().AddDesc("accessibility hint: ", BoolToString(nodeInfo.IsGivingHint()));
2206     DumpLog::GetInstance().AddDesc("hint text: ", nodeInfo.GetHint());
2207     DumpLog::GetInstance().AddDesc("error text: ", nodeInfo.GetError());
2208     DumpLog::GetInstance().AddDesc("max text length: ", nodeInfo.GetTextLengthLimit());
2209     DumpLog::GetInstance().AddDesc("scroll offset: ", nodeInfo.GetOffset());
2210     DumpLog::GetInstance().AddDesc("text selection start: ", nodeInfo.GetSelectedBegin());
2211     DumpLog::GetInstance().AddDesc("text selection end: ", nodeInfo.GetSelectedEnd());
2212     DumpLog::GetInstance().AddDesc("is multi line: ", BoolToString(nodeInfo.IsPluraLineSupported()));
2213     DumpLog::GetInstance().AddDesc("is password: ", BoolToString(nodeInfo.IsPassword()));
2214     DumpLog::GetInstance().AddDesc(
2215         "text input type: ", ConvertInputTypeToString(static_cast<AceTextCategory>(nodeInfo.GetInputType())));
2216 
2217     DumpLog::GetInstance().AddDesc("min value: ", nodeInfo.GetRange().GetMin());
2218     DumpLog::GetInstance().AddDesc("max value: ", nodeInfo.GetRange().GetMax());
2219     DumpLog::GetInstance().AddDesc("current value: ", nodeInfo.GetRange().GetCurrent());
2220     DumpLog::GetInstance().AddDesc("grid info rows: ", nodeInfo.GetGrid().GetRowCount());
2221     DumpLog::GetInstance().AddDesc("grid info columns: ", nodeInfo.GetGrid().GetColumnCount());
2222     DumpLog::GetInstance().AddDesc("grid info select mode: ", nodeInfo.GetGrid().GetSelectionMode());
2223     DumpLog::GetInstance().AddDesc("grid item info, row: ", nodeInfo.GetGridItem().GetRowIndex());
2224     DumpLog::GetInstance().AddDesc("grid item info, column: ", nodeInfo.GetGridItem().GetColumnIndex());
2225     DumpLog::GetInstance().AddDesc("grid item info, rowSpan: ", nodeInfo.GetGridItem().GetRowSpan());
2226     DumpLog::GetInstance().AddDesc("grid item info, columnSpan: ", nodeInfo.GetGridItem().GetColumnSpan());
2227     DumpLog::GetInstance().AddDesc("grid item info, is heading: ", nodeInfo.GetGridItem().IsHeading());
2228     DumpLog::GetInstance().AddDesc("grid item info, selected: ", nodeInfo.GetGridItem().IsSelected());
2229     DumpLog::GetInstance().AddDesc("current index: ", nodeInfo.GetCurrentIndex());
2230     DumpLog::GetInstance().AddDesc("begin index: ", nodeInfo.GetBeginIndex());
2231     DumpLog::GetInstance().AddDesc("end index: ", nodeInfo.GetEndIndex());
2232     DumpLog::GetInstance().AddDesc("collection item counts: ", nodeInfo.GetItemCounts());
2233     DumpLog::GetInstance().AddDesc("editable: ", BoolToString(nodeInfo.IsEditable()));
2234     DumpLog::GetInstance().AddDesc("is essential: ", BoolToString(nodeInfo.IsEssential()));
2235     DumpLog::GetInstance().AddDesc("deletable: ", nodeInfo.IsDeletable());
2236     DumpLog::GetInstance().AddDesc("live region: ", nodeInfo.GetLiveRegion());
2237     DumpLog::GetInstance().AddDesc("content description: ", nodeInfo.GetDescriptionInfo());
2238     DumpLog::GetInstance().AddDesc("content invalid: ", BoolToString(nodeInfo.GetContentInvalid()));
2239     DumpLog::GetInstance().AddDesc("accessibility label: ", nodeInfo.GetLabeledAccessibilityId());
2240     DumpLog::GetInstance().AddDesc("accessibilityVisible: ", nodeInfo.GetAccessibilityVisible());
2241     DumpExtraElementInfoNG(nodeInfo);
2242     DumpLog::GetInstance().AddDesc(
2243         "trigger action: ", static_cast<int32_t>(ConvertAccessibilityAction(nodeInfo.GetTriggerAction())));
2244     DumpLog::GetInstance().AddDesc("text move step: " + std::to_string(nodeInfo.GetTextMovementStep()));
2245     DumpSpanListNG(nodeInfo);
2246     DumpSupportActionNG(nodeInfo);
2247     DumpContentListNG(nodeInfo);
2248     DumpLog::GetInstance().AddDesc("latest content: ", nodeInfo.GetLatestContent());
2249 }
2250 
DumpCommonPropertyNG(const AccessibilityElementInfo & nodeInfo,int32_t treeId)2251 void JsAccessibilityManager::DumpCommonPropertyNG(const AccessibilityElementInfo& nodeInfo, int32_t treeId)
2252 {
2253     int64_t elementId = nodeInfo.GetAccessibilityId();
2254     AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId);
2255     DumpLog::GetInstance().AddDesc("ID: ", elementId);
2256     int64_t parentId = nodeInfo.GetParentNodeId();
2257     AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId);
2258     DumpLog::GetInstance().AddDesc("parent ID: ", parentId);
2259     DumpLog::GetInstance().AddDesc("child IDs: ", ChildrenToString(nodeInfo.GetChildIds(), treeId));
2260     DumpLog::GetInstance().AddDesc("component type: ", nodeInfo.GetComponentType());
2261     DumpLog::GetInstance().AddDesc("text: ", nodeInfo.GetContent());
2262     DumpLog::GetInstance().AddDesc("window id: " + std::to_string(nodeInfo.GetWindowId()));
2263     DumpRectNG(nodeInfo.GetRectInScreen());
2264 
2265     DumpLog::GetInstance().AddDesc("enabled: ", BoolToString(nodeInfo.IsEnabled()));
2266     DumpLog::GetInstance().AddDesc("focusable: ", BoolToString(nodeInfo.IsFocusable()));
2267     DumpLog::GetInstance().AddDesc("focused: ", BoolToString(nodeInfo.IsFocused()));
2268     DumpLog::GetInstance().AddDesc("visible: ", BoolToString(nodeInfo.IsVisible()));
2269     DumpLog::GetInstance().AddDesc("accessibility focused: ", BoolToString(nodeInfo.HasAccessibilityFocus()));
2270     DumpLog::GetInstance().AddDesc("accessibilityText: " + nodeInfo.GetAccessibilityText());
2271     DumpLog::GetInstance().AddDesc("accessibilityGroup: " + BoolToString(nodeInfo.GetAccessibilityGroup()));
2272     DumpLog::GetInstance().AddDesc("accessibilityLevel: " + nodeInfo.GetAccessibilityLevel());
2273     DumpLog::GetInstance().AddDesc("accessibilityDescription: " + nodeInfo.GetDescriptionInfo());
2274     DumpLog::GetInstance().AddDesc("hitTestBehavior: " + nodeInfo.GetHitTestBehavior());
2275 
2276     DumpLog::GetInstance().AddDesc("inspector key: ", nodeInfo.GetInspectorKey());
2277     DumpLog::GetInstance().AddDesc("bundle name: ", nodeInfo.GetBundleName());
2278     DumpLog::GetInstance().AddDesc("page id: " + std::to_string(nodeInfo.GetPageId()));
2279     DumpLog::GetInstance().AddDesc("page path: ", nodeInfo.GetPagePath());
2280     DumpLog::GetInstance().AddDesc("is valid element: ", BoolToString(nodeInfo.IsValidElement()));
2281     DumpLog::GetInstance().AddDesc("resource name: ", nodeInfo.GetComponentResourceId());
2282 
2283     DumpLog::GetInstance().AddDesc("clickable: ", BoolToString(nodeInfo.IsClickable()));
2284     DumpLog::GetInstance().AddDesc("long clickable: ", BoolToString(nodeInfo.IsLongClickable()));
2285     DumpLog::GetInstance().AddDesc("popup supported: ", BoolToString(nodeInfo.IsPopupSupported()));
2286     DumpLog::GetInstance().AddDesc("zindex: ", std::to_string(nodeInfo.GetZIndex()));
2287 }
2288 
UpdateVirtualNodeFocus()2289 void JsAccessibilityManager::UpdateVirtualNodeFocus()
2290 {
2291     auto frameNode = lastFrameNode_.Upgrade();
2292     CHECK_NULL_VOID(frameNode);
2293     if (!frameNode->IsAccessibilityVirtualNode()) {
2294         return;
2295     }
2296     RefPtr<NG::RenderContext> renderContext;
2297     auto geometryNode = frameNode->GetGeometryNode();
2298     CHECK_NULL_VOID(geometryNode);
2299     bool frameSizeChange = geometryNode->GetFrameSize() != oldGeometrySize_;
2300     if (frameNode->GetAccessibilityId() == currentFocusNodeId_ && frameSizeChange) {
2301         auto parentUinode = frameNode->GetVirtualNodeParent().Upgrade();
2302         CHECK_NULL_VOID(parentUinode);
2303         auto parentFrame = AceType::DynamicCast<NG::FrameNode>(parentUinode);
2304         CHECK_NULL_VOID(parentFrame);
2305         renderContext = parentFrame->GetRenderContext();
2306         CHECK_NULL_VOID(renderContext);
2307         renderContext->UpdateAccessibilityFocus(false);
2308         auto rect = frameNode->GetTransformRectRelativeToWindow();
2309         NG::RectT<int32_t> rectInt { static_cast<int32_t>(rect.Left()), static_cast<int32_t>(rect.Top()),
2310             static_cast<int32_t>(rect.Width()), static_cast<int32_t>(rect.Height()) };
2311         renderContext->UpdateAccessibilityFocusRect(rectInt);
2312         renderContext->UpdateAccessibilityFocus(true, frameNode->GetAccessibilityId());
2313         auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
2314         CHECK_NULL_VOID(accessibilityProperty);
2315         accessibilityProperty->SetAccessibilityFocusState(true);
2316     }
2317 }
2318 
~JsAccessibilityManager()2319 JsAccessibilityManager::~JsAccessibilityManager()
2320 {
2321     auto eventType = AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED;
2322 
2323     UnsubscribeStateObserver(eventType);
2324 
2325     DeregisterInteractionOperation();
2326 }
OnConfigChanged(const AccessibilityConfig::CONFIG_ID id,const AccessibilityConfig::ConfigValue & value)2327 void JsAccessibilityManager::ToastAccessibilityConfigObserver::OnConfigChanged(
2328     const AccessibilityConfig::CONFIG_ID id, const AccessibilityConfig::ConfigValue& value)
2329 {
2330     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "accessibility content timeout changed:%{public}u", value.contentTimeout);
2331     AceApplicationInfo::GetInstance().SetBarrierfreeDuration((int32_t)value.contentTimeout);
2332 }
2333 
SubscribeToastObserver()2334 bool JsAccessibilityManager::SubscribeToastObserver()
2335 {
2336     if (!toastObserver_) {
2337         toastObserver_ = std::make_shared<ToastAccessibilityConfigObserver>();
2338     }
2339     CHECK_NULL_RETURN(toastObserver_, false);
2340     auto& config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
2341     bool isSuccess = config.InitializeContext();
2342     if (!isSuccess) {
2343         return false;
2344     }
2345     config.SubscribeConfigObserver(CONFIG_CONTENT_TIMEOUT, toastObserver_);
2346     return true;
2347 }
2348 
UnsubscribeToastObserver()2349 bool JsAccessibilityManager::UnsubscribeToastObserver()
2350 {
2351     CHECK_NULL_RETURN(toastObserver_, false);
2352     auto& config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
2353     bool isSuccess = config.InitializeContext();
2354     if (!isSuccess) {
2355         return false;
2356     }
2357     config.UnsubscribeConfigObserver(CONFIG_CONTENT_TIMEOUT, toastObserver_);
2358     return true;
2359 }
2360 
SubscribeStateObserver(int eventType)2361 bool JsAccessibilityManager::SubscribeStateObserver(int eventType)
2362 {
2363     if (!stateObserver_) {
2364         stateObserver_ = std::make_shared<JsAccessibilityStateObserver>();
2365     }
2366 
2367     stateObserver_->SetAccessibilityManager(WeakClaim(this));
2368     stateObserver_->SetPipeline(context_);
2369 
2370     auto instance = AccessibilitySystemAbilityClient::GetInstance();
2371     CHECK_NULL_RETURN(instance, false);
2372     Accessibility::RetError ret = instance->SubscribeStateObserver(stateObserver_, eventType);
2373     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, " the result of SubscribeStateObserver:%{public}d", ret);
2374     return ret == RET_OK;
2375 }
2376 
UnsubscribeStateObserver(int eventType)2377 bool JsAccessibilityManager::UnsubscribeStateObserver(int eventType)
2378 {
2379     CHECK_NULL_RETURN(stateObserver_, false);
2380     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
2381     CHECK_NULL_RETURN(instance, false);
2382     Accessibility::RetError ret = instance->UnsubscribeStateObserver(stateObserver_, eventType);
2383     return ret == RET_OK;
2384 }
2385 
InitializeCallback()2386 void JsAccessibilityManager::InitializeCallback()
2387 {
2388     if (IsRegister()) {
2389         return;
2390     }
2391 
2392     auto pipelineContext = GetPipelineContext().Upgrade();
2393     CHECK_NULL_VOID(pipelineContext);
2394     windowId_ = pipelineContext->GetWindowId();
2395 
2396     auto client = AccessibilitySystemAbilityClient::GetInstance();
2397     CHECK_NULL_VOID(client);
2398     bool isEnabled = false;
2399     client->IsEnabled(isEnabled);
2400     AceApplicationInfo::GetInstance().SetAccessibilityEnabled(isEnabled);
2401 
2402     if (pipelineContext->IsFormRender() || pipelineContext->IsJsCard() || pipelineContext->IsJsPlugin()) {
2403         return;
2404     }
2405 
2406     auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
2407     if (container != nullptr && container->IsUIExtensionWindow()) {
2408         return;
2409     }
2410 
2411     SubscribeStateObserver(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED);
2412     if (isEnabled) {
2413         RegisterInteractionOperation(windowId_);
2414     }
2415 }
2416 
SendAccessibilitySyncEvent(const AccessibilityEvent & accessibilityEvent,AccessibilityEventInfo eventInfo)2417 bool JsAccessibilityManager::SendAccessibilitySyncEvent(
2418     const AccessibilityEvent& accessibilityEvent, AccessibilityEventInfo eventInfo)
2419 {
2420     if (!IsRegister()) {
2421         return false;
2422     }
2423     auto client = AccessibilitySystemAbilityClient::GetInstance();
2424     CHECK_NULL_RETURN(client, false);
2425     bool isEnabled = false;
2426     client->IsEnabled(isEnabled);
2427     if (!isEnabled) {
2428         return false;
2429     }
2430     AccessibilityElementInfo info = eventInfo.GetElementInfo();
2431     int64_t elementId = eventInfo.GetAccessibilityId();
2432     if (info.GetBelongTreeId() > 0) {
2433         AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(info.GetBelongTreeId(), elementId);
2434     }
2435     eventInfo.SetSource(elementId);
2436     UpdateElementInfoTreeId(info);
2437     eventInfo.SetElementInfo(info);
2438     eventInfo.SetPageId(info.GetPageId());
2439     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
2440         "send accessibility componentType:%{public}s event:%{public}d accessibilityId:%{public}" PRId64,
2441         eventInfo.GetComponentType().c_str(), eventInfo.GetEventType(), eventInfo.GetAccessibilityId());
2442     return client->SendEvent(eventInfo);
2443 }
2444 
TransferAccessibilityAsyncEvent(const AccessibilityEventInfo & eventInfo,int64_t uiExtensionOffset)2445 bool JsAccessibilityManager::TransferAccessibilityAsyncEvent(
2446     const AccessibilityEventInfo& eventInfo, int64_t uiExtensionOffset)
2447 {
2448 #ifdef WINDOW_SCENE_SUPPORTED
2449     auto client = AccessibilitySystemAbilityClient::GetInstance();
2450     CHECK_NULL_RETURN(client, false);
2451     bool isEnabled = false;
2452     client->IsEnabled(isEnabled);
2453     if (!isEnabled) {
2454         return false;
2455     }
2456 
2457     auto pipeline = context_.Upgrade();
2458     CHECK_NULL_RETURN(pipeline, false);
2459     RefPtr<NG::PipelineContext> ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
2460     CHECK_NULL_RETURN(ngPipeline, false);
2461     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
2462     CHECK_NULL_RETURN(uiExtensionManager, false);
2463     auto container = Container::GetContainer(ngPipeline->GetInstanceId());
2464     bool isDynamicRender = container && container->IsDynamicRender();
2465     if (!IsRegister() && !isDynamicRender) {
2466         return false;
2467     }
2468     AccessibilityEventInfo eventInfoNew = eventInfo;
2469     if (isDynamicRender) {
2470         auto focusedContainer = Container::GetFoucsed();
2471         if (focusedContainer) {
2472             eventInfoNew.SetWindowId(focusedContainer->GetWindowId());
2473         }
2474     }
2475     eventInfoNew.SetSource(uiExtensionOffset * GetUiextensionId() + eventInfo.GetViewId());
2476     AccessibilityElementInfo elementInfo;
2477     FillElementInfo(eventInfoNew.GetAccessibilityId(), elementInfo, pipeline, Claim(this),
2478         FillEventInfoParam { eventInfoNew.GetAccessibilityId(), -1, eventInfoNew.GetWindowId() });
2479     eventInfoNew.SetElementInfo(elementInfo);
2480     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "send accessibility event:%{public}d accessibilityId:%{public}" PRId64,
2481         eventInfoNew.GetEventType(), eventInfoNew.GetAccessibilityId());
2482     return client->SendEvent(eventInfoNew);
2483 #endif
2484     return false;
2485 }
2486 
SendExtensionAccessibilityEvent(const AccessibilityEventInfo & eventInfo,int64_t uiExtensionOffset)2487 void JsAccessibilityManager::SendExtensionAccessibilityEvent(
2488     const AccessibilityEventInfo& eventInfo, int64_t uiExtensionOffset)
2489 {
2490     TransferAccessibilityAsyncEvent(eventInfo, uiExtensionOffset);
2491 }
2492 
FillEventInfoWithNode(const RefPtr<NG::FrameNode> & node,AccessibilityEventInfo & eventInfo,const RefPtr<NG::PipelineContext> & context,int64_t elementId)2493 void JsAccessibilityManager::FillEventInfoWithNode(
2494     const RefPtr<NG::FrameNode>& node,
2495     AccessibilityEventInfo& eventInfo,
2496     const RefPtr<NG::PipelineContext>& context,
2497     int64_t elementId)
2498 {
2499     CHECK_NULL_VOID(node);
2500     eventInfo.SetComponentType(node->GetTag());
2501     eventInfo.SetPageId(node->GetPageId());
2502     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
2503     CHECK_NULL_VOID(accessibilityProperty);
2504     eventInfo.AddContent(accessibilityProperty->GetGroupText());
2505     eventInfo.SetItemCounts(accessibilityProperty->GetCollectionItemCounts());
2506     eventInfo.SetBeginIndex(accessibilityProperty->GetBeginIndex());
2507     eventInfo.SetEndIndex(accessibilityProperty->GetEndIndex());
2508     AccessibilityElementInfo elementInfo;
2509 
2510     CommonProperty commonProperty;
2511     auto mainContext = context_.Upgrade();
2512     CHECK_NULL_VOID(mainContext);
2513     GenerateCommonProperty(context, commonProperty, mainContext);
2514     UpdateAccessibilityElementInfo(node, commonProperty, elementInfo, context);
2515     elementInfo.SetWindowId(eventInfo.GetWindowId());
2516     eventInfo.SetElementInfo(elementInfo);
2517 }
2518 
GetDelayTimeBeforeSendEvent(const AccessibilityEvent & accessibilityEvent,const RefPtr<AceType> & node)2519 int64_t JsAccessibilityManager::GetDelayTimeBeforeSendEvent(
2520     const AccessibilityEvent& accessibilityEvent,
2521     const RefPtr<AceType>& node)
2522 {
2523     if (accessibilityEvent.type != AccessibilityEventType::CLICK) {
2524         return 0;
2525     }
2526 
2527     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
2528     if (frameNode) {
2529         if (IsUserCheckedOrSelected(frameNode)) {
2530             return DELAY_SEND_EVENT_MILLISECOND;
2531         }
2532     } else {
2533         auto context = GetPipelineContext().Upgrade();
2534         if (!AceType::InstanceOf<NG::PipelineContext>(context)) {
2535             return 0;
2536         }
2537         RefPtr<NG::FrameNode> findeNode;
2538         auto ngPipeline = FindPipelineByElementId(accessibilityEvent.nodeId, findeNode);
2539         if ((findeNode) && IsUserCheckedOrSelected(findeNode)) {
2540             return DELAY_SEND_EVENT_MILLISECOND;
2541         }
2542     }
2543 
2544     return 0;
2545 }
2546 
SendEventToAccessibilityWithNode(const AccessibilityEvent & accessibilityEvent,const RefPtr<AceType> & node,const RefPtr<PipelineBase> & context)2547 void JsAccessibilityManager::SendEventToAccessibilityWithNode(
2548     const AccessibilityEvent& accessibilityEvent, const RefPtr<AceType>& node, const RefPtr<PipelineBase>& context)
2549 {
2550     auto delayTime = GetDelayTimeBeforeSendEvent(accessibilityEvent, node);
2551     if ((delayTime > 0) && context) {
2552         context->GetTaskExecutor()->PostDelayedTask(
2553             [weak = WeakClaim(this), accessibilityEvent, node, context] {
2554                 auto jsAccessibilityManager = weak.Upgrade();
2555                 CHECK_NULL_VOID(jsAccessibilityManager);
2556                 jsAccessibilityManager->SendEventToAccessibilityWithNodeInner(accessibilityEvent, node, context);
2557             },
2558             TaskExecutor::TaskType::UI, delayTime, "ArkUIAccessibilitySendSyncEventWithDelay");
2559         return;
2560     }
2561     SendEventToAccessibilityWithNodeInner(accessibilityEvent, node, context);
2562 }
2563 
SendEventToAccessibilityWithNodeInner(const AccessibilityEvent & accessibilityEvent,const RefPtr<AceType> & node,const RefPtr<PipelineBase> & context)2564 void JsAccessibilityManager::SendEventToAccessibilityWithNodeInner(
2565     const AccessibilityEvent& accessibilityEvent, const RefPtr<AceType>& node, const RefPtr<PipelineBase>& context)
2566 {
2567     ACE_ACCESS_SCOPED_TRACE("SendAccessibilityAsyncEvent");
2568     CHECK_NULL_VOID(node);
2569     CHECK_NULL_VOID(context);
2570     int32_t windowId = static_cast<int32_t>(context->GetRealHostWindowId());
2571     if (windowId == 0) {
2572         return;
2573     }
2574     if (!AceType::InstanceOf<NG::FrameNode>(node)) {
2575         return;
2576     }
2577     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
2578     CHECK_NULL_VOID(frameNode);
2579     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
2580     CHECK_NULL_VOID(ngPipeline);
2581 
2582     if ((!frameNode->IsActive()) || frameNode->CheckAccessibilityLevelNo()) {
2583         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "node: %{public}" PRId64 ", is not active or level is no",
2584             frameNode->GetAccessibilityId());
2585         return;
2586     }
2587 
2588     AccessibilityEventInfo eventInfo;
2589 
2590     if (accessibilityEvent.type != AccessibilityEventType::PAGE_CHANGE || accessibilityEvent.windowId == 0) {
2591         eventInfo.SetWindowId(windowId);
2592     } else {
2593         eventInfo.SetWindowId(accessibilityEvent.windowId);
2594     }
2595     FillEventInfoWithNode(frameNode, eventInfo, ngPipeline, accessibilityEvent.nodeId);
2596     if ((ngPipeline != nullptr) && (ngPipeline->IsFormRender())) {
2597         eventInfo.SetWindowId(static_cast<int32_t>(GetWindowId()));
2598     }
2599     GenerateAccessibilityEventInfo(accessibilityEvent, eventInfo);
2600 
2601     auto container = Container::GetContainer(context->GetInstanceId());
2602     if (container && container->IsDynamicRender()) {
2603         SendExtensionAccessibilityEvent(eventInfo, NG::UI_EXTENSION_UNKNOW_ID);
2604     } else {
2605         context->GetTaskExecutor()->PostTask(
2606             [weak = WeakClaim(this), accessibilityEvent, eventInfo] {
2607                 auto jsAccessibilityManager = weak.Upgrade();
2608                 CHECK_NULL_VOID(jsAccessibilityManager);
2609                 jsAccessibilityManager->SendAccessibilitySyncEvent(accessibilityEvent, eventInfo);
2610             },
2611             TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySendSyncEvent");
2612     }
2613 }
2614 
GetRealEventWindowId(const AccessibilityEvent & accessibilityEvent,const RefPtr<NG::PipelineContext> & ngPipeline,uint32_t & windowId)2615 void GetRealEventWindowId(
2616     const AccessibilityEvent& accessibilityEvent, const RefPtr<NG::PipelineContext>& ngPipeline, uint32_t& windowId)
2617 {
2618     if ((accessibilityEvent.type == AccessibilityEventType::PAGE_CHANGE && accessibilityEvent.windowId != 0) ||
2619         accessibilityEvent.windowChangeTypes == WINDOW_UPDATE_ADDED) {
2620         windowId = accessibilityEvent.windowId;
2621         return;
2622     }
2623     if ((ngPipeline != nullptr) && (ngPipeline->IsFormRender())) {
2624         return;
2625     }
2626     windowId = ngPipeline->GetRealHostWindowId();
2627 }
2628 
SendAccessibilityAsyncEvent(const AccessibilityEvent & accessibilityEvent)2629 void JsAccessibilityManager::SendAccessibilityAsyncEvent(const AccessibilityEvent& accessibilityEvent)
2630 {
2631     auto delayTime = GetDelayTimeBeforeSendEvent(accessibilityEvent, nullptr);
2632     if (delayTime > 0) {
2633         auto context = GetPipelineContext().Upgrade();
2634         if (context) {
2635             context->GetTaskExecutor()->PostDelayedTask(
2636                 [weak = WeakClaim(this), accessibilityEvent] {
2637                     auto jsAccessibilityManager = weak.Upgrade();
2638                     CHECK_NULL_VOID(jsAccessibilityManager);
2639                     jsAccessibilityManager->SendAccessibilityAsyncEventInner(accessibilityEvent);
2640                 },
2641                 TaskExecutor::TaskType::UI, delayTime, "ArkUIAccessibilitySendSyncEventWithDelay");
2642         }
2643         return;
2644     }
2645     SendAccessibilityAsyncEventInner(accessibilityEvent);
2646 }
2647 
SendAccessibilityAsyncEventInner(const AccessibilityEvent & accessibilityEvent)2648 void JsAccessibilityManager::SendAccessibilityAsyncEventInner(const AccessibilityEvent& accessibilityEvent)
2649 {
2650     ACE_ACCESS_SCOPED_TRACE("SendAccessibilityAsyncEvent");
2651     auto context = GetPipelineContext().Upgrade();
2652     CHECK_NULL_VOID(context);
2653     int32_t windowId = static_cast<int32_t>(context->GetRealHostWindowId());
2654     if (windowId == 0) {
2655         return;
2656     }
2657     RefPtr<NG::PipelineContext> ngPipeline;
2658     AccessibilityEventInfo eventInfo;
2659     uint32_t realWindowId = GetWindowId();
2660     if (AceType::InstanceOf<NG::PipelineContext>(context)) {
2661         RefPtr<NG::FrameNode> node;
2662         ngPipeline = FindPipelineByElementId(accessibilityEvent.nodeId, node);
2663         CHECK_NULL_VOID(ngPipeline);
2664         CHECK_NULL_VOID(node);
2665         GetRealEventWindowId(accessibilityEvent, ngPipeline, realWindowId);
2666         FillEventInfo(node, eventInfo, ngPipeline, Claim(this),
2667             FillEventInfoParam {
2668                 accessibilityEvent.nodeId, accessibilityEvent.stackNodeId, realWindowId });
2669         eventInfo.SetWindowId(realWindowId);
2670     } else {
2671         ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
2672         auto node = GetAccessibilityNodeFromPage(accessibilityEvent.nodeId);
2673         CHECK_NULL_VOID(node);
2674         FillEventInfo(node, eventInfo);
2675         eventInfo.SetWindowId(windowId);
2676     }
2677     if (accessibilityEvent.type == AccessibilityEventType::PAGE_CHANGE && accessibilityEvent.windowId != 0) {
2678         eventInfo.SetWindowId(accessibilityEvent.windowId);
2679     }
2680     if (ngPipeline != nullptr) {
2681         if (ngPipeline->IsFormRender()) {
2682             eventInfo.SetWindowId(static_cast<int32_t>(GetWindowId()));
2683         }
2684     }
2685     GenerateAccessibilityEventInfo(accessibilityEvent, eventInfo);
2686 
2687     auto container = Container::GetContainer(context->GetInstanceId());
2688     if (container && container->IsDynamicRender()) {
2689         SendExtensionAccessibilityEvent(eventInfo, NG::UI_EXTENSION_OFFSET_MAX);
2690     } else {
2691         context->GetTaskExecutor()->PostTask(
2692             [weak = WeakClaim(this), accessibilityEvent, eventInfo] {
2693                 auto jsAccessibilityManager = weak.Upgrade();
2694                 CHECK_NULL_VOID(jsAccessibilityManager);
2695                 jsAccessibilityManager->SendAccessibilitySyncEvent(accessibilityEvent, eventInfo);
2696             },
2697             TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySendSyncEvent");
2698     }
2699 }
2700 
2701 #ifdef WEB_SUPPORTED
2702 
SendWebAccessibilityAsyncEvent(const AccessibilityEvent & accessibilityEvent,const RefPtr<NG::WebPattern> & webPattern)2703 void JsAccessibilityManager::SendWebAccessibilityAsyncEvent(
2704     const AccessibilityEvent& accessibilityEvent, const RefPtr<NG::WebPattern>& webPattern)
2705 {
2706     ACE_ACCESS_SCOPED_TRACE("SendWebAccessibilityAsyncEvent");
2707     auto context = GetPipelineContext().Upgrade();
2708     CHECK_NULL_VOID(context);
2709     int32_t windowId = static_cast<int32_t>(context->GetRealHostWindowId());
2710     if (windowId == 0) {
2711         return;
2712     }
2713 
2714     AccessibilityEventInfo eventInfo;
2715     RefPtr<NG::PipelineContext> ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
2716     CHECK_NULL_VOID(ngPipeline);
2717     FillWebEventInfo(eventInfo, ngPipeline, Claim(this),
2718         FillEventInfoParam {
2719                 accessibilityEvent.nodeId, accessibilityEvent.stackNodeId, ngPipeline->GetRealHostWindowId() },
2720         webPattern);
2721     eventInfo.SetWindowId(ngPipeline->GetRealHostWindowId());
2722 
2723     if (accessibilityEvent.type == AccessibilityEventType::PAGE_CHANGE && accessibilityEvent.windowId != 0) {
2724         eventInfo.SetWindowId(accessibilityEvent.windowId);
2725     }
2726 
2727     GenerateAccessibilityEventInfo(accessibilityEvent, eventInfo);
2728 
2729     context->GetTaskExecutor()->PostTask(
2730         [weak = WeakClaim(this), accessibilityEvent, eventInfo] {
2731             auto jsAccessibilityManager = weak.Upgrade();
2732             CHECK_NULL_VOID(jsAccessibilityManager);
2733             jsAccessibilityManager->SendAccessibilitySyncEvent(accessibilityEvent, eventInfo);
2734         },
2735         TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySendSyncEvent");
2736 }
2737 #endif
2738 
UpdateNodeChildIds(const RefPtr<AccessibilityNode> & node)2739 void JsAccessibilityManager::UpdateNodeChildIds(const RefPtr<AccessibilityNode>& node)
2740 {
2741     CHECK_NULL_VOID(node);
2742     node->ActionUpdateIds();
2743     const auto& children = node->GetChildList();
2744     std::vector<int32_t> childrenVec;
2745     auto cardId = GetCardId();
2746     auto rootNodeId = GetRootNodeId();
2747 
2748     // get last stack children to barrier free service.
2749     if ((node->GetNodeId() == GetRootNodeId() + ROOT_STACK_BASE) && !children.empty() && !IsDeclarative()) {
2750         auto lastChildNodeId = children.back()->GetNodeId();
2751         if (isOhosHostCard()) {
2752             childrenVec.emplace_back(ConvertToCardAccessibilityId(lastChildNodeId, cardId, rootNodeId));
2753         } else {
2754             childrenVec.emplace_back(lastChildNodeId);
2755             for (const auto& child : children) {
2756                 if (child->GetNodeId() == ROOT_DECOR_BASE - 1) {
2757                     childrenVec.emplace_back(child->GetNodeId());
2758                     break;
2759                 }
2760             }
2761         }
2762     } else {
2763         childrenVec.resize(children.size());
2764         if (isOhosHostCard()) {
2765             std::transform(children.begin(), children.end(), childrenVec.begin(),
2766                 [cardId, rootNodeId](const RefPtr<AccessibilityNode>& child) {
2767                     return ConvertToCardAccessibilityId(child->GetNodeId(), cardId, rootNodeId);
2768                 });
2769         } else {
2770             std::transform(children.begin(), children.end(), childrenVec.begin(),
2771                 [](const RefPtr<AccessibilityNode>& child) { return child->GetNodeId(); });
2772         }
2773     }
2774     node->SetChildIds(childrenVec);
2775 }
2776 
ProcessParameters(ActionType op,const std::vector<std::string> & params,std::map<std::string,std::string> & paramsMap)2777 void JsAccessibilityManager::ProcessParameters(
2778     ActionType op, const std::vector<std::string>& params, std::map<std::string, std::string>& paramsMap)
2779 {
2780     if (op == ActionType::ACCESSIBILITY_ACTION_SET_TEXT) {
2781         if (params.size() == EVENT_DUMP_PARAM_LENGTH_UPPER) {
2782             paramsMap = { { ACTION_ARGU_SET_TEXT, params[EVENT_DUMP_ACTION_PARAM_INDEX] } };
2783         }
2784     }
2785 
2786     if (op == ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) {
2787         paramsMap[ACTION_ARGU_SELECT_TEXT_START] = "-1";
2788         paramsMap[ACTION_ARGU_SELECT_TEXT_END] = "-1";
2789         paramsMap[ACTION_ARGU_SELECT_TEXT_INFORWARD] = STRING_DIR_BACKWARD;
2790         if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER) {
2791             paramsMap[ACTION_ARGU_SELECT_TEXT_START] = params[EVENT_DUMP_ACTION_PARAM_INDEX];
2792         }
2793         if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER + 1) {
2794             paramsMap[ACTION_ARGU_SELECT_TEXT_END] = params[EVENT_DUMP_ACTION_PARAM_INDEX + 1];
2795         }
2796         // 2 means params number Offset
2797         if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER + 2) {
2798             // 2 means params number Offset
2799             paramsMap[ACTION_ARGU_SELECT_TEXT_INFORWARD] = params[EVENT_DUMP_ACTION_PARAM_INDEX + 2];
2800         }
2801     }
2802 
2803     if (op == ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT || op == ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT) {
2804         if (params.size() == EVENT_DUMP_PARAM_LENGTH_UPPER) {
2805             paramsMap[ACTION_ARGU_MOVE_UNIT] = std::to_string(TextMoveUnit::STEP_CHARACTER);
2806         }
2807         paramsMap[ACTION_ARGU_MOVE_UNIT] = std::to_string(TextMoveUnit::STEP_CHARACTER);
2808     }
2809 
2810     if (op == ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION) {
2811         paramsMap[ACTION_ARGU_SET_OFFSET] = params[EVENT_DUMP_ACTION_PARAM_INDEX];
2812     }
2813 
2814     if ((op == ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD) ||
2815         (op == ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD)) {
2816         if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER) {
2817             paramsMap = { { ACTION_ARGU_SCROLL_STUB, params[EVENT_DUMP_ACTION_PARAM_INDEX] } };
2818         }
2819     }
2820 
2821     if (op == ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK) {
2822         if (params.size() > EVENT_DUMP_PARAM_LENGTH_LOWER) {
2823             paramsMap = { { ACTION_ARGU_SPAN_ID, params[EVENT_DUMP_ACTION_PARAM_INDEX] } };
2824         }
2825     }
2826 }
2827 
TransferExecuteAction(int64_t elementId,const RefPtr<NG::FrameNode> & node,const std::map<std::string,std::string> & actionArguments,ActionType action,int64_t uiExtensionOffset)2828 bool TransferExecuteAction(int64_t elementId, const RefPtr<NG::FrameNode>& node,
2829     const std::map<std::string, std::string>& actionArguments,
2830     ActionType action, int64_t uiExtensionOffset)
2831 {
2832     bool isExecuted = false;
2833     if ((uiExtensionOffset + 1) > NG::UI_EXTENSION_OFFSET_MIN) {
2834         isExecuted = node->TransferExecuteAction(
2835             elementId, actionArguments, static_cast<int>(action),
2836             uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
2837     }
2838     return isExecuted;
2839 }
2840 
GetPipelineByWindowId(uint32_t windowId)2841 RefPtr<NG::PipelineContext> JsAccessibilityManager::GetPipelineByWindowId(uint32_t windowId)
2842 {
2843     auto mainPipeline = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
2844     if (mainPipeline!= nullptr && mainPipeline->GetWindowId() == windowId) {
2845         return mainPipeline;
2846     }
2847     for (auto subPipelineWeak : GetSubPipelineContexts()) {
2848         auto subContextNG = AceType::DynamicCast<NG::PipelineContext>(subPipelineWeak.Upgrade());
2849         if (subContextNG!= nullptr && subContextNG->GetWindowId() == windowId) {
2850             return subContextNG;
2851         }
2852     }
2853     if (GetWindowId() == windowId) {
2854         return mainPipeline;
2855     }
2856     return nullptr;
2857 }
2858 
DumpTreeNG(bool useWindowId,uint32_t windowId,int64_t rootId,bool isDumpSimplify)2859 void JsAccessibilityManager::DumpTreeNG(bool useWindowId, uint32_t windowId, int64_t rootId, bool isDumpSimplify)
2860 {
2861     if (!useWindowId && rootId == -1) {
2862         // used to adapt old function
2863         DumpTree(0, 0);
2864         return;
2865     }
2866 
2867     auto pipeline = GetPipelineByWindowId(windowId);
2868     if (pipeline == nullptr) {
2869         DumpLog::GetInstance().Print("Error: pipeline is not found!");
2870         return;
2871     }
2872     auto rootNode = pipeline->GetRootElement();
2873     CHECK_NULL_VOID(rootNode);
2874     CommonProperty commonProperty;
2875     auto mainPipeline = context_.Upgrade();
2876     CHECK_NULL_VOID(mainPipeline);
2877     GenerateCommonProperty(pipeline, commonProperty, mainPipeline);
2878     auto nodeId = rootId == -1 ? rootNode->GetAccessibilityId() : rootId;
2879     DumpTreeNG(rootNode, 0, nodeId, commonProperty, isDumpSimplify);
2880 }
2881 
DumpHoverTestNG(uint32_t windowId,int64_t rootId,int32_t x,int32_t y,bool verbose)2882 void JsAccessibilityManager::DumpHoverTestNG(uint32_t windowId, int64_t rootId, int32_t x, int32_t y, bool verbose)
2883 {
2884     auto pipeline = GetPipelineByWindowId(windowId);
2885     CHECK_NULL_VOID(pipeline);
2886     auto accessibilityManagerNG = pipeline->GetAccessibilityManagerNG();
2887     CHECK_NULL_VOID(accessibilityManagerNG);
2888     auto pipelineRoot = pipeline->GetRootElement();
2889     RefPtr<NG::FrameNode> root = nullptr;
2890     if (rootId == -1) {
2891         root = pipelineRoot;
2892     } else {
2893         root = GetFramenodeByAccessibilityId(pipelineRoot, rootId);
2894     }
2895     CHECK_NULL_VOID(root);
2896 
2897     DumpLog::GetInstance().Print("Window ID: " + std::to_string(windowId));
2898     DumpLog::GetInstance().Print("Root ID: " + std::to_string(root->GetAccessibilityId()));
2899     NG::PointF hoverPoint(x, y);
2900     DumpLog::GetInstance().Print("Hover Point: " + hoverPoint.ToString());
2901 
2902     std::string summary;
2903     std::string detail;
2904     accessibilityManagerNG->HoverTestDebug(root, hoverPoint, summary, detail);
2905     DumpLog::GetInstance().Print(summary);
2906     if (verbose) {
2907         DumpLog::GetInstance().Print(detail);
2908     }
2909 }
2910 
CheckDumpInfoParams(const std::vector<std::string> & params)2911 bool JsAccessibilityManager::CheckDumpInfoParams(const std::vector<std::string> &params)
2912 {
2913     if (params.size() < 1) {
2914         return false;
2915     }
2916     const std::string firstParam = params[0];
2917     if (firstParam.compare("-inspector") != 0 && firstParam.compare("-accessibility") != 0 &&
2918         firstParam.compare("-simplify") != 0) {
2919         return false;
2920     }
2921     return true;
2922 }
2923 
OnDumpInfoNG(const std::vector<std::string> & params,uint32_t windowId)2924 void JsAccessibilityManager::OnDumpInfoNG(const std::vector<std::string>& params, uint32_t windowId)
2925 {
2926     if (!CheckDumpInfoParams(params)) {
2927         DumpLog::GetInstance().Print("Error: invalid arguments!");
2928         return;
2929     }
2930     enum class DumpMode {
2931         TREE,
2932         NODE,
2933         HANDLE_EVENT,
2934         HOVER_TEST
2935     };
2936     bool useWindowId = false;
2937     DumpMode mode = DumpMode::TREE;
2938     bool isDumpSimplify = params[0].compare("-simplify") == 0;
2939     bool verbose = false;
2940     int64_t rootId = -1;
2941     int32_t pointX = 0;
2942     int32_t pointY = 0;
2943     int64_t nodeId = -1;
2944     int32_t action = 0;
2945     for (auto arg = params.begin() + 1; arg != params.end(); ++arg) {
2946         if (*arg == "-w") {
2947             useWindowId = true;
2948         } else if (*arg == "--root") {
2949             ++arg;
2950             if (arg == params.end()) {
2951                 DumpLog::GetInstance().Print(std::string("Error: --root is used to set the root node, ") +
2952                     "e.g. '--root ${AccessibilityId}'!");
2953                 return;
2954             }
2955             rootId = StringUtils::StringToLongInt(*arg);
2956         } else if (*arg == "--hover-test") {
2957             mode = DumpMode::HOVER_TEST;
2958             static constexpr int32_t NUM_POINT_DIMENSION = 2;
2959             if (std::distance(arg, params.end()) <= NUM_POINT_DIMENSION) {
2960                 DumpLog::GetInstance().Print(std::string("Error: --hover-test is used to get nodes at a point ") +
2961                     "relative to the root node, e.g. '--hover-test ${x} ${y}'!");
2962                 return;
2963             }
2964             ++arg;
2965             pointX = StringUtils::StringToInt(*arg);
2966             ++arg;
2967             pointY = StringUtils::StringToInt(*arg);
2968         } else if (*arg == "-v") {
2969             verbose = true;
2970         } else {
2971             if (mode == DumpMode::NODE) {
2972                 mode = DumpMode::HANDLE_EVENT;
2973                 action = StringUtils::StringToInt(*arg);
2974                 break;
2975             } else {
2976                 mode = DumpMode::NODE;
2977                 nodeId = StringUtils::StringToLongInt(*arg);
2978             }
2979         }
2980     }
2981     std::vector<std::string> info;
2982     bool isChildElement = CheckIsChildElement(nodeId, params, info);
2983     if (isChildElement) {
2984         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "dump child element: %{public}" PRId64, nodeId);
2985         return;
2986     }
2987     switch (mode) {
2988         case DumpMode::TREE:
2989             DumpTreeNG(useWindowId, windowId, rootId, isDumpSimplify);
2990             break;
2991         case DumpMode::NODE:
2992             DumpPropertyNG(nodeId);
2993             break;
2994         case DumpMode::HANDLE_EVENT:
2995             DumpHandleEvent(params);
2996             break;
2997         case DumpMode::HOVER_TEST:
2998             DumpHoverTestNG(windowId, rootId, pointX, pointY, verbose);
2999             break;
3000         default:
3001             DumpLog::GetInstance().Print("Error: invalid arguments!");
3002             break;
3003     }
3004 }
3005 
DumpHandleEvent(const std::vector<std::string> & params)3006 void JsAccessibilityManager::DumpHandleEvent(const std::vector<std::string>& params)
3007 {
3008     if (params.size() > EVENT_DUMP_PARAM_LENGTH_UPPER + 1) {
3009         return DumpLog::GetInstance().Print("Error: params length is illegal!");
3010     }
3011     if (params[EVENT_DUMP_ORDER_INDEX] != DUMP_ORDER && params[EVENT_DUMP_ORDER_INDEX] != DUMP_INSPECTOR) {
3012         return DumpLog::GetInstance().Print("Error: not accessibility dump order!");
3013     }
3014     auto pipeline = context_.Upgrade();
3015     CHECK_NULL_VOID(pipeline);
3016     int64_t nodeId = StringUtils::StringToLongInt(params[EVENT_DUMP_ID_INDEX]);
3017 
3018     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3019     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3020     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(nodeId, splitElementId, splitTreeId);
3021     nodeId = splitElementId;
3022 
3023     auto action = static_cast<AceAction>(StringUtils::StringToInt(params[EVENT_DUMP_ACTION_INDEX]));
3024     auto op = ConvertAceAction(action);
3025     if ((op != ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) && (params.size() > EVENT_DUMP_PARAM_LENGTH_UPPER + 1)) {
3026         return DumpLog::GetInstance().Print("Error: params is illegal!");
3027     }
3028     std::map<std::string, std::string> paramsMap;
3029     ProcessParameters(op, params, paramsMap);
3030     if (AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
3031         RefPtr<NG::FrameNode> node;
3032 #ifdef WINDOW_SCENE_SUPPORTED
3033         auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
3034         auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3035         CHECK_NULL_VOID(uiExtensionManager);
3036         if (uiExtensionManager->IsWrapExtensionAbilityId(nodeId)) {
3037             ExecuteActionNG(nodeId, paramsMap, op, ngPipeline, NG::UI_EXTENSION_OFFSET_MAX);
3038             return;
3039         }
3040 #endif
3041         pipeline = FindPipelineByElementId(nodeId, node);
3042         CHECK_NULL_VOID(pipeline);
3043         pipeline->GetTaskExecutor()->PostTask(
3044             [weak = WeakClaim(this), op, nodeId, paramsMap, pipeline]() {
3045                 auto jsAccessibilityManager = weak.Upgrade();
3046                 CHECK_NULL_VOID(jsAccessibilityManager);
3047                 jsAccessibilityManager->ExecuteActionNG(nodeId, paramsMap, op, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
3048             },
3049             TaskExecutor::TaskType::UI, "ArkUIAccessibilityExecuteAction");
3050         return;
3051     }
3052     auto node = GetAccessibilityNodeFromPage(nodeId);
3053     CHECK_NULL_VOID(node);
3054     pipeline->GetTaskExecutor()->PostTask(
3055         [weak = WeakClaim(this), op, node, paramsMap, pipeline]() {
3056             auto jsAccessibilityManager = weak.Upgrade();
3057             CHECK_NULL_VOID(jsAccessibilityManager);
3058             jsAccessibilityManager->AccessibilityActionEvent(
3059                 op, paramsMap, node, AceType::DynamicCast<PipelineContext>(pipeline));
3060         },
3061         TaskExecutor::TaskType::UI, "ArkUIAccessibilityActionEvent");
3062 }
3063 
DumpProperty(const RefPtr<AccessibilityNode> & node)3064 void JsAccessibilityManager::DumpProperty(const RefPtr<AccessibilityNode>& node)
3065 {
3066     const auto& supportAceActions = node->GetSupportAction();
3067     const auto& charValue = node->GetChartValue();
3068 
3069     DumpLog::GetInstance().AddDesc("ID: ", node->GetNodeId());
3070     DumpLog::GetInstance().AddDesc("parent ID: ", node->GetParentId());
3071     DumpLog::GetInstance().AddDesc("child IDs: ", GetNodeChildIds(node));
3072     DumpLog::GetInstance().AddDesc("component type: ", node->GetTag());
3073     DumpLog::GetInstance().AddDesc("input type: ", node->GetInputType());
3074     DumpLog::GetInstance().AddDesc("text: ", node->GetText());
3075     DumpLog::GetInstance().AddDesc("width: ", node->GetWidth());
3076     DumpLog::GetInstance().AddDesc("height: ", node->GetHeight());
3077     DumpLog::GetInstance().AddDesc("left: ", node->GetLeft() + GetCardOffset().GetX());
3078     DumpLog::GetInstance().AddDesc("top: ", node->GetTop() + GetCardOffset().GetY());
3079     DumpLog::GetInstance().AddDesc("enabled: ", BoolToString(node->GetEnabledState()));
3080     DumpLog::GetInstance().AddDesc("checked: ", BoolToString(node->GetCheckedState()));
3081     DumpLog::GetInstance().AddDesc("selected: ", BoolToString(node->GetSelectedState()));
3082     DumpLog::GetInstance().AddDesc("focusable: ", BoolToString(node->GetFocusableState()));
3083     DumpLog::GetInstance().AddDesc("focused: ", BoolToString(node->GetFocusedState()));
3084     DumpLog::GetInstance().AddDesc("checkable: ", BoolToString(node->GetCheckableState()));
3085     DumpLog::GetInstance().AddDesc("clickable: ", BoolToString(node->GetClickableState()));
3086     DumpLog::GetInstance().AddDesc("long clickable: ", BoolToString(node->GetLongClickableState()));
3087     DumpLog::GetInstance().AddDesc("scrollable: ", BoolToString(node->GetScrollableState()));
3088     DumpLog::GetInstance().AddDesc("editable: ", BoolToString(node->GetEditable()));
3089     DumpLog::GetInstance().AddDesc("hint text: ", node->GetHintText());
3090     DumpLog::GetInstance().AddDesc("error text: ", node->GetErrorText());
3091     DumpLog::GetInstance().AddDesc("js component id: ", node->GetJsComponentId());
3092     DumpLog::GetInstance().AddDesc("accessibility label: ", node->GetAccessibilityLabel());
3093     DumpLog::GetInstance().AddDesc("accessibility hint: ", node->GetAccessibilityHint());
3094     DumpLog::GetInstance().AddDesc("max text length: ", node->GetMaxTextLength());
3095     DumpLog::GetInstance().AddDesc("text selection start: ", node->GetTextSelectionStart());
3096     DumpLog::GetInstance().AddDesc("text selection end: ", node->GetTextSelectionEnd());
3097     DumpLog::GetInstance().AddDesc("is multi line: ", BoolToString(node->GetIsMultiLine()));
3098     DumpLog::GetInstance().AddDesc("is password", BoolToString(node->GetIsPassword()));
3099     DumpLog::GetInstance().AddDesc("text input type: ", ConvertInputTypeToString(node->GetTextInputType()));
3100     DumpLog::GetInstance().AddDesc("min value: ", node->GetAccessibilityValue().min);
3101     DumpLog::GetInstance().AddDesc("max value: ", node->GetAccessibilityValue().max);
3102     DumpLog::GetInstance().AddDesc("current value: ", node->GetAccessibilityValue().current);
3103     DumpLog::GetInstance().AddDesc("collection info rows: ", node->GetCollectionInfo().rows);
3104     DumpLog::GetInstance().AddDesc("collection info columns: ", node->GetCollectionInfo().columns);
3105     DumpLog::GetInstance().AddDesc("collection item info, row: ", node->GetCollectionItemInfo().row);
3106     DumpLog::GetInstance().AddDesc("collection item info, column: ", node->GetCollectionItemInfo().column);
3107     DumpLog::GetInstance().AddDesc("chart has value: ", BoolToString(charValue && !charValue->empty()));
3108     DumpLog::GetInstance().AddDesc("accessibilityGroup: ", BoolToString(node->GetAccessible()));
3109     DumpLog::GetInstance().AddDesc("accessibilityImportance: ", node->GetImportantForAccessibility());
3110     DumpLog::GetInstance().AddDesc("support action: ", GetSupportAction(supportAceActions));
3111     DumpLog::GetInstance().Print(0, node->GetTag(), node->GetChildList().size());
3112 }
3113 
DumpPropertyNG(int64_t nodeID)3114 void JsAccessibilityManager::DumpPropertyNG(int64_t nodeID)
3115 {
3116     auto pipeline = context_.Upgrade();
3117     CHECK_NULL_VOID(pipeline);
3118     RefPtr<NG::PipelineContext> ngPipeline;
3119 
3120 #ifdef WINDOW_SCENE_SUPPORTED
3121     ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
3122     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3123     CHECK_NULL_VOID(uiExtensionManager);
3124     std::list<AccessibilityElementInfo> extensionElementInfos;
3125     if (uiExtensionManager->IsWrapExtensionAbilityId(nodeID)) {
3126         SearchElementInfoByAccessibilityIdNG(
3127             nodeID, PREFETCH_RECURSIVE_CHILDREN, extensionElementInfos, ngPipeline, NG::UI_EXTENSION_OFFSET_MAX);
3128         for (auto& extensionElementInfo : extensionElementInfos) {
3129             if (nodeID == extensionElementInfo.GetAccessibilityId()) {
3130                 DumpCommonPropertyNG(extensionElementInfo, treeId_);
3131                 DumpAccessibilityPropertyNG(extensionElementInfo);
3132                 DumpLog::GetInstance().Print(
3133                     0, extensionElementInfo.GetComponentType(), extensionElementInfo.GetChildCount());
3134                 return;
3135             }
3136         }
3137     }
3138 #endif
3139 
3140     RefPtr<NG::FrameNode> frameNode;
3141     ngPipeline = FindPipelineByElementId(nodeID, frameNode);
3142     CHECK_NULL_VOID(ngPipeline);
3143     CHECK_NULL_VOID(frameNode);
3144 
3145     CommonProperty commonProperty;
3146     GenerateCommonProperty(ngPipeline, commonProperty, pipeline);
3147     AccessibilityElementInfo nodeInfo;
3148     UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, ngPipeline);
3149     if (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode)) {
3150         SearchParameter param {-1, "", PREFETCH_RECURSIVE_CHILDREN, NG::UI_EXTENSION_OFFSET_MAX};
3151         std::list<AccessibilityElementInfo> extensionElementInfos;
3152         SearchExtensionElementInfoNG(param, frameNode, extensionElementInfos, nodeInfo);
3153     }
3154     DumpCommonPropertyNG(nodeInfo, treeId_);
3155     DumpAccessibilityPropertyNG(nodeInfo);
3156     auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
3157     if (accessibilityProperty) {
3158         DumpLog::GetInstance().AddDesc("offset: ", accessibilityProperty->GetScrollOffSet());
3159         DumpLog::GetInstance().AddDesc("childTreeId: ", accessibilityProperty->GetChildTreeId());
3160         DumpLog::GetInstance().AddDesc("childWindowId: ", accessibilityProperty->GetChildWindowId());
3161     }
3162     DumpLog::GetInstance().Print(0, nodeInfo.GetComponentType(), nodeInfo.GetChildCount());
3163 }
3164 
DumpProperty(const std::vector<std::string> & params)3165 void JsAccessibilityManager::DumpProperty(const std::vector<std::string>& params)
3166 {
3167     CHECK_NULL_VOID(DumpLog::GetInstance().GetDumpFile());
3168     if (params.empty()) {
3169         DumpLog::GetInstance().Print("Error: params cannot be empty!");
3170         return;
3171     }
3172     if (params.size() != PROPERTY_DUMP_PARAM_LENGTH) {
3173         DumpLog::GetInstance().Print("Error: params length is illegal!");
3174         return;
3175     }
3176     if (params[0] != DUMP_ORDER && params[0] != DUMP_INSPECTOR) {
3177         DumpLog::GetInstance().Print("Error: not accessibility dump order!");
3178         return;
3179     }
3180 
3181     auto pipeline = context_.Upgrade();
3182     CHECK_NULL_VOID(pipeline);
3183 
3184     if (!AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
3185         auto node = GetAccessibilityNodeFromPage(StringUtils::StringToLongInt(params[1]));
3186         if (!node) {
3187             DumpLog::GetInstance().Print("Error: can't find node with ID " + params[1]);
3188             return;
3189         }
3190         DumpProperty(node);
3191     } else {
3192         DumpPropertyNG(StringUtils::StringToLongInt(params[1]));
3193     }
3194 }
3195 
DumpAccessibilityElementInfosTreeNG(std::list<AccessibilityElementInfo> & infos,int32_t depth,int64_t accessibilityId,bool isRoot)3196 static void DumpAccessibilityElementInfosTreeNG(
3197     std::list<AccessibilityElementInfo>& infos, int32_t depth, int64_t accessibilityId, bool isRoot)
3198 {
3199     AccessibilityElementInfo accessibilityInfo;
3200     for (auto& info : infos) {
3201         if (accessibilityId == info.GetAccessibilityId()) {
3202             accessibilityInfo = info;
3203             break;
3204         }
3205     }
3206     if (!isRoot) {
3207         DumpLog::GetInstance().AddDesc("ID: " + std::to_string(accessibilityInfo.GetAccessibilityId()));
3208         DumpLog::GetInstance().AddDesc("compid: " + accessibilityInfo.GetInspectorKey());
3209         DumpLog::GetInstance().AddDesc("text: " + accessibilityInfo.GetContent());
3210         DumpLog::GetInstance().AddDesc("accessibilityText: " + accessibilityInfo.GetContent());
3211         DumpLog::GetInstance().AddDesc("accessibilityGroup: ");
3212         DumpLog::GetInstance().AddDesc("accessibilityLevel: ");
3213         DumpLog::GetInstance().AddDesc("top: " +
3214             std::to_string(accessibilityInfo.GetRectInScreen().GetLeftTopYScreenPostion()));
3215         DumpLog::GetInstance().AddDesc("left: " +
3216             std::to_string(accessibilityInfo.GetRectInScreen().GetLeftTopXScreenPostion()));
3217         DumpLog::GetInstance().AddDesc("width: " + std::to_string(
3218             accessibilityInfo.GetRectInScreen().GetRightBottomXScreenPostion() -
3219             accessibilityInfo.GetRectInScreen().GetLeftTopXScreenPostion()));
3220         DumpLog::GetInstance().AddDesc("height: " + std::to_string(
3221             accessibilityInfo.GetRectInScreen().GetRightBottomYScreenPostion() -
3222             accessibilityInfo.GetRectInScreen().GetLeftTopYScreenPostion()));
3223         DumpLog::GetInstance().AddDesc("visible: " + std::to_string(accessibilityInfo.IsVisible()));
3224         DumpLog::GetInstance().AddDesc(
3225             "clickable: " + std::to_string(accessibilityInfo.IsClickable()));
3226         DumpLog::GetInstance().AddDesc("longclickable: " +
3227             std::to_string(accessibilityInfo.IsLongClickable()));
3228         DumpLog::GetInstance().AddDesc("checkable: " + std::to_string(accessibilityInfo.IsCheckable()));
3229         DumpLog::GetInstance().AddDesc("scrollable: " + std::to_string(accessibilityInfo.IsScrollable()));
3230         DumpLog::GetInstance().AddDesc("checked: " + std::to_string(accessibilityInfo.IsChecked()));
3231         DumpLog::GetInstance().AddDesc("hint: " + accessibilityInfo.GetHint());
3232         DumpLog::GetInstance().Print(depth, accessibilityInfo.GetComponentType(), accessibilityInfo.GetChildCount());
3233         depth ++;
3234     }
3235     for (auto child : accessibilityInfo.GetChildIds()) {
3236         DumpAccessibilityElementInfosTreeNG(infos, depth, child, false);
3237     }
3238 }
3239 
DumpTreeNodeInfoNG(const RefPtr<NG::FrameNode> & node,int32_t depth,const CommonProperty & commonProperty,int32_t childSize)3240 static void DumpTreeNodeInfoNG(
3241     const RefPtr<NG::FrameNode>& node, int32_t depth, const CommonProperty& commonProperty, int32_t childSize)
3242 {
3243     NG::RectF rect = node->GetTransformRectRelativeToWindow();
3244     DumpLog::GetInstance().AddDesc("ID: " + std::to_string(node->GetAccessibilityId()));
3245     DumpLog::GetInstance().AddDesc("compid: " + node->GetInspectorId().value_or(""));
3246     DumpLog::GetInstance().AddDesc("text: " +
3247         node->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetGroupText());
3248     DumpLog::GetInstance().AddDesc(
3249         "accessibilityText: " + node->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetAccessibilityText());
3250     DumpLog::GetInstance().AddDesc("accessibilityGroup: " +
3251         std::to_string(node->GetAccessibilityProperty<NG::AccessibilityProperty>()->IsAccessibilityGroup()));
3252     DumpLog::GetInstance().AddDesc(
3253         "accessibilityLevel: " + node->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetAccessibilityLevel());
3254     DumpLog::GetInstance().AddDesc("top: " + std::to_string(rect.Top() + commonProperty.windowTop));
3255     DumpLog::GetInstance().AddDesc("left: " + std::to_string(rect.Left() + commonProperty.windowLeft));
3256     DumpLog::GetInstance().AddDesc("width: " + std::to_string(rect.Width()));
3257     DumpLog::GetInstance().AddDesc("height: " + std::to_string(rect.Height()));
3258     DumpLog::GetInstance().AddDesc("visible: " + std::to_string(node->IsVisible()));
3259     auto eventHub = node->GetEventHub<NG::EventHub>();
3260     if (eventHub) {
3261         auto gestureEventHub = eventHub->GetGestureEventHub();
3262         DumpLog::GetInstance().AddDesc(
3263             "clickable: " + std::to_string(gestureEventHub ? gestureEventHub->IsAccessibilityClickable() : false));
3264         DumpLog::GetInstance().AddDesc("longclickable: " +
3265             std::to_string(gestureEventHub ? gestureEventHub->IsAccessibilityLongClickable() : false));
3266     }
3267     DumpLog::GetInstance().AddDesc(
3268         "checkable: " + std::to_string(node->GetAccessibilityProperty<NG::AccessibilityProperty>()->IsCheckable()));
3269     DumpLog::GetInstance().AddDesc(
3270         "scrollable: " + std::to_string(node->GetAccessibilityProperty<NG::AccessibilityProperty>()->IsScrollable()));
3271     DumpLog::GetInstance().AddDesc(
3272         "checked: " + std::to_string(node->GetAccessibilityProperty<NG::AccessibilityProperty>()->IsChecked()));
3273     DumpLog::GetInstance().AddDesc(
3274         "hint: " + node->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetHintText());
3275     DumpLog::GetInstance().AddDesc(
3276         "childTree: " + std::to_string(node->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetChildTreeId()));
3277     DumpLog::GetInstance().Print(depth, node->GetTag(), childSize);
3278 }
3279 
DumpTreeNodeSafeAreaInfoNg(const RefPtr<NG::FrameNode> & node)3280 void JsAccessibilityManager::DumpTreeNodeSafeAreaInfoNg(const RefPtr<NG::FrameNode>& node)
3281 {
3282     auto layoutProperty = node->GetLayoutProperty();
3283     if (layoutProperty) {
3284         auto&& opts = layoutProperty->GetSafeAreaExpandOpts();
3285         if (opts && opts->type != NG::SAFE_AREA_TYPE_NONE && opts->edges != NG::SAFE_AREA_EDGE_NONE) {
3286             DumpLog::GetInstance().AddDesc(opts->ToString());
3287         }
3288         if (layoutProperty->GetSafeAreaInsets()) {
3289             DumpLog::GetInstance().AddDesc(layoutProperty->GetSafeAreaInsets()->ToString());
3290         }
3291     }
3292     if (node->SelfOrParentExpansive()) {
3293         auto geometryNode = node->GetGeometryNode();
3294         if (geometryNode) {
3295             auto rect = geometryNode->GetSelfAdjust();
3296             auto parentRect = geometryNode->GetParentAdjust();
3297             bool isDefaultSize = NearZero(rect.GetX(), 0.0) && NearZero(rect.GetY(), 0.0) &&
3298                                  NearZero(rect.Width(), 0.0) && NearZero(rect.Height(), 0.0);
3299             bool isParentDefaultSize = NearZero(parentRect.GetX(), 0.0) && NearZero(parentRect.GetY(), 0.0) &&
3300                                        NearZero(parentRect.Width(), 0.0) && NearZero(parentRect.Height(), 0.0);
3301             if (!isDefaultSize && !isParentDefaultSize) {
3302                 DumpLog::GetInstance().AddDesc(std::string("selfAdjust: ")
3303                                                    .append(rect.ToString().c_str())
3304                                                    .append(",parentAdjust")
3305                                                    .append(parentRect.ToString().c_str()));
3306             }
3307         }
3308     }
3309     CHECK_NULL_VOID(node->GetTag() == V2::PAGE_ETS_TAG);
3310     auto pipeline = node->GetContext();
3311     CHECK_NULL_VOID(pipeline);
3312     auto manager = pipeline->GetSafeAreaManager();
3313     CHECK_NULL_VOID(manager);
3314     if (!manager->IsIgnoreAsfeArea() && !manager->IsNeedAvoidWindow() && !manager->IsFullScreen() &&
3315         !manager->KeyboardSafeAreaEnabled() && !pipeline->GetUseCutout()) {
3316         DumpLog::GetInstance().AddDesc(std::string("ignoreSafeArea: ")
3317                                            .append(std::to_string(manager->IsIgnoreAsfeArea()))
3318                                            .append(std::string(", isNeedAvoidWindow: ").c_str())
3319                                            .append(std::to_string(manager->IsNeedAvoidWindow()))
3320                                            .append(std::string(", IisFullScreen: ").c_str())
3321                                            .append(std::to_string(manager->IsFullScreen()))
3322                                            .append(std::string(", isKeyboardAvoidMode: ").c_str())
3323                                            .append(std::to_string(manager->KeyboardSafeAreaEnabled()))
3324                                            .append(std::string(", isUseCutout: ").c_str())
3325                                            .append(std::to_string(pipeline->GetUseCutout())));
3326     }
3327 }
3328 
DumpPadding(const std::unique_ptr<NG::PaddingProperty> & padding,std::string label)3329 void JsAccessibilityManager::DumpPadding(const std::unique_ptr<NG::PaddingProperty>& padding, std::string label)
3330 {
3331     NG::CalcLength defaultValue = NG::CalcLength(Dimension(0));
3332     auto left = padding->left.value_or(defaultValue).GetDimension().Value();
3333     auto right = padding->right.value_or(defaultValue).GetDimension().Value();
3334     auto top = padding->top.value_or(defaultValue).GetDimension().Value();
3335     auto bottom = padding->bottom.value_or(defaultValue).GetDimension().Value();
3336     if (!NearZero(left, 0.0) && !NearZero(right, 0.0) && !NearZero(top, 0.0) && !NearZero(bottom, 0.0)) {
3337         DumpLog::GetInstance().AddDesc(label.append(padding->ToString().c_str()));
3338     }
3339 }
3340 
DumpBorder(const std::unique_ptr<NG::BorderWidthProperty> & border,std::string label)3341 void JsAccessibilityManager::DumpBorder(const std::unique_ptr<NG::BorderWidthProperty>& border, std::string label)
3342 {
3343     Dimension defaultValue(0);
3344     auto left = border->leftDimen.value_or(defaultValue).Value();
3345     auto right = border->rightDimen.value_or(defaultValue).Value();
3346     auto top = border->topDimen.value_or(defaultValue).Value();
3347     auto bottom = border->bottomDimen.value_or(defaultValue).Value();
3348     if (!NearZero(left, 0.0) && !NearZero(right, 0.0) && !NearZero(top, 0.0) && !NearZero(bottom, 0.0)) {
3349         DumpLog::GetInstance().AddDesc(label.append(border->ToString().c_str()));
3350     }
3351 }
3352 
DumpTreeNodeCommonInfoNg(const RefPtr<NG::FrameNode> & node,const CommonProperty & commonProperty)3353 void JsAccessibilityManager::DumpTreeNodeCommonInfoNg(
3354     const RefPtr<NG::FrameNode>& node, const CommonProperty& commonProperty)
3355 {
3356     DumpLog::GetInstance().AddDesc("ID: " + std::to_string(node->GetAccessibilityId()));
3357     auto renderContext = node->GetRenderContext();
3358     if (renderContext) {
3359         auto backgroundColor = renderContext->GetBackgroundColor();
3360         if (backgroundColor && backgroundColor->ColorToString().compare("#00000000") != 0) {
3361             DumpLog::GetInstance().AddDesc("BackgroundColor: " + backgroundColor->ColorToString());
3362         }
3363         DumpLog::GetInstance().AddDesc(std::string("PaintRectWithoutTransform: ")
3364                                            .append(renderContext->GetPaintRectWithoutTransform().ToString()));
3365     }
3366     NG::RectF rect = node->GetTransformRectRelativeToWindow();
3367     auto top = rect.Top() + commonProperty.windowTop;
3368     auto left = rect.Left() + commonProperty.windowLeft;
3369     if (!NearZero(top, 0.0) && !NearZero(left, 0.0)) {
3370         DumpLog::GetInstance().AddDesc("top: " + std::to_string(top));
3371         DumpLog::GetInstance().AddDesc("left: " + std::to_string(left));
3372     }
3373     DumpLog::GetInstance().AddDesc("width: " + std::to_string(rect.Width()));
3374     DumpLog::GetInstance().AddDesc("height: " + std::to_string(rect.Height()));
3375     auto layoutProperty = node->GetLayoutProperty();
3376     if (layoutProperty) {
3377         if (!node->IsVisible()) {
3378             DumpLog::GetInstance().AddDesc(
3379                 "visible: " + std::to_string(static_cast<int32_t>(layoutProperty->GetVisibility().value())));
3380         }
3381         auto& padding = layoutProperty->GetPaddingProperty();
3382         if (padding) {
3383             DumpPadding(padding, std::string("Padding: "));
3384         }
3385         auto& margin = layoutProperty->GetMarginProperty();
3386         if (margin) {
3387             DumpPadding(margin, std::string("Margin: "));
3388         }
3389         auto& border = layoutProperty->GetBorderWidthProperty();
3390         if (border) {
3391             DumpBorder(border, std::string("Border: "));
3392         }
3393         auto layoutRect = layoutProperty->GetLayoutRect();
3394         if (layoutRect) {
3395             DumpLog::GetInstance().AddDesc(std::string("LayoutRect: ").append(layoutRect.value().ToString().c_str()));
3396         }
3397     }
3398 }
3399 
DumpTreeNodeSimplifyInfoNG(const RefPtr<NG::FrameNode> & node,int32_t depth,const CommonProperty & commonProperty,int32_t childSize)3400 void JsAccessibilityManager::DumpTreeNodeSimplifyInfoNG(
3401     const RefPtr<NG::FrameNode>& node, int32_t depth, const CommonProperty& commonProperty, int32_t childSize)
3402 {
3403     DumpTreeNodeCommonInfoNg(node, commonProperty);
3404     DumpTreeNodeSafeAreaInfoNg(node);
3405     DumpLog::GetInstance().Print(depth, node->GetTag(), childSize);
3406 }
3407 
DumpTreeAccessibilityNodeNG(const RefPtr<NG::UINode> & uiNodeParent,int32_t depth,int64_t nodeID,const CommonProperty & commonProperty)3408 void JsAccessibilityManager::DumpTreeAccessibilityNodeNG(const RefPtr<NG::UINode>& uiNodeParent, int32_t depth,
3409     int64_t nodeID, const CommonProperty& commonProperty)
3410 {
3411     CHECK_NULL_VOID(uiNodeParent);
3412     auto virtualFrameNode = AceType::DynamicCast<NG::FrameNode>(uiNodeParent);
3413     auto uiNodeChildren = uiNodeParent->GetChildren(true);
3414     auto vNode = GetFramenodeByAccessibilityId(virtualFrameNode, nodeID);
3415     if (!vNode) {
3416         if (uiNodeChildren.size() == 0) {
3417             return;
3418         }
3419     }
3420     std::vector<int64_t> children;
3421     for (const auto& item : uiNodeChildren) {
3422         GetFrameNodeChildren(item, children, commonProperty.pageId);
3423     }
3424     if (vNode != nullptr) {
3425         DumpTreeNodeInfoNG(vNode, depth + 1, commonProperty, children.size());
3426     }
3427     for (const auto& item : uiNodeChildren) {
3428         DumpTreeAccessibilityNodeNG(item, depth + 1, item->GetAccessibilityId(), commonProperty);
3429     }
3430 }
3431 
DumpTreeNG(const RefPtr<NG::FrameNode> & parent,int32_t depth,int64_t nodeID,const CommonProperty & commonProperty,bool isDumpSimplify)3432 void JsAccessibilityManager::DumpTreeNG(const RefPtr<NG::FrameNode>& parent, int32_t depth,
3433     int64_t nodeID, const CommonProperty& commonProperty, bool isDumpSimplify)
3434 {
3435     auto node = GetFramenodeByAccessibilityId(parent, nodeID);
3436     if (!node) {
3437         DumpLog::GetInstance().Print("Error: failed to get accessibility node with ID " + std::to_string(nodeID));
3438         return;
3439     }
3440     if (!node->IsActive()) {
3441         return;
3442     }
3443     std::vector<int64_t> children;
3444     for (const auto& item : node->GetChildren(true)) {
3445         GetFrameNodeChildren(item, children, commonProperty.pageId);
3446     }
3447 
3448     auto overlayNode = node->GetOverlayNode();
3449     if (overlayNode) {
3450         GetFrameNodeChildren(overlayNode, children, commonProperty.pageId);
3451     }
3452 
3453     if (isDumpSimplify) {
3454         DumpTreeNodeSimplifyInfoNG(node, depth, commonProperty, children.size());
3455     } else {
3456         DumpTreeNodeInfoNG(node, depth, commonProperty, children.size());
3457     }
3458     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
3459     auto uiVirtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
3460     bool hasVirtualNode = false;
3461     if (uiVirtualNode != nullptr) {
3462         auto virtualNode = AceType::DynamicCast<NG::FrameNode>(uiVirtualNode);
3463         CHECK_NULL_VOID(virtualNode);
3464         hasVirtualNode = true;
3465         DumpTreeAccessibilityNodeNG(uiVirtualNode, depth+1, virtualNode->GetAccessibilityId(), commonProperty);
3466     }
3467     if (IsExtensionComponent(node) && !IsUIExtensionShowPlaceholder(node)) {
3468         std::list<AccessibilityElementInfo> extensionElementInfos;
3469         auto pipeline = context_.Upgrade();
3470         CHECK_NULL_VOID(pipeline);
3471         SearchElementInfoByAccessibilityIdNG(
3472             node->GetAccessibilityId(), PREFETCH_RECURSIVE_CHILDREN, extensionElementInfos,
3473             pipeline, NG::UI_EXTENSION_OFFSET_MAX);
3474         if (!extensionElementInfos.empty()) {
3475             DumpAccessibilityElementInfosTreeNG(extensionElementInfos, depth + 1, node->GetAccessibilityId(), true);
3476         }
3477     }
3478     if (!hasVirtualNode) {
3479         for (auto childId : children) {
3480             DumpTreeNG(node, depth + 1, childId, commonProperty, isDumpSimplify);
3481         }
3482     }
3483 }
3484 
DumpTree(int32_t depth,int64_t nodeID,bool isDumpSimplify)3485 void JsAccessibilityManager::DumpTree(int32_t depth, int64_t nodeID, bool isDumpSimplify)
3486 {
3487     auto pipeline = context_.Upgrade();
3488     CHECK_NULL_VOID(pipeline);
3489     if (!AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
3490         AccessibilityNodeManager::DumpTree(depth, nodeID, isDumpSimplify);
3491     } else {
3492         auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
3493         auto rootNode = ngPipeline->GetRootElement();
3494         CHECK_NULL_VOID(rootNode);
3495         nodeID = rootNode->GetAccessibilityId();
3496         CommonProperty commonProperty;
3497         GenerateCommonProperty(ngPipeline, commonProperty, pipeline);
3498         DumpTreeNG(rootNode, depth, nodeID, commonProperty, isDumpSimplify);
3499         for (auto subContext : GetSubPipelineContexts()) {
3500             auto subPipeline = subContext.Upgrade();
3501             ngPipeline = AceType::DynamicCast<NG::PipelineContext>(subPipeline);
3502             CHECK_NULL_VOID(ngPipeline);
3503             rootNode = ngPipeline->GetRootElement();
3504             CHECK_NULL_VOID(rootNode);
3505             nodeID = rootNode->GetAccessibilityId();
3506             commonProperty.windowId = static_cast<int32_t>(ngPipeline->GetWindowId());
3507             commonProperty.windowLeft = GetWindowLeft(ngPipeline->GetWindowId());
3508             commonProperty.windowTop = GetWindowTop(ngPipeline->GetWindowId());
3509             commonProperty.pageId = 0;
3510             commonProperty.pagePath = "";
3511             DumpTreeNG(rootNode, depth, nodeID, commonProperty, isDumpSimplify);
3512         }
3513     }
3514 }
3515 
SetCardViewParams(const std::string & key,bool focus)3516 void JsAccessibilityManager::SetCardViewParams(const std::string& key, bool focus)
3517 {
3518     callbackKey_ = key;
3519     if (!callbackKey_.empty()) {
3520         InitializeCallback();
3521     }
3522 }
3523 
UpdateViewScale()3524 void JsAccessibilityManager::UpdateViewScale()
3525 {
3526     auto context = GetPipelineContext().Upgrade();
3527     CHECK_NULL_VOID(context);
3528     float scaleX = 1.0;
3529     float scaleY = 1.0;
3530     if (context->GetViewScale(scaleX, scaleY)) {
3531         scaleX_ = scaleX;
3532         scaleY_ = scaleY;
3533     }
3534 }
3535 
HandleComponentPostBinding()3536 void JsAccessibilityManager::HandleComponentPostBinding()
3537 {
3538     for (auto targetIter = nodeWithTargetMap_.begin(); targetIter != nodeWithTargetMap_.end();) {
3539         auto nodeWithTarget = targetIter->second.Upgrade();
3540         if (nodeWithTarget) {
3541             if (nodeWithTarget->GetTag() == ACCESSIBILITY_TAG_POPUP) {
3542                 auto idNodeIter = nodeWithIdMap_.find(targetIter->first);
3543                 if (idNodeIter != nodeWithIdMap_.end()) {
3544                     auto nodeWithId = idNodeIter->second.Upgrade();
3545                     if (nodeWithId) {
3546                         nodeWithId->SetAccessibilityHint(nodeWithTarget->GetText());
3547                     } else {
3548                         nodeWithIdMap_.erase(idNodeIter);
3549                     }
3550                 }
3551             }
3552             ++targetIter;
3553         } else {
3554             // clear the disabled node in the maps
3555             nodeWithTargetMap_.erase(targetIter++);
3556         }
3557     }
3558 
3559     // clear the disabled node in the maps
3560     for (auto idItem = nodeWithIdMap_.begin(); idItem != nodeWithIdMap_.end();) {
3561         if (!idItem->second.Upgrade()) {
3562             nodeWithIdMap_.erase(idItem++);
3563         } else {
3564             ++idItem;
3565         }
3566     }
3567 }
3568 
Create()3569 RefPtr<AccessibilityNodeManager> AccessibilityNodeManager::Create()
3570 {
3571     return AceType::MakeRefPtr<JsAccessibilityManager>();
3572 }
3573 
GetPipelineByWindowId(const int32_t windowId)3574 RefPtr<PipelineBase> JsAccessibilityManager::GetPipelineByWindowId(const int32_t windowId)
3575 {
3576     auto context = context_.Upgrade();
3577     if (AceType::InstanceOf<NG::PipelineContext>(context)) {
3578         CHECK_NULL_RETURN(context, nullptr);
3579         if (context->GetWindowId() == static_cast<uint32_t>(windowId)) {
3580             return context;
3581         }
3582         if (GetWindowId() == static_cast<uint32_t>(windowId)) {
3583             return context;
3584         }
3585         for (auto& subContext : GetSubPipelineContexts()) {
3586             context = subContext.Upgrade();
3587             CHECK_NULL_RETURN(context, nullptr);
3588             if (context->GetWindowId() == static_cast<uint32_t>(windowId)) {
3589                 return context;
3590             }
3591         }
3592         return nullptr;
3593     } else {
3594         return context;
3595     }
3596 }
3597 
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t mode)3598 void JsAccessibilityManager::JsInteractionOperation::SearchElementInfoByAccessibilityId(const int64_t elementId,
3599     const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t mode)
3600 {
3601     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "search by id: %{public}" PRId64 ", mode: %{public}d",
3602         elementId, mode);
3603     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3604     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3605     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
3606 
3607     auto jsAccessibilityManager = GetHandler().Upgrade();
3608     CHECK_NULL_VOID(jsAccessibilityManager);
3609     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
3610     CHECK_NULL_VOID(context);
3611     auto windowId = windowId_;
3612     context->GetTaskExecutor()->PostTask(
3613         [weak = GetHandler(), splitElementId, requestId, &callback, mode, windowId]() {
3614             auto jsAccessibilityManager = weak.Upgrade();
3615             CHECK_NULL_VOID(jsAccessibilityManager);
3616             ACE_SCOPED_TRACE("SearchElementInfoByAccessibilityId");
3617             jsAccessibilityManager->SearchElementInfoByAccessibilityId(
3618                 splitElementId, requestId, callback, mode, windowId);
3619         },
3620         TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoById");
3621 }
3622 #ifdef WEB_SUPPORTED
3623 
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback,const int32_t mode)3624 void JsAccessibilityManager::WebInteractionOperation::SearchElementInfoByAccessibilityId(const int64_t elementId,
3625     const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode)
3626 {
3627     TAG_LOGD(AceLogTag::ACE_WEB, "search by id: %{public}" PRId64 ", mode: %{public}d",
3628         elementId, mode);
3629     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3630     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3631     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
3632 
3633     auto jsAccessibilityManager = GetHandler().Upgrade();
3634     CHECK_NULL_VOID(jsAccessibilityManager);
3635     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
3636     CHECK_NULL_VOID(context);
3637     auto windowId = windowId_;
3638     auto web = webPattern_;
3639     context->GetTaskExecutor()->PostTask(
3640         [weak = GetHandler(), splitElementId, requestId, &callback, mode, windowId, web]() {
3641             auto jsAccessibilityManager = weak.Upgrade();
3642             CHECK_NULL_VOID(jsAccessibilityManager);
3643             auto webPattern = web.Upgrade();
3644             CHECK_NULL_VOID(webPattern);
3645             ACE_SCOPED_TRACE("SearchWebElementInfoByAccessibilityId");
3646             jsAccessibilityManager->SearchWebElementInfoByAccessibilityId(
3647                 splitElementId, requestId, callback, mode, windowId, webPattern);
3648         },
3649         TaskExecutor::TaskType::UI, "ArkWebAccessibilitySearchElementInfoById");
3650 }
3651 
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)3652 void JsAccessibilityManager::WebInteractionOperation::SearchElementInfosByText(const int64_t elementId,
3653     const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback)
3654 {
3655 }
3656 
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)3657 void JsAccessibilityManager::WebInteractionOperation::FindFocusedElementInfo(const int64_t elementId,
3658     const int32_t focusType, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback)
3659 {
3660     TAG_LOGD(AceLogTag::ACE_WEB, "find focus: %{public}" PRId64 ", focusType: %{public}d",
3661         elementId, focusType);
3662     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3663     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3664     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
3665 
3666     auto jsAccessibilityManager = GetHandler().Upgrade();
3667     CHECK_NULL_VOID(jsAccessibilityManager);
3668     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
3669     CHECK_NULL_VOID(context);
3670     auto windowId = windowId_;
3671     auto web = webPattern_;
3672     context->GetTaskExecutor()->PostTask(
3673         [weak = GetHandler(), splitElementId, focusType, requestId, &callback, windowId, web]() {
3674             auto jsAccessibilityManager = weak.Upgrade();
3675             CHECK_NULL_VOID(jsAccessibilityManager);
3676             auto webPattern = web.Upgrade();
3677             CHECK_NULL_VOID(webPattern);
3678             ACE_SCOPED_TRACE("FindWebFocusedElementInfo");
3679             jsAccessibilityManager->FindWebFocusedElementInfo(
3680                 splitElementId, focusType, requestId, callback, windowId, webPattern);
3681         },
3682         TaskExecutor::TaskType::UI, "ArkWebFindFocusedElementInfo");
3683 }
3684 
FocusMoveSearch(const int64_t elementId,const int32_t direction,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)3685 void JsAccessibilityManager::WebInteractionOperation::FocusMoveSearch(const int64_t elementId, const int32_t direction,
3686     const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback)
3687 {
3688     TAG_LOGD(AceLogTag::ACE_WEB, "move search: %{public}" PRId64 ", direction: %{public}d",
3689         elementId, direction);
3690     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3691     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3692     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
3693 
3694     auto jsAccessibilityManager = GetHandler().Upgrade();
3695     CHECK_NULL_VOID(jsAccessibilityManager);
3696     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
3697     CHECK_NULL_VOID(context);
3698     auto windowId = windowId_;
3699     auto web = webPattern_;
3700     context->GetTaskExecutor()->PostTask(
3701         [weak = GetHandler(), splitElementId, direction, requestId, &callback, windowId, web] {
3702             auto jsAccessibilityManager = weak.Upgrade();
3703             CHECK_NULL_VOID(jsAccessibilityManager);
3704             auto webPattern = web.Upgrade();
3705             CHECK_NULL_VOID(webPattern);
3706             ACE_SCOPED_TRACE("FocusMoveSearch");
3707             jsAccessibilityManager->WebFocusMoveSearch(splitElementId, direction, requestId, callback,
3708                 windowId, webPattern);
3709         },
3710         TaskExecutor::TaskType::UI, "ArkWebFocusMoveSearch");
3711 }
3712 
ExecuteAction(const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback)3713 void JsAccessibilityManager::WebInteractionOperation::ExecuteAction(const int64_t elementId, const int32_t action,
3714     const std::map<std::string, std::string>& actionArguments, const int32_t requestId,
3715     Accessibility::AccessibilityElementOperatorCallback& callback)
3716 {
3717     TAG_LOGD(AceLogTag::ACE_WEB, "elementId: %{public}" PRId64 ", action: %{public}d", elementId, action);
3718     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3719     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3720     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
3721 
3722     auto jsAccessibilityManager = GetHandler().Upgrade();
3723     CHECK_NULL_VOID(jsAccessibilityManager);
3724     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
3725     CHECK_NULL_VOID(context);
3726     auto actionInfo = static_cast<ActionType>(action);
3727     ActionParam param { actionInfo, actionArguments };
3728     auto windowId = windowId_;
3729     auto web = webPattern_;
3730     context->GetTaskExecutor()->PostTask(
3731         [weak = GetHandler(), splitElementId, param, requestId, &callback, windowId, web] {
3732             auto jsAccessibilityManager = weak.Upgrade();
3733             CHECK_NULL_VOID(jsAccessibilityManager);
3734             auto webPattern = web.Upgrade();
3735             CHECK_NULL_VOID(webPattern);
3736             ACE_SCOPED_TRACE("ExecuteAction");
3737             jsAccessibilityManager->ExecuteWebAction(splitElementId, param, requestId, callback, windowId, webPattern);
3738         },
3739         TaskExecutor::TaskType::UI, "ArkWebAccessibilityExecuteAction");
3740 }
3741 
ClearFocus()3742 void JsAccessibilityManager::WebInteractionOperation::ClearFocus() {}
3743 
SetChildTreeIdAndWinId(const int64_t nodeId,const int32_t treeId,const int32_t childWindowId)3744 void JsAccessibilityManager::WebInteractionOperation::SetChildTreeIdAndWinId(const int64_t nodeId, const int32_t treeId,
3745     const int32_t childWindowId) {}
3746 
SetBelongTreeId(const int32_t treeId)3747 void JsAccessibilityManager::WebInteractionOperation::SetBelongTreeId(const int32_t treeId) {}
3748 
GetCursorPosition(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback)3749 void JsAccessibilityManager::WebInteractionOperation::GetCursorPosition(
3750     const int64_t elementId, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
3751 {
3752     TAG_LOGD(AceLogTag::ACE_WEB, "GetCursorPosition id: %{public}" PRId64, elementId);
3753     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
3754     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
3755     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
3756 
3757     auto jsAccessibilityManager = GetHandler().Upgrade();
3758     CHECK_NULL_VOID(jsAccessibilityManager);
3759     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
3760     CHECK_NULL_VOID(context);
3761     auto web = webPattern_;
3762     context->GetTaskExecutor()->PostTask(
3763         [weak = GetHandler(), splitElementId, requestId, &callback, web]() {
3764             auto jsAccessibilityManager = weak.Upgrade();
3765             CHECK_NULL_VOID(jsAccessibilityManager);
3766             auto webPattern = web.Upgrade();
3767             CHECK_NULL_VOID(webPattern);
3768             ACE_SCOPED_TRACE("GetWebCursorPosition");
3769             jsAccessibilityManager->GetWebCursorPosition(splitElementId, requestId, callback, webPattern);
3770         },
3771         TaskExecutor::TaskType::UI, "GetWebCursorPosition");
3772 }
3773 
OutsideTouch()3774 void JsAccessibilityManager::WebInteractionOperation::OutsideTouch() {}
3775 #endif
3776 
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t mode,const int32_t windowId)3777 void JsAccessibilityManager::SearchElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId,
3778     AccessibilityElementOperatorCallback& callback, const int32_t mode, const int32_t windowId)
3779 {
3780     std::list<AccessibilityElementInfo> infos;
3781 
3782     auto pipeline = GetPipelineByWindowId(windowId);
3783     if (pipeline) {
3784         auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
3785         if (ngPipeline) {
3786             SearchElementInfoByAccessibilityIdNG(elementId, mode, infos, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
3787             TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3788                 "SearchElementInfoByAccessibilityIdNG info size: %{public}zu, elementId: %{public}" PRId64,
3789                 infos.size(), elementId);
3790             SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
3791             return;
3792         }
3793     }
3794 
3795     int64_t nodeId = elementId;
3796     if (elementId == -1) {
3797         nodeId = 0;
3798     }
3799     auto weak = WeakClaim(this);
3800     auto jsAccessibilityManager = weak.Upgrade();
3801     CHECK_NULL_VOID(jsAccessibilityManager);
3802     auto node = jsAccessibilityManager->GetAccessibilityNodeFromPage(nodeId);
3803     if (!node) {
3804         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3805             "SearchElementInfoByAccessibilityIdNG info size: %{public}zu, elementId: %{public}" PRId64,
3806             infos.size(), elementId);
3807         SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
3808         return;
3809     }
3810 
3811     AccessibilityElementInfo nodeInfo;
3812     UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager, jsAccessibilityManager->windowId_);
3813     infos.push_back(nodeInfo);
3814     // cache parent/siblings/children infos
3815     UpdateCacheInfo(infos, mode, node, jsAccessibilityManager, jsAccessibilityManager->windowId_);
3816     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY,
3817         "SearchElementInfoByAccessibilityIdNG info size: %{public}zu, elementId: %{public}" PRId64,
3818         infos.size(), elementId);
3819     SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
3820 }
3821 
SearchElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,std::list<AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)3822 void JsAccessibilityManager::SearchElementInfoByAccessibilityIdNG(int64_t elementId, int32_t mode,
3823     std::list<AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context, int64_t uiExtensionOffset)
3824 {
3825     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", treeId: %{public}d, mode: %{public}d",
3826         elementId, treeId_, mode);
3827     auto mainContext = context_.Upgrade();
3828     CHECK_NULL_VOID(mainContext);
3829 
3830     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
3831     CHECK_NULL_VOID(ngPipeline);
3832     auto rootNode = ngPipeline->GetRootElement();
3833     CHECK_NULL_VOID(rootNode);
3834 
3835     AccessibilityElementInfo nodeInfo;
3836     int64_t nodeId = elementId;
3837     if (elementId == -1) {
3838         nodeId = rootNode->GetAccessibilityId();
3839     }
3840 
3841 #ifdef WINDOW_SCENE_SUPPORTED
3842     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3843     CHECK_NULL_VOID(uiExtensionManager);
3844     if (uiExtensionManager->IsWrapExtensionAbilityId(nodeId)) {
3845         SearchParameter param {nodeId, "", mode, uiExtensionOffset};
3846         return SearchExtensionElementInfoByAccessibilityIdNG(param, rootNode, infos, context, ngPipeline);
3847     }
3848 #endif
3849 
3850     CommonProperty commonProperty;
3851     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
3852     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "commonProperty.windowId: %{public}d", commonProperty.windowId);
3853     auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
3854     CHECK_NULL_VOID(node);
3855     UpdateAccessibilityElementInfo(node, commonProperty, nodeInfo, ngPipeline);
3856     SetRootAccessibilityVisible(node, nodeInfo);
3857     if (IsExtensionComponent(node) && !IsUIExtensionShowPlaceholder(node)) {
3858         SearchParameter param {-1, "", mode, uiExtensionOffset};
3859         SearchExtensionElementInfoNG(param, node, infos, nodeInfo);
3860     }
3861     infos.push_back(nodeInfo);
3862     SearchParameter param {nodeId, "", mode, uiExtensionOffset};
3863     UpdateCacheInfoNG(infos, node, commonProperty, ngPipeline, param);
3864     SortExtensionAccessibilityInfo(infos, nodeInfo.GetAccessibilityId());
3865     if ((infos.size() > 0) && (uiExtensionOffset != NG::UI_EXTENSION_OFFSET_MAX) &&
3866         (infos.front().GetComponentType() != V2::ROOT_ETS_TAG) &&
3867         (infos.front().GetParentNodeId() == rootNode->GetAccessibilityId())) {
3868             infos.front().SetParent(NG::UI_EXTENSION_ROOT_ID);
3869     }
3870 }
3871 
SearchExtensionElementInfoByAccessibilityIdNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,const RefPtr<NG::PipelineContext> & ngPipeline)3872 void JsAccessibilityManager::SearchExtensionElementInfoByAccessibilityIdNG(const SearchParameter& searchParam,
3873     const RefPtr<NG::FrameNode>& node, std::list<Accessibility::AccessibilityElementInfo>& infos,
3874     const RefPtr<PipelineBase>& context, const RefPtr<NG::PipelineContext>& ngPipeline)
3875 {
3876 #ifdef WINDOW_SCENE_SUPPORTED
3877     auto mainContext = context_.Upgrade();
3878     CHECK_NULL_VOID(mainContext);
3879     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3880     CHECK_NULL_VOID(uiExtensionManager);
3881     auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset, searchParam.nodeId);
3882     int64_t childWrapId = unWrapIdPair.second;
3883     int64_t uiExtensionId = unWrapIdPair.first;
3884     auto uiExtensionNode = FindNodeFromRootByExtensionId(node, uiExtensionId);
3885     CHECK_NULL_VOID(uiExtensionNode);
3886     SearchParameter param {childWrapId, "", searchParam.mode, searchParam.uiExtensionOffset};
3887     AccessibilityElementInfo nodeInfo;
3888     CommonProperty commonProperty;
3889     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
3890     UpdateAccessibilityElementInfo(uiExtensionNode, commonProperty, nodeInfo, ngPipeline);
3891     SearchExtensionElementInfoNG(param, uiExtensionNode, infos, nodeInfo);
3892 #endif
3893 }
3894 
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,const RefPtr<NG::FrameNode> & node,int64_t offset)3895 std::list<AccessibilityElementInfo> JsAccessibilityManager::SearchElementInfosByTextNG(
3896     int64_t elementId, const std::string& text, const RefPtr<NG::FrameNode>& node, int64_t offset)
3897 {
3898     std::list<AccessibilityElementInfo> extensionElementInfo;
3899     if (NG::UI_EXTENSION_OFFSET_MIN < (offset + 1)) {
3900         node->SearchElementInfosByTextNG(elementId, text, offset, extensionElementInfo);
3901     }
3902     return extensionElementInfo;
3903 }
3904 
SearchElementInfosByTextNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,const RefPtr<NG::PipelineContext> & ngPipeline)3905 void JsAccessibilityManager::SearchElementInfosByTextNG(const SearchParameter& searchParam,
3906     const RefPtr<NG::FrameNode>& node, std::list<Accessibility::AccessibilityElementInfo>& infos,
3907     const RefPtr<PipelineBase>& context, const RefPtr<NG::PipelineContext>& ngPipeline)
3908 {
3909 #ifdef WINDOW_SCENE_SUPPORTED
3910     auto mainContext = context_.Upgrade();
3911     CHECK_NULL_VOID(mainContext);
3912     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3913     CHECK_NULL_VOID(uiExtensionManager);
3914     auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset, searchParam.nodeId);
3915     int64_t childWrapId = unWrapIdPair.second;
3916     int64_t uiExtensionId = unWrapIdPair.first;
3917     std::list<AccessibilityElementInfo> extensionElementInfos;
3918     AccessibilityElementInfo nodeInfo;
3919     auto uiExtensionNode = FindNodeFromRootByExtensionId(node, uiExtensionId);
3920     CHECK_NULL_VOID(uiExtensionNode);
3921 
3922     extensionElementInfos = SearchElementInfosByTextNG(
3923         childWrapId, searchParam.text, uiExtensionNode, searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
3924     if (extensionElementInfos.empty()) {
3925         return;
3926     }
3927     CommonProperty commonProperty;
3928     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
3929     UpdateAccessibilityElementInfo(uiExtensionNode, commonProperty, nodeInfo, ngPipeline);
3930     ConvertExtensionAccessibilityNodeId(extensionElementInfos, uiExtensionNode,
3931         searchParam.uiExtensionOffset, nodeInfo);
3932     for (auto& info : extensionElementInfos) {
3933         infos.emplace_back(info);
3934     }
3935 #endif
3936 }
3937 
FindNodeFromRootByExtensionId(const RefPtr<NG::FrameNode> & root,const int64_t uiExtensionId)3938 RefPtr<NG::FrameNode> JsAccessibilityManager::FindNodeFromRootByExtensionId(
3939     const RefPtr<NG::FrameNode>& root, const int64_t uiExtensionId)
3940 {
3941     CHECK_NULL_RETURN(root, nullptr);
3942     std::queue<RefPtr<NG::UINode>> nodes;
3943     nodes.push(root);
3944     RefPtr<NG::FrameNode> frameNode;
3945     while (!nodes.empty()) {
3946         auto current = nodes.front();
3947         nodes.pop();
3948         frameNode = AceType::DynamicCast<NG::FrameNode>(current);
3949         if (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode) &&
3950             (uiExtensionId == frameNode->GetUiExtensionId())) {
3951             return frameNode;
3952         }
3953         const auto& children = current->GetChildren(true);
3954         for (const auto& child : children) {
3955             nodes.push(child);
3956         }
3957     }
3958     return nullptr;
3959 }
3960 
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)3961 void JsAccessibilityManager::SearchElementInfosByTextNG(int64_t elementId, const std::string& text,
3962     std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context,
3963     int64_t uiExtensionOffset)
3964 {
3965     auto mainContext = context_.Upgrade();
3966     CHECK_NULL_VOID(mainContext);
3967     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
3968     CHECK_NULL_VOID(ngPipeline);
3969     auto rootNode = ngPipeline->GetRootElement();
3970     CHECK_NULL_VOID(rootNode);
3971 #ifdef WINDOW_SCENE_SUPPORTED
3972     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
3973     CHECK_NULL_VOID(uiExtensionManager);
3974     if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
3975         SearchParameter param {elementId, text, 0, uiExtensionOffset};
3976         SearchElementInfosByTextNG(param, rootNode, infos, context, ngPipeline);
3977         return;
3978     }
3979 #endif
3980     if (elementId == NG::UI_EXTENSION_ROOT_ID) {
3981         elementId = rootNode->GetAccessibilityId();
3982     }
3983     auto node = GetFramenodeByAccessibilityId(rootNode, elementId);
3984     CHECK_NULL_VOID(node);
3985     CommonProperty commonProperty;
3986     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
3987     nlohmann::json textJson = nlohmann::json::parse(text, nullptr, false);
3988     if (textJson.is_null() || textJson.is_discarded() || !textJson.contains("type")) {
3989         return;
3990     }
3991     if (textJson["type"] == "textType") {
3992         SearchParameter param {0, text, 0, uiExtensionOffset};
3993         FindTextByTextHint(node, infos, ngPipeline, commonProperty, param);
3994         return;
3995     }
3996     if (!textJson.contains("value")) {
3997         return;
3998     }
3999     SearchParameter param {0, textJson["value"], 0, uiExtensionOffset};
4000     FindText(node, infos, ngPipeline, commonProperty, param);
4001 }
4002 
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,AccessibilityElementOperatorCallback & callback)4003 void JsAccessibilityManager::JsInteractionOperation::SearchElementInfosByText(const int64_t elementId,
4004     const std::string& text, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
4005 {
4006     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "search by text: %{public}" PRId64 ", text: %{public}s",
4007         elementId, text.c_str());
4008     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
4009     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
4010     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
4011 
4012     if (text.empty()) {
4013         return;
4014     }
4015     auto jsAccessibilityManager = GetHandler().Upgrade();
4016     CHECK_NULL_VOID(jsAccessibilityManager);
4017     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
4018     CHECK_NULL_VOID(context);
4019     auto windowId = windowId_;
4020     if (context) {
4021         context->GetTaskExecutor()->PostTask(
4022             [weak = GetHandler(), splitElementId, text, requestId, &callback, windowId]() {
4023                 auto jsAccessibilityManager = weak.Upgrade();
4024                 CHECK_NULL_VOID(jsAccessibilityManager);
4025                 ACE_SCOPED_TRACE("SearchElementInfosByText");
4026                 jsAccessibilityManager->SearchElementInfosByText(
4027                     splitElementId, text, requestId, callback, windowId);
4028             },
4029             TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoByText");
4030     }
4031 }
4032 
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)4033 void JsAccessibilityManager::SearchElementInfosByText(const int64_t elementId, const std::string& text,
4034     const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId)
4035 {
4036     if (text.empty()) {
4037         return;
4038     }
4039 
4040     if (elementId == -1) {
4041         return;
4042     }
4043 
4044     std::list<AccessibilityElementInfo> infos;
4045 
4046     auto pipeline = GetPipelineByWindowId(windowId);
4047     if (pipeline) {
4048         if (AceType::InstanceOf<NG::PipelineContext>(pipeline)) {
4049             SearchElementInfosByTextNG(elementId, text, infos, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
4050             SetSearchElementInfoByTextResult(callback, std::move(infos), requestId);
4051             return;
4052         }
4053     }
4054 
4055     auto weak = WeakClaim(this);
4056     auto jsAccessibilityManager = weak.Upgrade();
4057     CHECK_NULL_VOID(jsAccessibilityManager);
4058     int64_t nodeId = elementId;
4059     auto node = jsAccessibilityManager->GetAccessibilityNodeFromPage(nodeId);
4060     CHECK_NULL_VOID(node);
4061     std::list<RefPtr<AccessibilityNode>> nodeList;
4062     OHOS::Ace::Framework::FindText(node, text, nodeList);
4063     if (!nodeList.empty()) {
4064         for (const auto& node : nodeList) {
4065             AccessibilityElementInfo nodeInfo;
4066             UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager, jsAccessibilityManager->windowId_);
4067             infos.emplace_back(nodeInfo);
4068         }
4069     }
4070 
4071     SetSearchElementInfoByTextResult(callback, std::move(infos), requestId);
4072 }
4073 
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,AccessibilityElementOperatorCallback & callback)4074 void JsAccessibilityManager::JsInteractionOperation::FindFocusedElementInfo(const int64_t elementId,
4075     const int32_t focusType, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
4076 {
4077     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "find focus: %{public}" PRId64 ", focusType: %{public}d",
4078         elementId, focusType);
4079     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
4080     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
4081     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
4082 
4083     auto jsAccessibilityManager = GetHandler().Upgrade();
4084     CHECK_NULL_VOID(jsAccessibilityManager);
4085     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
4086     CHECK_NULL_VOID(context);
4087     auto windowId = windowId_;
4088     context->GetTaskExecutor()->PostTask(
4089         [weak = GetHandler(), splitElementId, focusType, requestId, &callback, windowId]() {
4090             auto jsAccessibilityManager = weak.Upgrade();
4091             CHECK_NULL_VOID(jsAccessibilityManager);
4092             ACE_SCOPED_TRACE("FindFocusedElementInfo");
4093             jsAccessibilityManager->FindFocusedElementInfo(splitElementId, focusType, requestId, callback, windowId);
4094         },
4095         TaskExecutor::TaskType::UI, "ArkUIAccessibilityFindFocusedElementInfo");
4096 }
4097 
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)4098 void JsAccessibilityManager::FindFocusedElementInfo(const int64_t elementId, const int32_t focusType,
4099     const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId)
4100 {
4101     AccessibilityElementInfo nodeInfo;
4102     if (focusType != FOCUS_TYPE_INPUT && focusType != FOCUS_TYPE_ACCESSIBILITY) {
4103         nodeInfo.SetValidElement(false);
4104         SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4105         return;
4106     }
4107 
4108     auto context = GetPipelineByWindowId(windowId);
4109     if (!context) {
4110         SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4111         return;
4112     }
4113 
4114     if (AceType::InstanceOf<NG::PipelineContext>(context)) {
4115         FindFocusedElementInfoNG(elementId, focusType, nodeInfo, context, NG::UI_EXTENSION_OFFSET_MAX);
4116         SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4117         return;
4118     }
4119 
4120     int64_t nodeId = static_cast<int64_t>(elementId);
4121     if (elementId == -1) {
4122         nodeId = 0;
4123     }
4124 
4125     auto node = GetAccessibilityNodeFromPage(nodeId);
4126     if (!node) {
4127         nodeInfo.SetValidElement(false);
4128         SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4129         return;
4130     }
4131 
4132     RefPtr<AccessibilityNode> resultNode = nullptr;
4133     bool status = false;
4134     if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
4135         status = FindAccessibilityFocus(node, resultNode);
4136     }
4137     if (focusType == FOCUS_TYPE_INPUT) {
4138         status = FindInputFocus(node, resultNode);
4139     }
4140 
4141     if ((status) && (resultNode != nullptr)) {
4142         UpdateAccessibilityNodeInfo(resultNode, nodeInfo, Claim(this), windowId_);
4143     }
4144 
4145     SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4146 }
4147 
FindFocusedElementInfoNG(int64_t elementId,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const int64_t uiExtensionOffset)4148 void JsAccessibilityManager::FindFocusedElementInfoNG(int64_t elementId, int32_t focusType,
4149     Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
4150     const int64_t uiExtensionOffset)
4151 {
4152     auto mainContext = context_.Upgrade();
4153     CHECK_NULL_VOID(mainContext);
4154     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4155     CHECK_NULL_VOID(ngPipeline);
4156     auto rootNode = ngPipeline->GetRootElement();
4157     CHECK_NULL_VOID(rootNode);
4158 #ifdef WINDOW_SCENE_SUPPORTED
4159     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
4160     CHECK_NULL_VOID(uiExtensionManager);
4161     if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
4162         SearchParameter param {elementId, "", focusType, uiExtensionOffset};
4163         return FindFocusedExtensionElementInfoNG(param, info, context, rootNode);
4164     }
4165 #endif
4166     int64_t nodeId = elementId;
4167     if (elementId == -1) {
4168         nodeId = rootNode->GetAccessibilityId();
4169     }
4170     auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
4171     if (!node) {
4172         return info.SetValidElement(false);
4173     }
4174     if (IsExtensionComponent(node) && !IsUIExtensionShowPlaceholder(node)) {
4175         SearchParameter transferSearchParam {NG::UI_EXTENSION_ROOT_ID, "", focusType, uiExtensionOffset};
4176         OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(transferSearchParam, node, info);
4177         return SetUiExtensionAbilityParentIdForFocus(node, uiExtensionOffset, info);
4178     }
4179     RefPtr<NG::FrameNode> resultNode;
4180     if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
4181         resultNode = FindAccessibilityFocus(node, focusType, info, uiExtensionOffset, context, currentFocusNodeId_);
4182     }
4183     if (focusType == FOCUS_TYPE_INPUT) {
4184         resultNode = FindInputFocus(node, focusType, info, uiExtensionOffset, context);
4185     }
4186     if ((!resultNode) || (IsExtensionComponent(resultNode) && !IsUIExtensionShowPlaceholder(resultNode))) {
4187         return;
4188     }
4189     CommonProperty commonProperty;
4190     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
4191     UpdateAccessibilityElementInfo(resultNode, commonProperty, info, ngPipeline);
4192     UpdateUiExtensionParentIdForFocus(rootNode, uiExtensionOffset, info);
4193 }
4194 
FindFocusedExtensionElementInfoNG(const SearchParameter & searchParam,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::FrameNode> & root)4195 void JsAccessibilityManager::FindFocusedExtensionElementInfoNG(const SearchParameter& searchParam,
4196     Accessibility::AccessibilityElementInfo& info,
4197     const RefPtr<PipelineBase>& context, const RefPtr<NG::FrameNode>& root)
4198 {
4199 #ifdef WINDOW_SCENE_SUPPORTED
4200     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4201     CHECK_NULL_VOID(ngPipeline);
4202     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
4203     CHECK_NULL_VOID(uiExtensionManager);
4204     auto elementIdPair = uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset,
4205         searchParam.nodeId);
4206     auto uiExtensionNode = uiExtensionManager->GetFocusUiExtensionNode();
4207     CHECK_NULL_VOID(uiExtensionNode);
4208     SearchParameter transferSearchParam {elementIdPair.second, "",
4209         searchParam.mode, searchParam.uiExtensionOffset};
4210     OHOS::Ace::Framework::FindFocusedExtensionElementInfoNG(transferSearchParam, uiExtensionNode, info);
4211     SetUiExtensionAbilityParentIdForFocus(uiExtensionNode, searchParam.uiExtensionOffset, info);
4212 #endif
4213 }
4214 
FindNodeFromPipeline(const WeakPtr<PipelineBase> & context,const int64_t elementId)4215 RefPtr<NG::FrameNode> JsAccessibilityManager::FindNodeFromPipeline(
4216     const WeakPtr<PipelineBase>& context, const int64_t elementId)
4217 {
4218     auto pipeline = context.Upgrade();
4219     CHECK_NULL_RETURN(pipeline, nullptr);
4220 
4221     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
4222     auto rootNode = ngPipeline->GetRootElement();
4223     CHECK_NULL_RETURN(rootNode, nullptr);
4224 
4225     int64_t nodeId = elementId;
4226     // accessibility use -1 for first search to get root node
4227     if (elementId == -1) {
4228         nodeId = rootNode->GetAccessibilityId();
4229     }
4230 
4231     auto node = GetFramenodeByAccessibilityId(rootNode, nodeId);
4232     if (node) {
4233         return node;
4234     }
4235     return nullptr;
4236 }
4237 
FindPipelineByElementId(const int64_t elementId,RefPtr<NG::FrameNode> & node)4238 RefPtr<NG::PipelineContext> JsAccessibilityManager::FindPipelineByElementId(
4239     const int64_t elementId, RefPtr<NG::FrameNode>& node)
4240 {
4241     node = FindNodeFromPipeline(context_, elementId);
4242     if (node) {
4243         auto context = AceType::DynamicCast<NG::PipelineContext>(context_.Upgrade());
4244         return context;
4245     }
4246     for (auto subContext : GetSubPipelineContexts()) {
4247         node = FindNodeFromPipeline(subContext, elementId);
4248         if (node) {
4249             auto context = AceType::DynamicCast<NG::PipelineContext>(subContext.Upgrade());
4250             return context;
4251         }
4252     }
4253     return nullptr;
4254 }
4255 
ExecuteAction(const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,AccessibilityElementOperatorCallback & callback)4256 void JsAccessibilityManager::JsInteractionOperation::ExecuteAction(const int64_t elementId, const int32_t action,
4257     const std::map<std::string, std::string>& actionArguments, const int32_t requestId,
4258     AccessibilityElementOperatorCallback& callback)
4259 {
4260     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", action: %{public}d", elementId, action);
4261     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
4262     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
4263     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
4264 
4265     auto jsAccessibilityManager = GetHandler().Upgrade();
4266     CHECK_NULL_VOID(jsAccessibilityManager);
4267     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
4268     CHECK_NULL_VOID(context);
4269     auto actionInfo = static_cast<ActionType>(action);
4270     ActionParam param { actionInfo, actionArguments };
4271     auto windowId = windowId_;
4272     context->GetTaskExecutor()->PostTask(
4273         [weak = GetHandler(), splitElementId, param, requestId, &callback, windowId] {
4274             auto jsAccessibilityManager = weak.Upgrade();
4275             CHECK_NULL_VOID(jsAccessibilityManager);
4276             ACE_SCOPED_TRACE("ExecuteAction");
4277             jsAccessibilityManager->ExecuteAction(splitElementId, param, requestId, callback, windowId);
4278         },
4279         TaskExecutor::TaskType::UI, "ArkUIAccessibilityExecuteAction");
4280 }
4281 
AccessibilityActionEvent(const ActionType & action,const std::map<std::string,std::string> & actionArguments,const RefPtr<AccessibilityNode> & node,const RefPtr<PipelineContext> & context)4282 bool JsAccessibilityManager::AccessibilityActionEvent(const ActionType& action,
4283     const std::map<std::string, std::string>& actionArguments, const RefPtr<AccessibilityNode>& node,
4284     const RefPtr<PipelineContext>& context)
4285 {
4286     if (!node || !context) {
4287         return false;
4288     }
4289     ContainerScope scope(context->GetInstanceId());
4290     switch (action) {
4291         case ActionType::ACCESSIBILITY_ACTION_CLICK: {
4292             node->SetClicked(true);
4293             if (!node->GetClickEventMarker().IsEmpty()) {
4294 #ifndef NG_BUILD
4295                 context->SendEventToFrontend(node->GetClickEventMarker());
4296 #endif
4297                 node->ActionClick();
4298                 return true;
4299             }
4300             return node->ActionClick();
4301         }
4302         case ActionType::ACCESSIBILITY_ACTION_LONG_CLICK: {
4303             if (!node->GetLongPressEventMarker().IsEmpty()) {
4304 #ifndef NG_BUILD
4305                 context->SendEventToFrontend(node->GetLongPressEventMarker());
4306 #endif
4307                 node->ActionLongClick();
4308                 return true;
4309             }
4310             return node->ActionLongClick();
4311         }
4312         case ActionType::ACCESSIBILITY_ACTION_SET_TEXT: {
4313             if (!node->GetSetTextEventMarker().IsEmpty()) {
4314 #ifndef NG_BUILD
4315                 context->SendEventToFrontend(node->GetSetTextEventMarker());
4316 #endif
4317                 node->ActionSetText(actionArguments.find(ACTION_ARGU_SET_TEXT)->second);
4318                 return true;
4319             }
4320             return node->ActionSetText(actionArguments.find(ACTION_ARGU_SET_TEXT)->second);
4321         }
4322         case ActionType::ACCESSIBILITY_ACTION_FOCUS: {
4323 #ifndef NG_BUILD
4324             context->AccessibilityRequestFocus(std::to_string(node->GetNodeId()));
4325 #endif
4326             if (!node->GetFocusEventMarker().IsEmpty()) {
4327 #ifndef NG_BUILD
4328                 context->SendEventToFrontend(node->GetFocusEventMarker());
4329 #endif
4330                 node->ActionFocus();
4331                 return true;
4332             }
4333             return node->ActionFocus();
4334         }
4335         case ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS: {
4336             return RequestAccessibilityFocus(node);
4337         }
4338         case ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
4339             return ClearAccessibilityFocus(node);
4340         }
4341         case ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD:
4342             return node->ActionScrollForward();
4343         case ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD:
4344             return node->ActionScrollBackward();
4345         default:
4346             return false;
4347     }
4348 }
4349 
SendActionEvent(const Accessibility::ActionType & action,int64_t nodeId)4350 void JsAccessibilityManager::SendActionEvent(const Accessibility::ActionType& action, int64_t nodeId)
4351 {
4352     static std::unordered_map<Accessibility::ActionType, std::string> actionToStr {
4353         { Accessibility::ActionType::ACCESSIBILITY_ACTION_CLICK, DOM_CLICK },
4354         { Accessibility::ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, DOM_LONG_PRESS },
4355         { Accessibility::ActionType::ACCESSIBILITY_ACTION_FOCUS, DOM_FOCUS },
4356         { Accessibility::ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, ACCESSIBILITY_FOCUSED_EVENT },
4357         { Accessibility::ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, ACCESSIBILITY_CLEAR_FOCUS_EVENT },
4358         { Accessibility::ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, SCROLL_END_EVENT },
4359         { Accessibility::ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, SCROLL_END_EVENT },
4360     };
4361     if (actionToStr.find(action) == actionToStr.end()) {
4362         return;
4363     }
4364     AccessibilityEvent accessibilityEvent;
4365     accessibilityEvent.eventType = actionToStr[action];
4366     accessibilityEvent.nodeId = static_cast<int64_t>(nodeId);
4367     SendAccessibilityAsyncEvent(accessibilityEvent);
4368 }
4369 
4370 namespace {
stringToLower(std::string & str)4371 void stringToLower(std::string &str)
4372 {
4373     std::transform(str.begin(), str.end(), str.begin(), [](char &c) {
4374         return std::tolower(c);
4375     });
4376 }
4377 
conversionDirection(std::string dir)4378 bool conversionDirection(std::string dir)
4379 {
4380     stringToLower(dir);
4381     if (dir.compare(STRING_DIR_FORWARD) == 0) {
4382         return true;
4383     }
4384 
4385     return false;
4386 }
4387 
getArgumentByKey(const std::map<std::string,std::string> & actionArguments,const std::string & checkKey)4388 int32_t getArgumentByKey(const std::map<std::string, std::string>& actionArguments, const std::string& checkKey)
4389 {
4390     auto iter = actionArguments.find(checkKey);
4391     int32_t argument = -1; // -1:default value
4392     if (iter != actionArguments.end()) {
4393         std::stringstream strArguments;
4394         strArguments << iter->second;
4395         strArguments >> argument;
4396     }
4397     return argument;
4398 }
4399 
findAccessibilityScrollType(int32_t accessibilityScrollTypeValue)4400 AccessibilityScrollType findAccessibilityScrollType(int32_t accessibilityScrollTypeValue)
4401 {
4402     switch (accessibilityScrollTypeValue) {
4403         case 0:
4404             return AccessibilityScrollType::SCROLL_HALF;
4405         case 1:
4406             return AccessibilityScrollType::SCROLL_FULL;
4407         default:
4408             return AccessibilityScrollType::SCROLL_DEFAULT;
4409     }
4410 }
4411 
getAccessibilityScrollType(const std::map<std::string,std::string> & actionArguments,const std::string & checkKey)4412 AccessibilityScrollType getAccessibilityScrollType(const std::map<std::string, std::string>& actionArguments,
4413     const std::string& checkKey)
4414 {
4415     auto argument = getArgumentByKey(actionArguments, checkKey);
4416     return findAccessibilityScrollType(argument);
4417 }
4418 
4419 
ActAccessibilityAction(Accessibility::ActionType action,const std::map<std::string,std::string> & actionArguments,RefPtr<NG::AccessibilityProperty> accessibilityProperty)4420 bool ActAccessibilityAction(Accessibility::ActionType action, const std::map<std::string, std::string>& actionArguments,
4421     RefPtr<NG::AccessibilityProperty> accessibilityProperty)
4422 {
4423     AccessibilityActionParam param;
4424     if (action == ActionType::ACCESSIBILITY_ACTION_SET_SELECTION) {
4425         std::string dir = STRING_DIR_BACKWARD;
4426         auto iter = actionArguments.find(ACTION_ARGU_SELECT_TEXT_INFORWARD);
4427         if (iter != actionArguments.end()) {
4428             dir = iter->second;
4429         }
4430         param.setSelectionStart = getArgumentByKey(actionArguments, ACTION_ARGU_SELECT_TEXT_START);
4431         param.setSelectionEnd = getArgumentByKey(actionArguments, ACTION_ARGU_SELECT_TEXT_END);
4432         param.setSelectionDir = conversionDirection(dir);
4433     }
4434     if (action == ActionType::ACCESSIBILITY_ACTION_SET_TEXT) {
4435         auto iter = actionArguments.find(ACTION_ARGU_SET_TEXT);
4436         if (iter != actionArguments.end()) {
4437             param.setTextArgument = iter->second;
4438         }
4439     }
4440     if (action == ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT ||
4441         action == ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT) {
4442         int moveUnit = TextMoveUnit::STEP_CHARACTER;
4443         auto iter = actionArguments.find(ACTION_ARGU_MOVE_UNIT);
4444         if (iter != actionArguments.end()) {
4445             std::stringstream str_moveUnit;
4446             str_moveUnit << iter->second;
4447             str_moveUnit >> moveUnit;
4448         }
4449         param.moveUnit = static_cast<TextMoveUnit>(moveUnit);
4450     }
4451     if (action == ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION) {
4452         param.setCursorIndex = getArgumentByKey(actionArguments, ACTION_ARGU_SET_OFFSET);
4453     }
4454     if ((action == ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD) ||
4455         (action == ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD)) {
4456         param.scrollType = getAccessibilityScrollType(actionArguments, ACTION_ARGU_SCROLL_STUB);
4457     }
4458     if (action == ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK) {
4459         param.spanId = getArgumentByKey(actionArguments, ACTION_ARGU_SPAN_ID);
4460     }
4461     auto accessibiltyAction = ACTIONS.find(action);
4462     if (accessibiltyAction != ACTIONS.end()) {
4463         param.accessibilityProperty = accessibilityProperty;
4464         return accessibiltyAction->second(param);
4465     }
4466     return false;
4467 }
4468 }
4469 
ExecuteExtensionActionNG(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)4470 bool JsAccessibilityManager::ExecuteExtensionActionNG(int64_t elementId,
4471     const std::map<std::string, std::string>& actionArguments, int32_t action, const RefPtr<PipelineBase>& context,
4472     int64_t uiExtensionOffset)
4473 {
4474     return ExecuteActionNG(
4475         elementId, actionArguments, static_cast<ActionType>(action), context, uiExtensionOffset);
4476 }
4477 
ExecuteActionNG(int64_t elementId,const std::map<std::string,std::string> & actionArguments,ActionType action,const RefPtr<PipelineBase> & context,int64_t uiExtensionOffset)4478 bool JsAccessibilityManager::ExecuteActionNG(int64_t elementId,
4479     const std::map<std::string, std::string>& actionArguments, ActionType action, const RefPtr<PipelineBase>& context,
4480     int64_t uiExtensionOffset)
4481 {
4482     bool result = false;
4483     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4484     CHECK_NULL_RETURN(ngPipeline, result);
4485 #ifdef WINDOW_SCENE_SUPPORTED
4486     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
4487     CHECK_NULL_RETURN(uiExtensionManager, result);
4488     if (uiExtensionManager->IsWrapExtensionAbilityId(elementId)) {
4489         auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(uiExtensionOffset, elementId);
4490         int64_t childWrapId = unWrapIdPair.second;
4491         int64_t uiExtensionId = unWrapIdPair.first;
4492         auto rootNode = ngPipeline->GetRootElement();
4493         CHECK_NULL_RETURN(rootNode, result);
4494         auto uiExtensionNode = FindNodeFromRootByExtensionId(rootNode, uiExtensionId);
4495         CHECK_NULL_RETURN(uiExtensionNode, result);
4496         return OHOS::Ace::Framework::TransferExecuteAction(
4497             childWrapId, uiExtensionNode, actionArguments, action, uiExtensionOffset);
4498     }
4499 #endif
4500     ContainerScope instance(ngPipeline->GetInstanceId());
4501     auto frameNode = GetFramenodeByAccessibilityId(ngPipeline->GetRootElement(), elementId);
4502     if (!frameNode && elementId == lastElementId_) {
4503         frameNode = lastFrameNode_.Upgrade();
4504     }
4505     CHECK_NULL_RETURN(frameNode, result);
4506 
4507     auto enabled = frameNode->GetFocusHub() ? frameNode->GetFocusHub()->IsEnabled() : true;
4508     if (!enabled && action != ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS &&
4509         action != ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS) {
4510         return result;
4511     }
4512     result = ConvertActionTypeToBoolen(action, frameNode, elementId, ngPipeline);
4513     if (!result) {
4514         auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
4515         CHECK_NULL_RETURN(accessibilityProperty, false);
4516         result = ActAccessibilityAction(action, actionArguments, accessibilityProperty);
4517     }
4518     return result;
4519 }
4520 
ConvertActionTypeToBoolen(ActionType action,RefPtr<NG::FrameNode> & frameNode,int64_t elementId,RefPtr<NG::PipelineContext> & context)4521 bool JsAccessibilityManager::ConvertActionTypeToBoolen(ActionType action, RefPtr<NG::FrameNode>& frameNode,
4522     int64_t elementId, RefPtr<NG::PipelineContext>& context)
4523 {
4524     bool result = false;
4525     switch (action) {
4526         case ActionType::ACCESSIBILITY_ACTION_FOCUS: {
4527             result = RequestFocus(frameNode);
4528             break;
4529         }
4530         case ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS: {
4531             result = LostFocus(frameNode);
4532             break;
4533         }
4534         case ActionType::ACCESSIBILITY_ACTION_CLICK: {
4535             result = ActClick(frameNode);
4536             break;
4537         }
4538         case ActionType::ACCESSIBILITY_ACTION_LONG_CLICK: {
4539             result = ActLongClick(frameNode);
4540             break;
4541         }
4542         case ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS: {
4543             SaveLast(elementId, frameNode);
4544             SaveCurrentFocusNodeSize(frameNode);
4545             result = ActAccessibilityFocus(elementId, frameNode, context, currentFocusNodeId_, false);
4546             break;
4547         }
4548         case ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
4549             SaveLast(elementId, frameNode);
4550             result = ActAccessibilityFocus(elementId, frameNode, context, currentFocusNodeId_, true);
4551             break;
4552         }
4553         default:
4554             break;
4555     }
4556     return result;
4557 }
4558 
ExecuteAction(const int64_t elementId,const ActionParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId)4559 void JsAccessibilityManager::ExecuteAction(const int64_t elementId, const ActionParam& param, const int32_t requestId,
4560     AccessibilityElementOperatorCallback& callback, const int32_t windowId)
4561 {
4562     auto action = param.action;
4563     auto actionArguments = param.actionArguments;
4564 
4565     bool actionResult = false;
4566     auto context = GetPipelineByWindowId(windowId);
4567     if (!context) {
4568         SetExecuteActionResult(callback, actionResult, requestId);
4569         return;
4570     }
4571 
4572     if (AceType::InstanceOf<NG::PipelineContext>(context)) {
4573         actionResult = ExecuteActionNG(elementId, actionArguments, action, context, NG::UI_EXTENSION_OFFSET_MAX);
4574     } else {
4575         auto node = GetAccessibilityNodeFromPage(elementId);
4576         if (!node) {
4577             SetExecuteActionResult(callback, false, requestId);
4578             return;
4579         }
4580 
4581         actionResult =
4582             AccessibilityActionEvent(action, actionArguments, node, AceType::DynamicCast<PipelineContext>(context));
4583     }
4584     SetExecuteActionResult(callback, actionResult, requestId);
4585     if (actionResult && AceType::InstanceOf<PipelineContext>(context)) {
4586         SendActionEvent(action, elementId);
4587     }
4588 }
4589 
GetCursorPosition(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback)4590 void JsAccessibilityManager::JsInteractionOperation::GetCursorPosition(const int64_t elementId,
4591     const int32_t requestId, AccessibilityElementOperatorCallback &callback)
4592 {
4593     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
4594     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
4595     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
4596 
4597     auto jsAccessibilityManager = GetHandler().Upgrade();
4598     CHECK_NULL_VOID(jsAccessibilityManager);
4599     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
4600     CHECK_NULL_VOID(context);
4601     RefPtr<NG::FrameNode> node;
4602     auto ngPipeline = jsAccessibilityManager->FindPipelineByElementId(splitElementId, node);
4603     CHECK_NULL_VOID(ngPipeline);
4604 #ifdef WINDOW_SCENE_SUPPORTED
4605     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
4606     CHECK_NULL_VOID(uiExtensionManager);
4607     if (uiExtensionManager->IsWrapExtensionAbilityId(splitElementId)) {
4608         auto unWrapIdPair = uiExtensionManager->UnWrapExtensionAbilityId(NG::UI_EXTENSION_OFFSET_MAX, elementId);
4609         int64_t uiExtensionId = unWrapIdPair.first;
4610         auto rootNode = ngPipeline->GetRootElement();
4611         CHECK_NULL_VOID(rootNode);
4612         auto uiExtensionNode = jsAccessibilityManager->FindNodeFromRootByExtensionId(rootNode, uiExtensionId);
4613         CHECK_NULL_VOID(uiExtensionNode);
4614         auto accessibilityProperty = uiExtensionNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
4615         CHECK_NULL_VOID(accessibilityProperty);
4616         auto callNumber = accessibilityProperty->ActActionGetIndex();
4617         callback.SetCursorPositionResult(callNumber, requestId);
4618         return;
4619     }
4620 #endif
4621     auto frameNode = GetFramenodeByAccessibilityId(ngPipeline->GetRootElement(), splitElementId);
4622     CHECK_NULL_VOID(frameNode);
4623     auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
4624     CHECK_NULL_VOID(accessibilityProperty);
4625     auto callNumber = accessibilityProperty->ActActionGetIndex();
4626     callback.SetCursorPositionResult(callNumber, requestId);
4627 }
4628 
ClearFocus()4629 void JsAccessibilityManager::JsInteractionOperation::ClearFocus()
4630 {
4631     auto jsAccessibilityManager = GetHandler().Upgrade();
4632     CHECK_NULL_VOID(jsAccessibilityManager);
4633     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
4634     CHECK_NULL_VOID(context);
4635     context->GetTaskExecutor()->PostTask(
4636         [weak = GetHandler()] {
4637             auto jsAccessibilityManager = weak.Upgrade();
4638             CHECK_NULL_VOID(jsAccessibilityManager);
4639             ACE_SCOPED_TRACE("ClearCurrentFocus");
4640             jsAccessibilityManager->ClearCurrentFocus();
4641         },
4642         TaskExecutor::TaskType::UI, "ArkUIAccessibilityClearCurrentFocus");
4643 }
4644 
OutsideTouch()4645 void JsAccessibilityManager::JsInteractionOperation::OutsideTouch() {}
4646 #ifdef WEB_SUPPORTED
4647 
GetChildrenFromWebNode(int64_t nodeId,std::list<int64_t> & children,const RefPtr<NG::PipelineContext> & ngPipeline,const RefPtr<NG::WebPattern> & webPattern)4648 void GetChildrenFromWebNode(
4649     int64_t nodeId, std::list<int64_t>& children,
4650     const RefPtr<NG::PipelineContext>& ngPipeline, const RefPtr<NG::WebPattern>& webPattern)
4651 {
4652     std::list<int64_t> webNodeChildren;
4653     if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
4654         auto node = webPattern->GetAccessibilityNodeById(nodeId);
4655         CHECK_NULL_VOID(node);
4656     for (auto& childId : node->GetChildIds()) {
4657             webNodeChildren.emplace_back(childId);
4658         }
4659     }
4660     while (!webNodeChildren.empty()) {
4661         children.emplace_back(webNodeChildren.front());
4662         webNodeChildren.pop_front();
4663     }
4664 }
4665 
SearchWebElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t mode,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)4666 void JsAccessibilityManager::SearchWebElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId,
4667     AccessibilityElementOperatorCallback& callback, const int32_t mode, const int32_t windowId,
4668     const RefPtr<NG::WebPattern>& webPattern)
4669 {
4670     std::list<AccessibilityElementInfo> infos;
4671 
4672     auto pipeline = GetPipelineByWindowId(windowId);
4673     CHECK_NULL_VOID(pipeline);
4674     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
4675     CHECK_NULL_VOID(ngPipeline);
4676 
4677     if (!ngPipeline->GetOnFoucs() && (SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE)) {
4678         TAG_LOGD(AceLogTag::ACE_WEB,
4679             "SearchWebElementInfo GetOnFocus, elementId: %{public}" PRId64
4680             ", requestId: %{public}d, mode: %{public}d, windowId: %{public}d",
4681             elementId, requestId, mode, windowId);
4682         SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
4683         return;
4684     }
4685     CHECK_NULL_VOID(webPattern);
4686     auto webNode = webPattern->GetHost();
4687     bool webActive = webPattern->GetActiveStatus();
4688     if (!webActive) {
4689         TAG_LOGD(AceLogTag::ACE_WEB,
4690             "SearchWebElementinfo webActive false, elementId: %{public}" PRId64
4691             ", requestId: %{public}d, mode: %{public}d, windowId: %{public}d",
4692             elementId, requestId, mode, windowId);
4693         SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
4694         return;
4695     }
4696     if (!IsNodeInRoot(webNode, ngPipeline)) {
4697         TAG_LOGD(AceLogTag::ACE_WEB,
4698             "SearchWebElementInfo IsNodeInRoot, elementId: %{public}" PRId64
4699             ", requestId: %{public}d, mode: %{public}d, windowId: %{public}d",
4700             elementId, requestId, mode, windowId);
4701         SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
4702         return;
4703     }
4704 
4705     SearchWebElementInfoByAccessibilityIdNG(elementId, mode, infos, ngPipeline, webPattern);
4706     SetSearchElementInfoByAccessibilityIdResult(callback, std::move(infos), requestId);
4707 }
4708 
SearchWebElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,std::list<AccessibilityElementInfo> & infos,const RefPtr<PipelineBase> & context,const RefPtr<NG::WebPattern> & webPattern)4709 void JsAccessibilityManager::SearchWebElementInfoByAccessibilityIdNG(int64_t elementId, int32_t mode,
4710     std::list<AccessibilityElementInfo>& infos, const RefPtr<PipelineBase>& context,
4711     const RefPtr<NG::WebPattern>& webPattern)
4712 {
4713     TAG_LOGD(AceLogTag::ACE_WEB, "elementId: %{public}" PRId64 ", treeId: %{public}d, mode: %{public}d",
4714         elementId, treeId_, mode);
4715     auto mainContext = context_.Upgrade();
4716     CHECK_NULL_VOID(mainContext);
4717 
4718     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4719     CHECK_NULL_VOID(ngPipeline);
4720 
4721     AccessibilityElementInfo nodeInfo;
4722 
4723     CommonProperty commonProperty;
4724     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
4725 
4726     CHECK_NULL_VOID(webPattern);
4727     auto node = webPattern->GetAccessibilityNodeById(elementId);
4728     CHECK_NULL_VOID(node);
4729     UpdateWebAccessibilityElementInfo(node, commonProperty, nodeInfo, webPattern);
4730     nodeInfo.SetAccessibilityVisible(webPattern->GetAccessibilityVisible(elementId));
4731     infos.push_back(nodeInfo);
4732     SearchParameter param {elementId, "", mode, 0};
4733     UpdateWebCacheInfo(infos, elementId, commonProperty, ngPipeline, param, webPattern);
4734 }
4735 
FindWebFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)4736 void JsAccessibilityManager::FindWebFocusedElementInfo(const int64_t elementId, const int32_t focusType,
4737     const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId,
4738     const RefPtr<NG::WebPattern>& webPattern)
4739 {
4740     AccessibilityElementInfo nodeInfo;
4741     if (focusType != FOCUS_TYPE_INPUT && focusType != FOCUS_TYPE_ACCESSIBILITY) {
4742         nodeInfo.SetValidElement(false);
4743         SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4744         return;
4745     }
4746 
4747     auto context = GetPipelineByWindowId(windowId);
4748     if (!context || AceType::InstanceOf<NG::PipelineContext>(context)) {
4749         nodeInfo.SetValidElement(false);
4750         SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4751         return;
4752     }
4753 
4754     FindWebFocusedElementInfoNG(elementId, focusType, nodeInfo, context, webPattern);
4755     SetFindFocusedElementInfoResult(callback, nodeInfo, requestId);
4756 }
4757 
FindWebFocusedElementInfoNG(int64_t elementId,int32_t focusType,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::WebPattern> & webPattern)4758 void JsAccessibilityManager::FindWebFocusedElementInfoNG(int64_t elementId, int32_t focusType,
4759     Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
4760     const RefPtr<NG::WebPattern>& webPattern)
4761 {
4762     auto mainContext = context_.Upgrade();
4763     CHECK_NULL_VOID(mainContext);
4764     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4765     CHECK_NULL_VOID(ngPipeline);
4766     auto node = webPattern->GetFocusedAccessibilityNode(elementId, focusType == FOCUS_TYPE_ACCESSIBILITY);
4767     if (!node) {
4768         info.SetValidElement(false);
4769         return;
4770     }
4771     CHECK_NULL_VOID(node);
4772     CommonProperty commonProperty;
4773     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
4774     UpdateWebAccessibilityElementInfo(node, commonProperty, info, webPattern);
4775 }
4776 
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)4777 void JsAccessibilityManager::WebFocusMoveSearch(const int64_t elementId, const int32_t direction,
4778     const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId,
4779     const RefPtr<NG::WebPattern>& webPattern)
4780 {
4781     AccessibilityElementInfo nodeInfo;
4782     auto context = GetPipelineByWindowId(windowId);
4783     if (!context) {
4784         nodeInfo.SetValidElement(false);
4785         SetFocusMoveSearchResult(callback, nodeInfo, requestId);
4786         return;
4787     }
4788 
4789     WebFocusMoveSearchNG(elementId, direction, nodeInfo, context, webPattern);
4790     SetFocusMoveSearchResult(callback, nodeInfo, requestId);
4791 }
4792 
WebFocusMoveSearchNG(int64_t elementId,int32_t direction,AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::WebPattern> & webPattern)4793 void JsAccessibilityManager::WebFocusMoveSearchNG(int64_t elementId, int32_t direction,
4794     AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
4795     const RefPtr<NG::WebPattern>& webPattern)
4796 {
4797     auto mainContext = context_.Upgrade();
4798     CHECK_NULL_VOID(mainContext);
4799     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
4800     CHECK_NULL_VOID(ngPipeline);
4801 
4802     auto node = webPattern->GetAccessibilityNodeByFocusMove(elementId, direction);
4803     if (!node) {
4804         info.SetValidElement(false);
4805         return;
4806     }
4807     CommonProperty commonProperty;
4808     GenerateCommonProperty(ngPipeline, commonProperty, mainContext);
4809     UpdateWebAccessibilityElementInfo(node, commonProperty, info, webPattern);
4810 }
4811 
ExecuteWebActionNG(int64_t elementId,ActionType action,const std::map<std::string,std::string> & actionArguments,const RefPtr<NG::WebPattern> & webPattern)4812 bool JsAccessibilityManager::ExecuteWebActionNG(int64_t elementId, ActionType action,
4813     const std::map<std::string, std::string>& actionArguments, const RefPtr<NG::WebPattern>& webPattern)
4814 {
4815     CHECK_NULL_RETURN(webPattern, false);
4816     return webPattern->ExecuteAction(elementId, ConvertAccessibilityAction(action), actionArguments);
4817 }
4818 
ExecuteWebAction(const int64_t elementId,const ActionParam & param,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const int32_t windowId,const RefPtr<NG::WebPattern> & webPattern)4819 void JsAccessibilityManager::ExecuteWebAction(const int64_t elementId, const ActionParam& param,
4820     const int32_t requestId, AccessibilityElementOperatorCallback& callback, const int32_t windowId,
4821     const RefPtr<NG::WebPattern>& webPattern)
4822 {
4823     auto action = param.action;
4824     auto actionArguments = param.actionArguments;
4825 
4826     bool actionResult = false;
4827     auto context = GetPipelineByWindowId(windowId);
4828     if (!context || !AceType::InstanceOf<NG::PipelineContext>(context)) {
4829         SetExecuteActionResult(callback, actionResult, requestId);
4830         return;
4831     }
4832 
4833     actionResult = ExecuteWebActionNG(elementId, action, actionArguments, webPattern);
4834     SetExecuteActionResult(callback, actionResult, requestId);
4835 }
4836 
RegisterWebInteractionOperationAsChildTree(int64_t accessibilityId,const WeakPtr<NG::WebPattern> & webPattern)4837 bool JsAccessibilityManager::RegisterWebInteractionOperationAsChildTree(int64_t accessibilityId,
4838     const WeakPtr<NG::WebPattern>& webPattern)
4839 {
4840     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
4841     CHECK_NULL_RETURN(instance, false);
4842     auto pipelineContext = GetPipelineContext().Upgrade();
4843     CHECK_NULL_RETURN(pipelineContext, false);
4844     auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
4845     if (container != nullptr && container->IsUIExtensionWindow()) {
4846         windowId_ = pipelineContext->GetRealHostWindowId();
4847     }
4848 
4849     AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId_, accessibilityId);
4850 
4851     uint32_t windowId = GetWindowId();
4852     auto interactionOperation = std::make_shared<WebInteractionOperation>(windowId);
4853     interactionOperation->SetHandler(WeakClaim(this));
4854     interactionOperation->SetWebPattern(webPattern);
4855     auto pattern = webPattern.Upgrade();
4856     CHECK_NULL_RETURN(pattern, false);
4857     Accessibility::Registration registration {
4858         .windowId = windowId,
4859         .parentWindowId = windowId,
4860         .parentTreeId = treeId_,
4861         .elementId = accessibilityId,
4862     };
4863     parentWebWindowId_ = windowId;
4864     TAG_LOGI(AceLogTag::ACE_WEB, "windowId: %{public}u, parentWindowId: %{public}u, "
4865         "parentTreeId: %{public}d, elementId %{public}" PRId64,
4866         windowId, windowId, treeId_, accessibilityId);
4867     Accessibility::RetError retReg = instance->RegisterElementOperator(registration, interactionOperation);
4868     TAG_LOGI(AceLogTag::ACE_WEB, "RegisterWebInteractionOperationAsChildTree result: %{public}d", retReg);
4869     return retReg == RET_OK;
4870 }
4871 
DeregisterWebInteractionOperationAsChildTree(int32_t treeId)4872 bool JsAccessibilityManager::DeregisterWebInteractionOperationAsChildTree(int32_t treeId)
4873 {
4874     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
4875     CHECK_NULL_RETURN(instance, false);
4876     uint32_t windowId = GetWindowId();
4877     Accessibility::RetError retReg = instance->DeregisterElementOperator(windowId, treeId);
4878     return retReg == RET_OK;
4879 }
4880 
UpdateWebCacheInfo(std::list<AccessibilityElementInfo> & infos,int64_t nodeId,const CommonProperty & commonProperty,const RefPtr<NG::PipelineContext> & ngPipeline,const SearchParameter & searchParam,const RefPtr<NG::WebPattern> & webPattern)4881 void JsAccessibilityManager::UpdateWebCacheInfo(std::list<AccessibilityElementInfo>& infos,
4882     int64_t nodeId, const CommonProperty& commonProperty, const RefPtr<NG::PipelineContext>& ngPipeline,
4883     const SearchParameter& searchParam, const RefPtr<NG::WebPattern>& webPattern)
4884 {
4885     uint32_t umode = searchParam.mode;
4886     std::list<int64_t> children;
4887     // get all children
4888     if (!(umode & static_cast<uint32_t>(PREFETCH_RECURSIVE_CHILDREN))) {
4889         return;
4890     }
4891     GetChildrenFromWebNode(nodeId, children, ngPipeline, webPattern);
4892     while (!children.empty()) {
4893         int64_t parent = children.front();
4894         children.pop_front();
4895         AccessibilityElementInfo nodeInfo;
4896 
4897         GetChildrenFromWebNode(parent, children, ngPipeline, webPattern);
4898         auto node = webPattern->GetAccessibilityNodeById(parent);
4899         if (node) {
4900             UpdateWebAccessibilityElementInfo(node, commonProperty, nodeInfo, webPattern);
4901             infos.push_back(nodeInfo);
4902         }
4903     }
4904 }
4905 #endif //WEB_SUPPORTED
4906 
RegisterInteractionOperationAsChildTree(const Registration & registration)4907 bool JsAccessibilityManager::RegisterInteractionOperationAsChildTree(
4908     const Registration& registration)
4909 {
4910     bool ret = false;
4911     switch (registration.operatorType) {
4912         case OperatorType::JS_THIRD_PROVIDER:
4913             ret = RegisterThirdProviderInteractionOperationAsChildTree(registration);
4914             break;
4915         default:
4916             TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY,
4917                 "RegisterInteractionOperationAsChildTree operatorType: %{public}d",
4918                 static_cast<int32_t>(registration.operatorType));
4919     }
4920     return ret;
4921 }
4922 
RegisterThirdProviderInteractionOperationAsChildTree(const Registration & registration)4923 bool JsAccessibilityManager::RegisterThirdProviderInteractionOperationAsChildTree(
4924     const Registration& registration)
4925 {
4926     std::shared_ptr<AccessibilitySystemAbilityClient> instance =
4927         AccessibilitySystemAbilityClient::GetInstance();
4928     CHECK_NULL_RETURN(instance, false);
4929     Accessibility::Registration innerRegistration {
4930         .windowId = registration.windowId,
4931         .parentWindowId = registration.parentWindowId,
4932         .parentTreeId = registration.parentTreeId,
4933         .elementId = registration.elementId,
4934     };
4935 
4936     auto provider = registration.accessibilityProvider.Upgrade();
4937     CHECK_NULL_RETURN(provider, false);
4938     auto interactionOperation = std::make_shared<JsThirdProviderInteractionOperation>(
4939         registration.accessibilityProvider, WeakClaim(this), registration.hostNode);
4940     provider->SendThirdAccessibilityProvider(interactionOperation);
4941     interactionOperation->Initialize();
4942     RegisterJsThirdProviderInteractionOperation(registration.elementId,
4943         interactionOperation);
4944     Accessibility::RetError retReg = instance->RegisterElementOperator(
4945         innerRegistration, interactionOperation);
4946     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
4947         "RegisterWebInteractionOperationAsChildTree result: %{public}d", retReg);
4948     return retReg == RET_OK;
4949 }
4950 
DeregisterInteractionOperationAsChildTree(uint32_t windowId,int32_t treeId)4951 bool JsAccessibilityManager::DeregisterInteractionOperationAsChildTree(
4952     uint32_t windowId, int32_t treeId)
4953 {
4954     std::shared_ptr<AccessibilitySystemAbilityClient> instance =
4955         AccessibilitySystemAbilityClient::GetInstance();
4956     CHECK_NULL_RETURN(instance, false);
4957     Accessibility::RetError retReg = instance->DeregisterElementOperator(windowId, treeId);
4958     return retReg == RET_OK;
4959 }
4960 
RegisterInteractionOperation(int windowId)4961 int JsAccessibilityManager::RegisterInteractionOperation(int windowId)
4962 {
4963     if (IsRegister()) {
4964         return 0;
4965     }
4966 
4967     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
4968     CHECK_NULL_RETURN(instance, -1);
4969     auto interactionOperation = std::make_shared<JsInteractionOperation>(windowId);
4970     interactionOperation->SetHandler(WeakClaim(this));
4971     Accessibility::RetError retReg = instance->RegisterElementOperator(windowId, interactionOperation);
4972     RefPtr<PipelineBase> context;
4973     for (auto subContext : GetSubPipelineContexts()) {
4974         context = subContext.Upgrade();
4975         CHECK_NULL_RETURN(context, -1);
4976         interactionOperation = std::make_shared<JsInteractionOperation>(context->GetWindowId());
4977         interactionOperation->SetHandler(WeakClaim(this));
4978         auto retResult = instance->RegisterElementOperator(context->GetWindowId(), interactionOperation);
4979         retReg = retResult == RET_OK ? retReg : retResult;
4980     }
4981     Register(retReg == RET_OK);
4982     if (retReg == RET_OK) {
4983         NotifyChildTreeOnRegister(treeId_);
4984     }
4985 
4986     return retReg;
4987 }
4988 
RegisterSubWindowInteractionOperation(int windowId)4989 void JsAccessibilityManager::RegisterSubWindowInteractionOperation(int windowId)
4990 {
4991     if (!AceApplicationInfo::GetInstance().IsAccessibilityEnabled() || !IsRegister()) {
4992         return;
4993     }
4994 
4995     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
4996     CHECK_NULL_VOID(instance);
4997     auto interactionOperation = std::make_shared<JsInteractionOperation>(windowId);
4998     interactionOperation->SetHandler(WeakClaim(this));
4999     instance->RegisterElementOperator(windowId, interactionOperation);
5000 }
5001 
DeregisterInteractionOperation()5002 void JsAccessibilityManager::DeregisterInteractionOperation()
5003 {
5004     if (!IsRegister()) {
5005         return;
5006     }
5007     int windowId = static_cast<int>(GetWindowId());
5008 
5009     auto instance = AccessibilitySystemAbilityClient::GetInstance();
5010     CHECK_NULL_VOID(instance);
5011     Register(false);
5012     if (currentFocusNodeId_ != -1 && lastElementId_ != -1) {
5013         auto focusNode = lastFrameNode_.Upgrade();
5014         if (focusNode != nullptr) {
5015             focusNode->GetRenderContext()->UpdateAccessibilityFocus(false);
5016         }
5017     }
5018     lastFrameNode_.Reset();
5019     lastElementId_ = -1;
5020     currentFocusNodeId_ = -1;
5021     if (parentWindowId_ == 0) {
5022         instance->DeregisterElementOperator(windowId);
5023     } else {
5024         instance->DeregisterElementOperator(windowId, treeId_);
5025         parentElementId_ = INVALID_PARENT_ID;
5026         parentTreeId_ = 0;
5027         parentWindowId_ = 0;
5028     }
5029 
5030     RefPtr<PipelineBase> context;
5031     for (auto subContext : GetSubPipelineContexts()) {
5032         context = subContext.Upgrade();
5033         CHECK_NULL_VOID(context);
5034         instance->DeregisterElementOperator(context->GetWindowId());
5035     }
5036     NotifyChildTreeOnDeregister();
5037 }
5038 
RegisterAccessibilityChildTreeCallback(int64_t elementId,const std::shared_ptr<AccessibilityChildTreeCallback> & callback)5039 void JsAccessibilityManager::RegisterAccessibilityChildTreeCallback(
5040     int64_t elementId, const std::shared_ptr<AccessibilityChildTreeCallback> &callback)
5041 {
5042     std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
5043     childTreeCallbackMap_[elementId] = callback;
5044 }
5045 
DeregisterAccessibilityChildTreeCallback(int64_t elementId)5046 void JsAccessibilityManager::DeregisterAccessibilityChildTreeCallback(int64_t elementId)
5047 {
5048     std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
5049     childTreeCallbackMap_.erase(elementId);
5050 }
5051 
RegisterAccessibilitySAObserverCallback(int64_t elementId,const std::shared_ptr<AccessibilitySAObserverCallback> & callback)5052 void JsAccessibilityManager::RegisterAccessibilitySAObserverCallback(
5053     int64_t elementId, const std::shared_ptr<AccessibilitySAObserverCallback> &callback)
5054 {
5055     std::lock_guard<std::mutex> lock(componentSACallbackMutex_);
5056     componentSACallbackMap_[elementId] = callback;
5057 }
5058 
DeregisterAccessibilitySAObserverCallback(int64_t elementId)5059 void JsAccessibilityManager::DeregisterAccessibilitySAObserverCallback(int64_t elementId)
5060 {
5061     std::lock_guard<std::mutex> lock(componentSACallbackMutex_);
5062     componentSACallbackMap_.erase(elementId);
5063 }
5064 
NotifyAccessibilitySAStateChange(bool state)5065 void JsAccessibilityManager::NotifyAccessibilitySAStateChange(bool state)
5066 {
5067     std::lock_guard<std::mutex> lock(componentSACallbackMutex_);
5068     for (auto &item : componentSACallbackMap_) {
5069         if (item.second == nullptr) {
5070             continue;
5071         }
5072         item.second->OnState(state);
5073     }
5074 }
5075 
NotifyChildTreeOnRegister(int32_t treeId)5076 void JsAccessibilityManager::NotifyChildTreeOnRegister(int32_t treeId)
5077 {
5078     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "NotifyChildTreeOnRegister size: %{public}zu", childTreeCallbackMap_.size());
5079     std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
5080     for (auto &item : childTreeCallbackMap_) {
5081         if (item.second == nullptr) {
5082             continue;
5083         }
5084         item.second->OnRegister(GetWindowId(), treeId);
5085     }
5086 }
5087 
NotifyChildTreeOnDeregister()5088 void JsAccessibilityManager::NotifyChildTreeOnDeregister()
5089 {
5090     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "NotifyChildTreeOnDeregister size: %{public}zu",
5091         childTreeCallbackMap_.size());
5092     std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
5093     for (auto &item : childTreeCallbackMap_) {
5094         if (item.second == nullptr) {
5095             continue;
5096         }
5097         item.second->OnDeregister();
5098     }
5099 }
5100 
NotifySetChildTreeIdAndWinId(int64_t elementId,const int32_t treeId,const int32_t childWindowId)5101 void JsAccessibilityManager::NotifySetChildTreeIdAndWinId(
5102     int64_t elementId, const int32_t treeId, const int32_t childWindowId)
5103 {
5104     std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
5105     auto findResult = childTreeCallbackMap_.find(elementId);
5106     if (findResult == childTreeCallbackMap_.end()) {
5107         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "node: %{public}" PRId64 " not found, treeId: %{public}d", elementId,
5108             treeId);
5109         return;
5110     }
5111     auto callback = findResult->second;
5112     CHECK_NULL_VOID(callback);
5113     callback->SetChildTreeId(treeId);
5114     callback->OnSetChildTree(childWindowId, treeId);
5115 }
5116 
CheckIsChildElement(int64_t & elementId,const std::vector<std::string> & params,std::vector<std::string> & info)5117 bool JsAccessibilityManager::CheckIsChildElement(
5118     int64_t &elementId, const std::vector<std::string> &params, std::vector<std::string> &info)
5119 {
5120     if (elementId <= 0) {
5121         return false;
5122     }
5123 
5124     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5125     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5126     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5127     if (splitTreeId <= 0 || splitTreeId == treeId_) {
5128         elementId = splitElementId;
5129         return false;
5130     }
5131     std::lock_guard<std::mutex> lock(childTreeCallbackMapMutex_);
5132     for (const auto &item : childTreeCallbackMap_) {
5133         if (item.second == nullptr) {
5134             continue;
5135         }
5136         if (item.second->GetChildTreeId() != splitTreeId) {
5137             continue;
5138         }
5139         item.second->OnDumpChildInfo(params, info);
5140         for (const auto &childInfo : info) {
5141             DumpLog::GetInstance().Print(childInfo.c_str());
5142         }
5143         return true;
5144     }
5145     return false;
5146 }
5147 
NeedRegisterChildTree(uint32_t parentWindowId,int32_t parentTreeId,int64_t parentElementId)5148 bool JsAccessibilityManager::NeedRegisterChildTree(
5149     uint32_t parentWindowId, int32_t parentTreeId, int64_t parentElementId)
5150 {
5151     if (!IsRegister()) {
5152         return true;
5153     }
5154 
5155     if (parentWindowId_ == parentWindowId && parentTreeId_ == parentTreeId && parentElementId_ == parentElementId) {
5156         return false;
5157     }
5158     DeregisterInteractionOperationAsChildTree();
5159     return true;
5160 }
5161 
RegisterInteractionOperationAsChildTree(uint32_t parentWindowId,int32_t parentTreeId,int64_t parentElementId)5162 void JsAccessibilityManager::RegisterInteractionOperationAsChildTree(
5163     uint32_t parentWindowId, int32_t parentTreeId, int64_t parentElementId)
5164 {
5165     AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(parentTreeId, parentElementId);
5166     if (!NeedRegisterChildTree(parentWindowId, parentTreeId, parentElementId)) {
5167         return;
5168     }
5169 
5170     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
5171     CHECK_NULL_VOID(instance);
5172     auto pipelineContext = GetPipelineContext().Upgrade();
5173     CHECK_NULL_VOID(pipelineContext);
5174     auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId());
5175     if (container != nullptr && container->IsUIExtensionWindow()) {
5176         windowId_ = pipelineContext->GetRealHostWindowId();
5177     } else if (pipelineContext->IsFormRender()) {
5178         windowId_ = parentWindowId;
5179     }
5180 
5181     uint32_t windowId = GetWindowId();
5182     auto interactionOperation = std::make_shared<JsInteractionOperation>(windowId);
5183     interactionOperation->SetHandler(WeakClaim(this));
5184     Accessibility::Registration registration {
5185         .windowId = windowId,
5186         .parentWindowId = parentWindowId,
5187         .parentTreeId = parentTreeId,
5188         .elementId = parentElementId,
5189     };
5190     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "windowId: %{public}u, parentWindowId: %{public}u, "
5191                                            "parentTreeId: %{public}d, %{public}" PRId64,
5192                                            windowId, parentWindowId, parentTreeId, parentElementId);
5193     Accessibility::RetError retReg = instance->RegisterElementOperator(registration, interactionOperation);
5194     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "RegisterElementOperator result: %{public}d", retReg);
5195     Register(retReg == RET_OK);
5196     AceApplicationInfo::GetInstance().SetAccessibilityEnabled(retReg == RET_OK);
5197     parentElementId_ = parentElementId;
5198     parentTreeId_ = parentTreeId;
5199     parentWindowId_ = parentWindowId;
5200 
5201     for (auto subContext : GetSubPipelineContexts()) {
5202         auto context = subContext.Upgrade();
5203         CHECK_NULL_VOID(context);
5204         interactionOperation = std::make_shared<JsInteractionOperation>(context->GetWindowId());
5205         interactionOperation->SetHandler(WeakClaim(this));
5206         instance->RegisterElementOperator(context->GetWindowId(), interactionOperation);
5207     }
5208 }
5209 
SetAccessibilityGetParentRectHandler(std::function<void (int32_t &,int32_t &)> && callback)5210 void JsAccessibilityManager::SetAccessibilityGetParentRectHandler(std::function<void(int32_t &, int32_t &)> &&callback)
5211 {
5212     getParentRectHandler_ = std::move(callback);
5213 }
5214 
DeregisterInteractionOperationAsChildTree()5215 void JsAccessibilityManager::DeregisterInteractionOperationAsChildTree()
5216 {
5217     if (!IsRegister()) {
5218         return;
5219     }
5220     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "deregister accessibility childTree");
5221 
5222     std::shared_ptr<AccessibilitySystemAbilityClient> instance = AccessibilitySystemAbilityClient::GetInstance();
5223     CHECK_NULL_VOID(instance);
5224     uint32_t windowId = GetWindowId();
5225     Register(false);
5226     currentFocusNodeId_ = -1;
5227     instance->DeregisterElementOperator(windowId, treeId_);
5228     AceApplicationInfo::GetInstance().SetAccessibilityEnabled(false);
5229     parentElementId_ = INVALID_PARENT_ID;
5230     parentTreeId_ = 0;
5231     parentWindowId_ = 0;
5232     NotifyChildTreeOnDeregister();
5233 
5234     RefPtr<PipelineBase> context;
5235     for (auto subContext : GetSubPipelineContexts()) {
5236         context = subContext.Upgrade();
5237         CHECK_NULL_VOID(context);
5238         instance->DeregisterElementOperator(context->GetWindowId());
5239     }
5240 }
5241 
SendUecOnTreeEvent(int64_t splitElementId)5242 void JsAccessibilityManager::SendUecOnTreeEvent(int64_t splitElementId)
5243 {
5244     auto context = GetPipelineContext().Upgrade();
5245     CHECK_NULL_VOID(context);
5246     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5247     CHECK_NULL_VOID(ngPipeline);
5248     auto rootNode = ngPipeline->GetRootElement();
5249     CHECK_NULL_VOID(rootNode);
5250     auto frameNode = GetFramenodeByAccessibilityId(rootNode, splitElementId);
5251     CHECK_NULL_VOID(frameNode);
5252 
5253     if ((!frameNode) || (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode))) {
5254         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Register element is uec: %{public}s ", frameNode->GetTag().c_str());
5255         rootNode->OnAccessibilityEvent(AccessibilityEventType::CHANGE);
5256     } else {
5257         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "Register element is not uec: %{public}s", frameNode->GetTag().c_str());
5258     }
5259 }
SetChildTreeIdAndWinId(const int64_t nodeId,const int32_t treeId,const int32_t childWindowId)5260 void JsAccessibilityManager::JsInteractionOperation::SetChildTreeIdAndWinId(
5261     const int64_t nodeId, const int32_t treeId, const int32_t childWindowId)
5262 {
5263     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5264     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5265     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(nodeId, splitElementId, splitTreeId);
5266     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetChildTreeId node: %{public}" PRId64 " treeId: %{public}d",
5267         splitElementId, treeId);
5268     auto jsAccessibilityManager = GetHandler().Upgrade();
5269     CHECK_NULL_VOID(jsAccessibilityManager);
5270     jsAccessibilityManager->NotifySetChildTreeIdAndWinId(splitElementId, treeId, childWindowId);
5271 }
5272 
SetBelongTreeId(const int32_t treeId)5273 void JsAccessibilityManager::JsInteractionOperation::SetBelongTreeId(const int32_t treeId)
5274 {
5275     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "SetBelongTreeId treeId: %{public}d", treeId);
5276     auto jsAccessibilityManager = GetHandler().Upgrade();
5277     CHECK_NULL_VOID(jsAccessibilityManager);
5278     jsAccessibilityManager->treeId_ = treeId;
5279     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5280     CHECK_NULL_VOID(context);
5281     context->GetTaskExecutor()->PostTask(
5282         [weak = GetHandler(), treeId] {
5283             auto jsAccessibilityManager = weak.Upgrade();
5284             CHECK_NULL_VOID(jsAccessibilityManager);
5285             ACE_SCOPED_TRACE("SetBelongTreeId");
5286             jsAccessibilityManager->NotifyChildTreeOnRegister(treeId);
5287         },
5288         TaskExecutor::TaskType::UI, "ArkUIAccessibilityClearCurrentFocus");
5289 }
5290 
UpdateElementInfoTreeId(Accessibility::AccessibilityElementInfo & info)5291 void JsAccessibilityManager::UpdateElementInfoTreeId(Accessibility::AccessibilityElementInfo& info)
5292 {
5293     int32_t treeId = info.GetBelongTreeId();
5294     if (treeId <= 0) {
5295         return;
5296     }
5297 
5298     int64_t elementId = info.GetAccessibilityId();
5299     AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId);
5300     info.SetAccessibilityId(elementId);
5301 
5302     int64_t parentId = info.GetParentNodeId();
5303     if (parentId != INVALID_PARENT_ID) {
5304         AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId);
5305         info.SetParent(parentId);
5306     }
5307 
5308     UpdateElementInfoPageIdWithTreeId(info, treeId);
5309 
5310     std::vector<int64_t> childIds = info.GetChildIds();
5311     for (int64_t child : childIds) {
5312         info.RemoveChild(child);
5313         AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, child);
5314         info.AddChild(child);
5315     }
5316 }
5317 
UpdateElementInfosTreeId(std::list<Accessibility::AccessibilityElementInfo> & infos)5318 void JsAccessibilityManager::UpdateElementInfosTreeId(std::list<Accessibility::AccessibilityElementInfo>& infos)
5319 {
5320     for (auto &item : infos) {
5321         int32_t treeId = item.GetBelongTreeId();
5322         if (treeId <= 0) {
5323             continue;
5324         }
5325 
5326         int64_t elementId = item.GetAccessibilityId();
5327         AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId);
5328         item.SetAccessibilityId(elementId);
5329 
5330         int64_t parentId = item.GetParentNodeId();
5331         if (parentId != INVALID_PARENT_ID) {
5332             AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId);
5333             item.SetParent(parentId);
5334         }
5335 
5336         UpdateElementInfoPageIdWithTreeId(item, treeId);
5337 
5338         std::vector<int64_t> childIds = item.GetChildIds();
5339         for (int64_t child : childIds) {
5340             item.RemoveChild(child);
5341             AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, child);
5342             item.AddChild(child);
5343         }
5344     }
5345 }
5346 
SetPipelineContext(const RefPtr<PipelineBase> & context)5347 void JsAccessibilityManager::SetPipelineContext(const RefPtr<PipelineBase>& context)
5348 {
5349     context_ = context;
5350     if (stateObserver_ != nullptr) {
5351         stateObserver_->SetPipeline(context_);
5352     }
5353 }
5354 
OnStateChanged(const bool state)5355 void JsAccessibilityManager::JsAccessibilityStateObserver::OnStateChanged(const bool state)
5356 {
5357     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "accessibility state changed:%{public}d", state);
5358     // Do not upgrade jsAccessibilityManager on async thread, destructor will cause freeze
5359     auto pipelineRef = pipeline_.Upgrade();
5360     CHECK_NULL_VOID(pipelineRef);
5361     pipelineRef->GetTaskExecutor()->PostTask(
5362         [weak = accessibilityManager_, state]() {
5363             auto jsAccessibilityManager = weak.Upgrade();
5364             CHECK_NULL_VOID(jsAccessibilityManager);
5365             if (state) {
5366                 jsAccessibilityManager->RegisterInteractionOperation(jsAccessibilityManager->GetWindowId());
5367             } else {
5368                 jsAccessibilityManager->DeregisterInteractionOperation();
5369             }
5370             AceApplicationInfo::GetInstance().SetAccessibilityEnabled(state);
5371             jsAccessibilityManager->NotifyAccessibilitySAStateChange(state);
5372         },
5373         TaskExecutor::TaskType::UI, "ArkUIAccessibilityStateChanged");
5374 }
5375 
FocusMoveSearch(int64_t elementId,const int32_t direction,const int32_t requestId,AccessibilityElementOperatorCallback & callback)5376 void JsAccessibilityManager::JsInteractionOperation::FocusMoveSearch(
5377     int64_t elementId, const int32_t direction, const int32_t requestId, AccessibilityElementOperatorCallback& callback)
5378 {
5379     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "move search: %{public}" PRId64 ", direction: %{public}d",
5380         elementId, direction);
5381     int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID;
5382     int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID;
5383     AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId);
5384 
5385     auto jsAccessibilityManager = GetHandler().Upgrade();
5386     CHECK_NULL_VOID(jsAccessibilityManager);
5387     auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
5388     CHECK_NULL_VOID(context);
5389     auto windowId = windowId_;
5390     context->GetTaskExecutor()->PostTask(
5391         [weak = GetHandler(), splitElementId, direction, requestId, &callback, windowId] {
5392             auto jsAccessibilityManager = weak.Upgrade();
5393             CHECK_NULL_VOID(jsAccessibilityManager);
5394             ACE_SCOPED_TRACE("FocusMoveSearch");
5395             jsAccessibilityManager->FocusMoveSearch(splitElementId, direction, requestId, callback, windowId);
5396         },
5397         TaskExecutor::TaskType::UI, "ArkUIAccessibilityFocusMoveSearch");
5398 }
5399 
FocusMoveSearch(const int64_t elementId,const int32_t direction,const int32_t requestId,Accessibility::AccessibilityElementOperatorCallback & callback,const int32_t windowId)5400 void JsAccessibilityManager::FocusMoveSearch(const int64_t elementId, const int32_t direction, const int32_t requestId,
5401     Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId)
5402 {
5403     AccessibilityElementInfo nodeInfo;
5404     auto context = GetPipelineByWindowId(windowId);
5405     if (!context) {
5406         nodeInfo.SetValidElement(false);
5407         SetFocusMoveSearchResult(callback, nodeInfo, requestId);
5408         return;
5409     }
5410 
5411     if (AceType::InstanceOf<NG::PipelineContext>(context)) {
5412         FocusMoveSearchNG(elementId, direction, nodeInfo, context, NG::UI_EXTENSION_OFFSET_MAX);
5413         SetFocusMoveSearchResult(callback, nodeInfo, requestId);
5414         return;
5415     }
5416 
5417     auto node = GetAccessibilityNodeFromPage(elementId);
5418     if (!node) {
5419         nodeInfo.SetValidElement(false);
5420         SetFocusMoveSearchResult(callback, nodeInfo, requestId);
5421         return;
5422     }
5423 
5424     // get root node.
5425     auto rootNode = node;
5426     while (rootNode->GetParentNode()) {
5427         rootNode = rootNode->GetParentNode();
5428         if (!rootNode->GetParentNode()) {
5429             break;
5430         }
5431     }
5432 
5433     std::list<RefPtr<AccessibilityNode>> nodeList;
5434     AddFocusableNode(nodeList, rootNode);
5435     RefPtr<AccessibilityNode> resultNode;
5436 
5437     switch (direction) {
5438         case FocusMoveDirection::FORWARD:
5439         case FocusMoveDirection::BACKWARD:
5440             // forward and backward
5441             resultNode = FindNodeInRelativeDirection(nodeList, node, direction);
5442             break;
5443         case FocusMoveDirection::UP:
5444         case FocusMoveDirection::DOWN:
5445         case FocusMoveDirection::LEFT:
5446         case FocusMoveDirection::RIGHT:
5447             // up, down, left and right
5448             resultNode = FindNodeInAbsoluteDirection(nodeList, node, direction);
5449             break;
5450         default:
5451             break;
5452     }
5453 
5454     if (resultNode) {
5455         auto jsAccessibilityManager = Claim(this);
5456         UpdateAccessibilityNodeInfo(resultNode, nodeInfo, jsAccessibilityManager, windowId_);
5457     }
5458 
5459     SetFocusMoveSearchResult(callback, nodeInfo, requestId);
5460 }
5461 
AddFocusableNode(std::list<RefPtr<AccessibilityNode>> & nodeList,const RefPtr<AccessibilityNode> & node)5462 void JsAccessibilityManager::AddFocusableNode(
5463     std::list<RefPtr<AccessibilityNode>>& nodeList, const RefPtr<AccessibilityNode>& node)
5464 {
5465     const std::string importance = node->GetImportantForAccessibility();
5466     if (CanAccessibilityFocused(node)) {
5467         nodeList.push_back(node);
5468     }
5469     if (!node->GetAccessible() && importance != "no-hide-descendants") {
5470         for (auto& child : node->GetChildList()) {
5471             AddFocusableNode(nodeList, child);
5472         }
5473     }
5474 }
5475 
CanAccessibilityFocused(const RefPtr<AccessibilityNode> & node)5476 bool JsAccessibilityManager::CanAccessibilityFocused(const RefPtr<AccessibilityNode>& node)
5477 {
5478     return node != nullptr && !node->IsRootNode() && node->GetVisible() &&
5479            node->GetImportantForAccessibility() != "no" &&
5480            node->GetImportantForAccessibility() != "no-hide-descendants";
5481 }
5482 
FindNodeInRelativeDirection(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node,const int direction)5483 RefPtr<AccessibilityNode> JsAccessibilityManager::FindNodeInRelativeDirection(
5484     const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node, const int direction)
5485 {
5486     switch (direction) {
5487         case FocusMoveDirection::FORWARD:
5488             return GetNextFocusableNode(nodeList, node);
5489         case FocusMoveDirection::BACKWARD:
5490             return GetPreviousFocusableNode(nodeList, node);
5491         default:
5492             break;
5493     }
5494 
5495     return nullptr;
5496 }
5497 
FindNodeInAbsoluteDirection(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node,const int direction)5498 RefPtr<AccessibilityNode> JsAccessibilityManager::FindNodeInAbsoluteDirection(
5499     const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node, const int direction)
5500 {
5501     auto tempBest = node->GetRect();
5502     auto nodeRect = node->GetRect();
5503 
5504     switch (direction) {
5505         case FocusMoveDirection::LEFT:
5506             tempBest.SetLeft(node->GetLeft() + node->GetWidth() + 1);
5507             break;
5508         case FocusMoveDirection::RIGHT:
5509             tempBest.SetLeft(node->GetLeft() - node->GetWidth() - 1);
5510             break;
5511         case FocusMoveDirection::UP:
5512             tempBest.SetTop(node->GetTop() + node->GetHeight() + 1);
5513             break;
5514         case FocusMoveDirection::DOWN:
5515             tempBest.SetTop(node->GetTop() - node->GetHeight() - 1);
5516             break;
5517         default:
5518             break;
5519     }
5520 
5521     RefPtr<AccessibilityNode> nearestNode = nullptr;
5522     for (auto nodeItem = nodeList.begin(); nodeItem != nodeList.end(); nodeItem++) {
5523         if ((*nodeItem)->GetNodeId() == node->GetNodeId() || (*nodeItem)->IsRootNode()) {
5524             continue;
5525         }
5526         auto itemRect = (*nodeItem)->GetRect();
5527         if (CheckBetterRect(nodeRect, direction, itemRect, tempBest)) {
5528             tempBest = itemRect;
5529             nearestNode = (*nodeItem);
5530         }
5531     }
5532 
5533     return nearestNode;
5534 }
5535 
GetNextFocusableNode(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node)5536 RefPtr<AccessibilityNode> JsAccessibilityManager::GetNextFocusableNode(
5537     const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node)
5538 {
5539     auto nodeItem = nodeList.begin();
5540     for (; nodeItem != nodeList.end(); nodeItem++) {
5541         if ((*nodeItem)->GetNodeId() == node->GetNodeId()) {
5542             break;
5543         }
5544     }
5545 
5546     if (nodeItem != nodeList.end() && ++nodeItem != nodeList.end()) {
5547         return (*nodeItem);
5548     }
5549     if (!nodeList.empty()) {
5550         return (*nodeList.begin());
5551     }
5552 
5553     return nullptr;
5554 }
5555 
GetPreviousFocusableNode(const std::list<RefPtr<AccessibilityNode>> & nodeList,RefPtr<AccessibilityNode> & node)5556 RefPtr<AccessibilityNode> JsAccessibilityManager::GetPreviousFocusableNode(
5557     const std::list<RefPtr<AccessibilityNode>>& nodeList, RefPtr<AccessibilityNode>& node)
5558 {
5559     auto nodeItem = nodeList.rbegin();
5560     for (; nodeItem != nodeList.rend(); nodeItem++) {
5561         if ((*nodeItem)->GetNodeId() == node->GetNodeId()) {
5562             break;
5563         }
5564     }
5565 
5566     if (nodeItem != nodeList.rend() && ++nodeItem != nodeList.rend()) {
5567         return (*nodeItem);
5568     }
5569 
5570     if (!nodeList.empty()) {
5571         return (*nodeList.rbegin());
5572     }
5573     return nullptr;
5574 }
5575 
RequestAccessibilityFocus(const RefPtr<AccessibilityNode> & node)5576 bool JsAccessibilityManager::RequestAccessibilityFocus(const RefPtr<AccessibilityNode>& node)
5577 {
5578     auto requestNodeId = node->GetNodeId();
5579     if (currentFocusNodeId_ == requestNodeId) {
5580         return false;
5581     }
5582 
5583     ClearCurrentFocus();
5584     currentFocusNodeId_ = requestNodeId;
5585     node->SetAccessibilityFocusedState(true);
5586     return node->ActionAccessibilityFocus(true);
5587 }
5588 
ClearAccessibilityFocus(const RefPtr<AccessibilityNode> & node)5589 bool JsAccessibilityManager::ClearAccessibilityFocus(const RefPtr<AccessibilityNode>& node)
5590 {
5591     auto requestNodeId = node->GetNodeId();
5592     if (currentFocusNodeId_ != requestNodeId) {
5593         return false;
5594     }
5595 
5596     currentFocusNodeId_ = -1;
5597     node->SetAccessibilityFocusedState(false);
5598     return node->ActionAccessibilityFocus(false);
5599 }
5600 
ClearCurrentFocus()5601 bool JsAccessibilityManager::ClearCurrentFocus()
5602 {
5603     auto currentFocusNode = GetAccessibilityNodeFromPage(currentFocusNodeId_);
5604     CHECK_NULL_RETURN(currentFocusNode, false);
5605     currentFocusNodeId_ = -1;
5606     currentFocusNode->SetFocusedState(false);
5607     currentFocusNode->SetAccessibilityFocusedState(false);
5608     return currentFocusNode->ActionAccessibilityFocus(false);
5609 }
5610 
FocusExtensionElementMoveSearchNG(const SearchParameter & searchParam,const RefPtr<NG::FrameNode> & node,Accessibility::AccessibilityElementInfo & info)5611 void FocusExtensionElementMoveSearchNG(const SearchParameter& searchParam,
5612     const RefPtr<NG::FrameNode>& node, Accessibility::AccessibilityElementInfo& info)
5613 {
5614     if (NG::UI_EXTENSION_OFFSET_MIN < (searchParam.uiExtensionOffset + 1)) {
5615         node->FocusMoveSearchNG(searchParam.nodeId, searchParam.mode,
5616             searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR, info);
5617     } else {
5618         info.SetValidElement(false);
5619     }
5620 }
5621 
GetExtensionNextFocusableNode(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node)5622 void GetExtensionNextFocusableNode(const AccessibilityElementInfo& focusElement,
5623     const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node)
5624 {
5625     auto nodeItem = nodeList.begin();
5626     for (; nodeItem != nodeList.end(); nodeItem++) {
5627         if ((*nodeItem).GetAccessibilityId() == focusElement.GetAccessibilityId()) {
5628             break;
5629         }
5630     }
5631 
5632     if (nodeItem != nodeList.end() && ++nodeItem != nodeList.end()) {
5633         node = (*nodeItem);
5634     }
5635     if (!nodeList.empty()) {
5636         node = (*nodeList.begin());
5637     }
5638 }
5639 
GetExtensionPreviousFocusableNode(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node)5640 void GetExtensionPreviousFocusableNode(const AccessibilityElementInfo& focusElement,
5641     const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node)
5642 {
5643     auto nodeItem = nodeList.rbegin();
5644     for (; nodeItem != nodeList.rend(); nodeItem++) {
5645         if ((*nodeItem).GetAccessibilityId() == focusElement.GetAccessibilityId()) {
5646             break;
5647         }
5648     }
5649 
5650     if (nodeItem != nodeList.rend() && ++nodeItem != nodeList.rend()) {
5651         node = (*nodeItem);
5652     }
5653 
5654     if (!nodeList.empty()) {
5655         node = (*nodeList.rbegin());
5656     }
5657 }
5658 
FindExtensionNodeInAbsoluteDirection(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node,int32_t direction)5659 void FindExtensionNodeInAbsoluteDirection(const AccessibilityElementInfo& focusElement,
5660     const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node, int32_t direction)
5661 {
5662     auto left = focusElement.GetRectInScreen().GetLeftTopXScreenPostion();
5663     auto top = focusElement.GetRectInScreen().GetLeftTopYScreenPostion();
5664     auto width = focusElement.GetRectInScreen().GetRightBottomXScreenPostion() -
5665         focusElement.GetRectInScreen().GetLeftTopXScreenPostion();
5666     auto height = focusElement.GetRectInScreen().GetRightBottomYScreenPostion() -
5667         focusElement.GetRectInScreen().GetLeftTopYScreenPostion();
5668     Rect rect(left, top, width, height);
5669     Rect tempBest(left, top, width, height);
5670     auto nodeRect = tempBest;
5671     switch (direction) {
5672         case FocusMoveDirection::LEFT:
5673             tempBest.SetLeft(left + width + 1);
5674             break;
5675         case FocusMoveDirection::RIGHT:
5676             tempBest.SetLeft(left - width - 1);
5677             break;
5678         case FocusMoveDirection::UP:
5679             tempBest.SetTop(top + height + 1);
5680             break;
5681         case FocusMoveDirection::DOWN:
5682             tempBest.SetTop(top - height - 1);
5683             break;
5684         default:
5685             break;
5686     }
5687     for (const auto& nodeItem : nodeList) {
5688         if (nodeItem.GetAccessibilityId() == focusElement.GetAccessibilityId() ||
5689             V2::ROOT_ETS_TAG == nodeItem.GetComponentType()) {
5690             continue;
5691         }
5692         left = nodeItem.GetRectInScreen().GetLeftTopXScreenPostion();
5693         top = nodeItem.GetRectInScreen().GetLeftTopYScreenPostion();
5694         width = nodeItem.GetRectInScreen().GetRightBottomXScreenPostion() -
5695             nodeItem.GetRectInScreen().GetLeftTopXScreenPostion();
5696         height = nodeItem.GetRectInScreen().GetRightBottomYScreenPostion() -
5697             nodeItem.GetRectInScreen().GetLeftTopYScreenPostion();
5698         Rect itemRect(left, top, width, height);
5699         if (CheckBetterRect(nodeRect, direction, itemRect, tempBest)) {
5700             tempBest = itemRect;
5701             node = nodeItem;
5702         }
5703     }
5704 }
5705 
FindExtensionNodeInRelativeDirection(const AccessibilityElementInfo & focusElement,const std::list<AccessibilityElementInfo> & nodeList,AccessibilityElementInfo & node,int direction)5706 void FindExtensionNodeInRelativeDirection(const AccessibilityElementInfo& focusElement,
5707     const std::list<AccessibilityElementInfo>& nodeList, AccessibilityElementInfo& node, int direction)
5708 {
5709     switch (direction) {
5710         case FocusMoveDirection::FORWARD:
5711             GetExtensionNextFocusableNode(focusElement, nodeList, node);
5712             break;
5713         case FocusMoveDirection::BACKWARD:
5714             GetExtensionPreviousFocusableNode(focusElement, nodeList, node);
5715             break;
5716         default:
5717             break;
5718     }
5719 }
5720 
FilterAccessibilityElementByFocusable(std::list<AccessibilityElementInfo> & elementList,AccessibilityElementInfo & focusElement,int64_t elementId)5721 void FilterAccessibilityElementByFocusable(std::list<AccessibilityElementInfo>& elementList,
5722     AccessibilityElementInfo& focusElement, int64_t elementId)
5723 {
5724     auto input = elementList;
5725     elementList.clear();
5726     std::set<int64_t> filterIds;
5727     for (auto& element : input) {
5728         if (filterIds.find(element.GetParentNodeId()) != filterIds.end()) {
5729             filterIds.insert(element.GetAccessibilityId());
5730             continue;
5731         }
5732         auto width = element.GetRectInScreen().GetRightBottomXScreenPostion() -
5733             element.GetRectInScreen().GetLeftTopXScreenPostion();
5734         auto height = element.GetRectInScreen().GetRightBottomYScreenPostion() -
5735             element.GetRectInScreen().GetLeftTopYScreenPostion();
5736         if (width == 0 || height == 0) {
5737             filterIds.insert(element.GetAccessibilityId());
5738             continue;
5739         }
5740         elementList.emplace_back(element);
5741         if (element.GetAccessibilityId() == elementId) {
5742             focusElement = element;
5743         }
5744     }
5745 }
5746 
GetResultOfFocusMoveSearchNG(int64_t elementId,int32_t direction,AccessibilityElementInfo & info)5747 void JsAccessibilityManager::GetResultOfFocusMoveSearchNG(
5748     int64_t elementId, int32_t direction, AccessibilityElementInfo& info)
5749 {
5750     auto pipeline = context_.Upgrade();
5751     CHECK_NULL_VOID(pipeline);
5752     std::list<AccessibilityElementInfo> nodeList;
5753     SearchElementInfoByAccessibilityIdNG(NG::UI_EXTENSION_ROOT_ID,
5754         PREFETCH_RECURSIVE_CHILDREN, nodeList, pipeline, NG::UI_EXTENSION_OFFSET_MAX);
5755     AccessibilityElementInfo focusElement;
5756     FilterAccessibilityElementByFocusable(nodeList, focusElement, elementId);
5757     switch (direction) {
5758         case FocusMoveDirection::FORWARD:
5759         case FocusMoveDirection::BACKWARD:
5760             Framework::FindExtensionNodeInRelativeDirection(focusElement, nodeList, info, direction);
5761             break;
5762         case FocusMoveDirection::UP:
5763         case FocusMoveDirection::DOWN:
5764         case FocusMoveDirection::LEFT:
5765         case FocusMoveDirection::RIGHT:
5766             Framework::FindExtensionNodeInAbsoluteDirection(focusElement, nodeList, info, direction);
5767             break;
5768         default:
5769             break;
5770     }
5771 }
5772 
FocusMoveSearchNG(int64_t elementId,int32_t direction,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const int64_t uiExtensionOffset)5773 void JsAccessibilityManager::FocusMoveSearchNG(int64_t elementId, int32_t direction,
5774     Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
5775     const int64_t uiExtensionOffset)
5776 {
5777     auto mainContext = context_.Upgrade();
5778     CHECK_NULL_VOID(mainContext);
5779     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5780     CHECK_NULL_VOID(ngPipeline);
5781     auto rootNode = ngPipeline->GetRootElement();
5782     CHECK_NULL_VOID(rootNode);
5783     auto node = GetFramenodeByAccessibilityId(rootNode, elementId);
5784     info.SetValidElement(false);
5785     GetResultOfFocusMoveSearchNG(elementId, direction, info);
5786 }
5787 
FocusExtensionElementMoveSearchNG(const SearchParameter & searchParam,Accessibility::AccessibilityElementInfo & info,const RefPtr<PipelineBase> & context,const RefPtr<NG::FrameNode> & root,RefPtr<NG::FrameNode> & outputExtensionNode)5788 void JsAccessibilityManager::FocusExtensionElementMoveSearchNG(const SearchParameter& searchParam,
5789     Accessibility::AccessibilityElementInfo& info, const RefPtr<PipelineBase>& context,
5790     const RefPtr<NG::FrameNode>& root, RefPtr<NG::FrameNode>& outputExtensionNode)
5791 {
5792 #ifdef WINDOW_SCENE_SUPPORTED
5793     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5794     CHECK_NULL_VOID(ngPipeline);
5795     auto uiExtensionManager = ngPipeline->GetUIExtensionManager();
5796     CHECK_NULL_VOID(uiExtensionManager);
5797     auto elementIdPair =
5798         uiExtensionManager->UnWrapExtensionAbilityId(searchParam.uiExtensionOffset, searchParam.nodeId);
5799     outputExtensionNode = uiExtensionManager->GetFocusUiExtensionNode();
5800     CHECK_NULL_VOID(outputExtensionNode);
5801     SearchParameter transferSearchParam {elementIdPair.second, "",
5802         searchParam.mode, searchParam.uiExtensionOffset};
5803     OHOS::Ace::Framework::FocusExtensionElementMoveSearchNG(transferSearchParam, outputExtensionNode, info);
5804     AccessibilityElementInfo parentInfo;
5805     ConvertExtensionAccessibilityId(info, outputExtensionNode, searchParam.uiExtensionOffset, parentInfo);
5806 #endif
5807 }
5808 
5809 // AccessibilitySystemAbilityClient will release callback after DeregisterElementOperator
SetSearchElementInfoByAccessibilityIdResult(AccessibilityElementOperatorCallback & callback,std::list<AccessibilityElementInfo> && infos,const int32_t requestId)5810 void JsAccessibilityManager::SetSearchElementInfoByAccessibilityIdResult(AccessibilityElementOperatorCallback& callback,
5811     std::list<AccessibilityElementInfo>&& infos, const int32_t requestId)
5812 {
5813     if (!IsRegister()) {
5814         return;
5815     }
5816     auto context = GetPipelineContext().Upgrade();
5817     CHECK_NULL_VOID(context);
5818     context->GetTaskExecutor()->PostTask(
5819         [weak = WeakClaim(this), infos = std::move(infos), &callback, requestId] () mutable {
5820             auto jsAccessibilityManager = weak.Upgrade();
5821             CHECK_NULL_VOID(jsAccessibilityManager);
5822             TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "winId: %{public}d, treeId: %{public}d, reqId: %{public}d",
5823                 jsAccessibilityManager->windowId_, jsAccessibilityManager->treeId_, requestId);
5824             if (!jsAccessibilityManager->IsRegister()) {
5825                 return;
5826             }
5827             jsAccessibilityManager->UpdateElementInfosTreeId(infos);
5828             callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
5829         }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoById");
5830 }
5831 
SetSearchElementInfoByTextResult(AccessibilityElementOperatorCallback & callback,std::list<AccessibilityElementInfo> && infos,const int32_t requestId)5832 void JsAccessibilityManager::SetSearchElementInfoByTextResult(AccessibilityElementOperatorCallback& callback,
5833     std::list<AccessibilityElementInfo>&& infos, const int32_t requestId)
5834 {
5835     if (!IsRegister()) {
5836         return;
5837     }
5838     auto context = GetPipelineContext().Upgrade();
5839     CHECK_NULL_VOID(context);
5840     context->GetTaskExecutor()->PostTask(
5841         [weak = WeakClaim(this), infos = std::move(infos), &callback, requestId] () mutable {
5842             auto jsAccessibilityManager = weak.Upgrade();
5843             CHECK_NULL_VOID(jsAccessibilityManager);
5844             if (!jsAccessibilityManager->IsRegister()) {
5845                 return;
5846             }
5847             jsAccessibilityManager->UpdateElementInfosTreeId(infos);
5848             callback.SetSearchElementInfoByTextResult(infos, requestId);
5849         }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoByText");
5850 }
5851 
SetFindFocusedElementInfoResult(AccessibilityElementOperatorCallback & callback,AccessibilityElementInfo & info,const int32_t requestId)5852 void JsAccessibilityManager::SetFindFocusedElementInfoResult(
5853     AccessibilityElementOperatorCallback& callback, AccessibilityElementInfo& info, const int32_t requestId)
5854 {
5855     if (IsRegister()) {
5856         UpdateElementInfoTreeId(info);
5857         callback.SetFindFocusedElementInfoResult(info, requestId);
5858     }
5859 }
5860 
SetFocusMoveSearchResult(AccessibilityElementOperatorCallback & callback,AccessibilityElementInfo & info,const int32_t requestId)5861 void JsAccessibilityManager::SetFocusMoveSearchResult(
5862     AccessibilityElementOperatorCallback& callback, AccessibilityElementInfo& info, const int32_t requestId)
5863 {
5864     if (IsRegister()) {
5865         UpdateElementInfoTreeId(info);
5866         callback.SetFocusMoveSearchResult(info, requestId);
5867     }
5868 }
5869 
SetExecuteActionResult(AccessibilityElementOperatorCallback & callback,const bool succeeded,const int32_t requestId)5870 void JsAccessibilityManager::SetExecuteActionResult(
5871     AccessibilityElementOperatorCallback& callback, const bool succeeded, const int32_t requestId)
5872 {
5873     if (IsRegister()) {
5874         callback.SetExecuteActionResult(succeeded, requestId);
5875     }
5876 }
5877 
GetPagePath()5878 std::string JsAccessibilityManager::GetPagePath()
5879 {
5880     auto context = context_.Upgrade();
5881     CHECK_NULL_RETURN(context, "");
5882     auto frontend = context->GetFrontend();
5883     CHECK_NULL_RETURN(frontend, "");
5884     ContainerScope scope(context->GetInstanceId());
5885     return frontend->GetPagePath();
5886 }
5887 
GenerateCommonProperty(const RefPtr<PipelineBase> & context,CommonProperty & output,const RefPtr<PipelineBase> & mainContext)5888 void JsAccessibilityManager::GenerateCommonProperty(const RefPtr<PipelineBase>& context, CommonProperty& output,
5889     const RefPtr<PipelineBase>& mainContext)
5890 {
5891     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(context);
5892     CHECK_NULL_VOID(ngPipeline);
5893     auto stageManager = ngPipeline->GetStageManager();
5894     CHECK_NULL_VOID(stageManager);
5895     if (!ngPipeline->IsFormRender()) {
5896         output.windowId = static_cast<int32_t>(ngPipeline->GetRealHostWindowId());
5897     } else {
5898         output.windowId = static_cast<int32_t>(GetWindowId());
5899     }
5900     if (getParentRectHandler_) {
5901         getParentRectHandler_(output.windowTop, output.windowLeft);
5902     } else {
5903         output.windowLeft = GetWindowLeft(ngPipeline->GetWindowId());
5904         output.windowTop = GetWindowTop(ngPipeline->GetWindowId());
5905     }
5906     auto page = stageManager->GetLastPageWithTransition();
5907     if (page != nullptr) {
5908         output.pageId = page->GetPageId();
5909         output.pagePath = GetPagePath();
5910     }
5911     if (context->GetWindowId() != mainContext->GetWindowId()) {
5912         output.pageId = 0;
5913         output.pagePath = "";
5914     }
5915 }
5916 
FindText(const RefPtr<NG::UINode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<NG::PipelineContext> & context,const CommonProperty & commonProperty,const SearchParameter & searchParam)5917 void JsAccessibilityManager::FindText(const RefPtr<NG::UINode>& node,
5918     std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<NG::PipelineContext>& context,
5919     const CommonProperty& commonProperty, const SearchParameter& searchParam)
5920 {
5921     CHECK_NULL_VOID(node);
5922     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
5923     if (frameNode && !frameNode->IsInternal()) {
5924         if (frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetGroupText().find(
5925             searchParam.text) != std::string::npos) {
5926             AccessibilityElementInfo nodeInfo;
5927             UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
5928             infos.emplace_back(nodeInfo);
5929         }
5930     }
5931     if (IsExtensionComponent(frameNode) && !IsUIExtensionShowPlaceholder(frameNode)) {
5932         auto infosByIPC = SearchElementInfosByTextNG(NG::UI_EXTENSION_ROOT_ID, searchParam.text,
5933             frameNode, searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
5934         if (!infosByIPC.empty()) {
5935             AccessibilityElementInfo nodeInfo;
5936             UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
5937             ConvertExtensionAccessibilityNodeId(infosByIPC, frameNode, searchParam.uiExtensionOffset, nodeInfo);
5938             for (auto& info : infosByIPC) {
5939                 infos.emplace_back(info);
5940             }
5941         }
5942     }
5943     if (!node->GetChildren(true).empty()) {
5944         for (const auto& child : node->GetChildren(true)) {
5945             FindText(child, infos, context, commonProperty, searchParam);
5946         }
5947     }
5948 }
5949 
FindTextByTextHint(const RefPtr<NG::UINode> & node,std::list<Accessibility::AccessibilityElementInfo> & infos,const RefPtr<NG::PipelineContext> & context,const CommonProperty & commonProperty,const SearchParameter & searchParam)5950 void JsAccessibilityManager::FindTextByTextHint(const RefPtr<NG::UINode>& node,
5951     std::list<Accessibility::AccessibilityElementInfo>& infos, const RefPtr<NG::PipelineContext>& context,
5952     const CommonProperty& commonProperty, const SearchParameter& searchParam)
5953 {
5954     CHECK_NULL_VOID(node);
5955     auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
5956     if (frameNode && !frameNode->IsInternal()) {
5957         std::string text = searchParam.text;
5958         nlohmann::json textJson = nlohmann::json::parse(text, nullptr, false);
5959         std::string value = "";
5960         if (!textJson.is_null() && !textJson.is_discarded() && textJson.contains("value")) {
5961             value = textJson["value"];
5962         }
5963         std::string textType = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetTextType();
5964         nlohmann::json textTypeJson = nlohmann::json::parse(textType, nullptr, false);
5965         if (!textTypeJson.is_null() && !textTypeJson.is_discarded() &&
5966             textTypeJson.contains("type") && textTypeJson["type"] == value) {
5967             AccessibilityElementInfo nodeInfo;
5968             UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
5969             infos.emplace_back(nodeInfo);
5970         }
5971     }
5972     if (IsIsolatedComponent(frameNode)) {
5973         auto infosByIPC = SearchElementInfosByTextNG(NG::UI_EXTENSION_ROOT_ID, searchParam.text,
5974             frameNode, searchParam.uiExtensionOffset / NG::UI_EXTENSION_ID_FACTOR);
5975         if (!infosByIPC.empty()) {
5976             AccessibilityElementInfo nodeInfo;
5977             UpdateAccessibilityElementInfo(frameNode, commonProperty, nodeInfo, context);
5978             ConvertExtensionAccessibilityNodeId(infosByIPC, frameNode, searchParam.uiExtensionOffset, nodeInfo);
5979             for (auto& info : infosByIPC) {
5980                 infos.emplace_back(info);
5981             }
5982         }
5983     }
5984     if (!node->GetChildren(true).empty()) {
5985         for (const auto& child : node->GetChildren(true)) {
5986             FindTextByTextHint(child, infos, context, commonProperty, searchParam);
5987         }
5988     }
5989 }
5990 
TransferThirdProviderHoverEvent(const WeakPtr<NG::FrameNode> & hostNode,const NG::PointF & point,SourceType source,NG::AccessibilityHoverEventType eventType,TimeStamp time)5991 void JsAccessibilityManager::TransferThirdProviderHoverEvent(
5992     const WeakPtr<NG::FrameNode>& hostNode, const NG::PointF& point, SourceType source,
5993     NG::AccessibilityHoverEventType eventType, TimeStamp time)
5994 {
5995     auto pipelineContext = GetPipelineContext().Upgrade();
5996     CHECK_NULL_VOID(pipelineContext);
5997     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
5998     CHECK_NULL_VOID(ngPipeline);
5999     auto frameNode = hostNode.Upgrade();
6000     CHECK_NULL_VOID(frameNode);
6001     AccessibilityHoverForThirdConfig config;
6002     config.hostElementId = frameNode->GetAccessibilityId();
6003     config.point = point;
6004     config.sourceType = source;
6005     config.eventType = eventType;
6006     config.time = time;
6007     config.hostNode = frameNode;
6008     config.context = ngPipeline;
6009     HandleAccessibilityHoverForThird(config);
6010 }
6011 
OnDumpChildInfoForThird(int64_t hostElementId,const std::vector<std::string> & params,std::vector<std::string> & info)6012 bool JsAccessibilityManager::OnDumpChildInfoForThird(
6013     int64_t hostElementId,
6014     const std::vector<std::string>& params,
6015     std::vector<std::string>& info)
6016 {
6017     return OnDumpChildInfoForThirdRecursive(hostElementId, params, info, WeakClaim(this));
6018 }
6019 
6020 #ifdef WEB_SUPPORTED
GetWebCursorPosition(const int64_t elementId,const int32_t requestId,AccessibilityElementOperatorCallback & callback,const RefPtr<NG::WebPattern> & webPattern)6021 void JsAccessibilityManager::GetWebCursorPosition(const int64_t elementId, const int32_t requestId,
6022     AccessibilityElementOperatorCallback& callback, const RefPtr<NG::WebPattern>& webPattern)
6023 {
6024     CHECK_NULL_VOID(webPattern);
6025     auto node = webPattern->GetAccessibilityNodeById(elementId);
6026     CHECK_NULL_VOID(node);
6027 
6028     callback.SetCursorPositionResult(node->GetSelectionStart(), requestId);
6029 }
6030 #endif // WEB_SUPPORTED
6031 
FireAccessibilityEventCallback(uint32_t eventId,int64_t parameter)6032 void JsAccessibilityManager::FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter)
6033 {
6034     auto eventType = static_cast<AccessibilityCallbackEventId>(eventId);
6035     AccessibilityEvent event;
6036     switch (eventType) {
6037         case AccessibilityCallbackEventId::ON_LOAD_PAGE:
6038             event.nodeId = parameter;
6039             event.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
6040             event.type = AccessibilityEventType::CHANGE;
6041             SendAccessibilityAsyncEvent(event);
6042             break;
6043         case AccessibilityCallbackEventId::ON_SEND_ELEMENT_INFO_CHANGE:
6044             event.type = AccessibilityEventType::ELEMENT_INFO_CHANGE;
6045             event.nodeId = parameter;
6046             SendAccessibilityAsyncEvent(event);
6047             break;
6048         default:
6049             break;
6050     }
6051 }
6052 } // namespace OHOS::Ace::Framework
6053