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