diff --git a/adapter/ohos/osal/BUILD.gn b/adapter/ohos/osal/BUILD.gn index e1a561fc3580d1b8df93f40a10e1b0c42a4ed5ce..8ba4b13e918af39dcfa78e50b2478b7824cb7231 100644 --- a/adapter/ohos/osal/BUILD.gn +++ b/adapter/ohos/osal/BUILD.gn @@ -155,6 +155,7 @@ template("ace_osal_ohos_source_set") { if (defined(config.accessibility_support) && config.accessibility_support) { sources += [ + "accessibility/accessibility_hidumper_osal.cpp", "js_accessibility_manager.cpp", "js_third_accessibility_hover_ng.cpp", "js_third_provider_interaction_operation.cpp", diff --git a/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.cpp b/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.cpp new file mode 100644 index 0000000000000000000000000000000000000000..521e4ac150dcf6c12278fa09b6460b24bc3fa336 --- /dev/null +++ b/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "accessibility_system_ability_client.h" + +#include "adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h" +#include "base/log/dump_log.h" +#include "core/accessibility/accessibility_utils.h" + +using namespace OHOS::Accessibility; +using namespace OHOS::AccessibilityConfig; + +namespace OHOS::Ace::Framework { + +namespace { +const std::string ACTION_DEFAULT_PARAM = "ACCESSIBILITY_ACTION_INVALID"; + +inline std::string BoolToString(bool tag) +{ + return tag ? "true" : "false"; +} + +std::string ConvertInputTypeToString(AceTextCategory type) +{ + switch (type) { + case AceTextCategory::INPUT_TYPE_DEFAULT: + return "INPUT_TYPE_DEFAULT"; + case AceTextCategory::INPUT_TYPE_TEXT: + return "INPUT_TYPE_TEXT"; + case AceTextCategory::INPUT_TYPE_EMAIL: + return "INPUT_TYPE_EMAIL"; + case AceTextCategory::INPUT_TYPE_DATE: + return "INPUT_TYPE_DATE"; + case AceTextCategory::INPUT_TYPE_TIME: + return "INPUT_TYPE_TIME"; + case AceTextCategory::INPUT_TYPE_NUMBER: + return "INPUT_TYPE_NUMBER"; + case AceTextCategory::INPUT_TYPE_PASSWORD: + return "INPUT_TYPE_PASSWORD"; + case AceTextCategory::INPUT_TYPE_PHONENUMBER: + return "INPUT_TYPE_PHONENUMBER"; + case AceTextCategory::INPUT_TYPE_USER_NAME: + return "INPUT_TYPE_USER_NAME"; + case AceTextCategory::INPUT_TYPE_NEW_PASSWORD: + return "INPUT_TYPE_NEW_PASSWORD"; + default: + return "illegal input type"; + } +} + +inline void DumpGridInfoNG(const AccessibilityElementInfo& nodeInfo) +{ + DumpLog::GetInstance().AddDesc("grid info rows: ", nodeInfo.GetGrid().GetRowCount()); + DumpLog::GetInstance().AddDesc("grid info columns: ", nodeInfo.GetGrid().GetColumnCount()); + DumpLog::GetInstance().AddDesc("grid info select mode: ", nodeInfo.GetGrid().GetSelectionMode()); + DumpLog::GetInstance().AddDesc("grid item info, row: ", nodeInfo.GetGridItem().GetRowIndex()); + DumpLog::GetInstance().AddDesc("grid item info, column: ", nodeInfo.GetGridItem().GetColumnIndex()); + DumpLog::GetInstance().AddDesc("grid item info, rowSpan: ", nodeInfo.GetGridItem().GetRowSpan()); + DumpLog::GetInstance().AddDesc("grid item info, columnSpan: ", nodeInfo.GetGridItem().GetColumnSpan()); + DumpLog::GetInstance().AddDesc("grid item info, is heading: ", nodeInfo.GetGridItem().IsHeading()); + DumpLog::GetInstance().AddDesc("grid item info, selected: ", nodeInfo.GetGridItem().IsSelected()); +} + +void DumpExtraElementInfoNG(const AccessibilityElementInfo& nodeInfo) +{ + ExtraElementInfo extraElementInfo = nodeInfo.GetExtraElement(); + if (!extraElementInfo.GetExtraElementInfoValueStr().empty()) { + for (auto i = extraElementInfo.GetExtraElementInfoValueStr().begin(); + i != extraElementInfo.GetExtraElementInfoValueStr().end(); ++i) { + DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second); + } + } + if (!extraElementInfo.GetExtraElementInfoValueInt().empty()) { + for (auto i = extraElementInfo.GetExtraElementInfoValueInt().begin(); + i != extraElementInfo.GetExtraElementInfoValueInt().end(); ++i) { + DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second); + } + } +} + +void UpdateSpanList(std::vector& spansInfosList, std::string& spans) +{ + for (const auto& span : spansInfosList) { + if (!spans.empty()) { + spans.append(","); + } + spans.append("\n\t span id: "); + spans.append(std::to_string(span.GetSpanId())); + spans.append(", span text: "); + spans.append(span.GetSpanText()); + spans.append(", accessibility text: "); + spans.append(span.GetAccessibilityText()); + spans.append(", accessibility description: "); + spans.append(span.GetAccessibilityDescription()); + spans.append(", accessibility level: "); + spans.append(span.GetAccessibilityLevel()); + } +} + +inline void DumpSpanListNG(const AccessibilityElementInfo& nodeInfo) +{ + std::string spans; + std::vector spansInfosList = nodeInfo.GetSpanList(); + std::size_t spanCount = spansInfosList.size(); + UpdateSpanList(spansInfosList, spans); + DumpLog::GetInstance().AddDesc("span list count: ", static_cast(spanCount)); + DumpLog::GetInstance().AddDesc("span list: ", spans); +} + +void DumpSupportActionNG(const AccessibilityElementInfo& nodeInfo) +{ + DumpLog::GetInstance().AddDesc( + "support action instructions: use command to make application components perform corresponding action"); + DumpLog::GetInstance().AddDesc( + "use support action command: aa dump -i [AbilityRecord] -c -inspector [AccessibilityId] [AceAction]"); + std::string actionForDump; + for (const auto& action : nodeInfo.GetActionList()) { + if (!actionForDump.empty()) { + actionForDump.append(","); + } + actionForDump.append(AccessibilityManagerHidumper::ConvertActionTypeToString(action.GetActionType())); + actionForDump.append(": "); + actionForDump.append( + std::to_string( + static_cast( + AccessibilityManagerHidumper::ConvertAccessibilityAction(action.GetActionType())))); + } + DumpLog::GetInstance().AddDesc("support action: ", actionForDump); +} + +inline void DumpContentListNG(const AccessibilityElementInfo& nodeInfo) +{ + std::vector contentList; + nodeInfo.GetContentList(contentList); + std::string contents; + for (const auto& content : contentList) { + if (!contents.empty()) { + contents.append(","); + } + contents.append(content); + } + DumpLog::GetInstance().AddDesc("content list: ", contents); +} + +inline std::string ChildrenToString(const std::vector& children, int32_t treeId) +{ + std::string ids; + for (auto child : children) { + if (!ids.empty()) { + ids.append(","); + } + int64_t childId = child; + AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, childId); + ids.append(std::to_string(childId)); + } + return ids; +} + +inline void DumpRectNG(const Accessibility::Rect& rect) +{ + DumpLog::GetInstance().AddDesc( + "width: ", std::to_string(rect.GetRightBottomXScreenPostion() - rect.GetLeftTopXScreenPostion())); + DumpLog::GetInstance().AddDesc( + "height: ", std::to_string(rect.GetRightBottomYScreenPostion() - rect.GetLeftTopYScreenPostion())); + DumpLog::GetInstance().AddDesc("left: ", std::to_string(rect.GetLeftTopXScreenPostion())); + DumpLog::GetInstance().AddDesc("top: ", std::to_string(rect.GetLeftTopYScreenPostion())); + DumpLog::GetInstance().AddDesc("right: ", std::to_string(rect.GetRightBottomXScreenPostion())); + DumpLog::GetInstance().AddDesc("bottom: ", std::to_string(rect.GetRightBottomYScreenPostion())); +} + +inline void DumpRange(const AccessibilityElementInfo& nodeInfo) +{ + DumpLog::GetInstance().AddDesc("min value: ", nodeInfo.GetRange().GetMin()); + DumpLog::GetInstance().AddDesc("max value: ", nodeInfo.GetRange().GetMax()); + DumpLog::GetInstance().AddDesc("current value: ", nodeInfo.GetRange().GetCurrent()); +} + +inline void DumpIndex(const AccessibilityElementInfo& nodeInfo) +{ + DumpLog::GetInstance().AddDesc("current index: ", nodeInfo.GetCurrentIndex()); + DumpLog::GetInstance().AddDesc("begin index: ", nodeInfo.GetBeginIndex()); + DumpLog::GetInstance().AddDesc("end index: ", nodeInfo.GetEndIndex()); +} +} // namespace + + +void AccessibilityElementInfoUtils::ToKeyInfo( + const Accessibility::AccessibilityElementInfo& nodeInfo, + int32_t treeId) +{ +} + +void AccessibilityElementInfoUtils::ToCommonInfo( + const Accessibility::AccessibilityElementInfo& nodeInfo, + int32_t treeId) +{ + int64_t elementId = nodeInfo.GetAccessibilityId(); + AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId); + DumpLog::GetInstance().AddDesc("ID: ", elementId); + DumpLog::GetInstance().AddDesc("UniqueID: ", nodeInfo.GetUniqueId()); + int64_t parentId = nodeInfo.GetParentNodeId(); + AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId); + DumpLog::GetInstance().AddDesc("parent ID: ", parentId); + DumpLog::GetInstance().AddDesc("child IDs: ", ChildrenToString(nodeInfo.GetChildIds(), treeId)); + DumpLog::GetInstance().AddDesc("component type: ", nodeInfo.GetComponentType()); + DumpLog::GetInstance().AddDesc("accessibilityCustomRole: " + nodeInfo.GetCustomComponentType()); + DumpLog::GetInstance().AddDesc("text: ", nodeInfo.GetContent()); + DumpLog::GetInstance().AddDesc("originText: ", nodeInfo.GetOriginalText()); + DumpLog::GetInstance().AddDesc("window id: " + std::to_string(nodeInfo.GetWindowId())); + DumpRectNG(nodeInfo.GetRectInScreen()); + + DumpLog::GetInstance().AddDesc("enabled: ", BoolToString(nodeInfo.IsEnabled())); + DumpLog::GetInstance().AddDesc("focusable: ", BoolToString(nodeInfo.IsFocusable())); + DumpLog::GetInstance().AddDesc("focused: ", BoolToString(nodeInfo.IsFocused())); + DumpLog::GetInstance().AddDesc("visible: ", BoolToString(nodeInfo.IsVisible())); + DumpLog::GetInstance().AddDesc("accessibility focused: ", BoolToString(nodeInfo.HasAccessibilityFocus())); + DumpLog::GetInstance().AddDesc("accessibilityText: " + nodeInfo.GetAccessibilityText()); + DumpLog::GetInstance().AddDesc("accessibilityGroup: " + BoolToString(nodeInfo.GetAccessibilityGroup())); + DumpLog::GetInstance().AddDesc("accessibilityLevel: " + nodeInfo.GetAccessibilityLevel()); + DumpLog::GetInstance().AddDesc("accessibilityDescription: " + nodeInfo.GetDescriptionInfo()); + DumpLog::GetInstance().AddDesc("hitTestBehavior: " + nodeInfo.GetHitTestBehavior()); + + DumpLog::GetInstance().AddDesc("inspector key: ", nodeInfo.GetInspectorKey()); + DumpLog::GetInstance().AddDesc("bundle name: ", nodeInfo.GetBundleName()); + DumpLog::GetInstance().AddDesc("page id: " + std::to_string(nodeInfo.GetPageId())); + DumpLog::GetInstance().AddDesc("page path: ", nodeInfo.GetPagePath()); + DumpLog::GetInstance().AddDesc("is valid element: ", BoolToString(nodeInfo.IsValidElement())); + DumpLog::GetInstance().AddDesc("resource name: ", nodeInfo.GetComponentResourceId()); + + DumpLog::GetInstance().AddDesc("clickable: ", BoolToString(nodeInfo.IsClickable())); + DumpLog::GetInstance().AddDesc("long clickable: ", BoolToString(nodeInfo.IsLongClickable())); + DumpLog::GetInstance().AddDesc("popup supported: ", BoolToString(nodeInfo.IsPopupSupported())); + DumpLog::GetInstance().AddDesc("zindex: ", std::to_string(nodeInfo.GetZIndex())); +} + +void AccessibilityElementInfoUtils::ToDetailInfo( + const Accessibility::AccessibilityElementInfo& nodeInfo, + int32_t treeId) +{ + DumpLog::GetInstance().AddDesc("checked: ", BoolToString(nodeInfo.IsChecked())); + DumpLog::GetInstance().AddDesc("selected: ", BoolToString(nodeInfo.IsSelected())); + DumpLog::GetInstance().AddDesc("checkable: ", BoolToString(nodeInfo.IsCheckable())); + DumpLog::GetInstance().AddDesc("scrollable: ", BoolToString(nodeInfo.IsScrollable())); + DumpLog::GetInstance().AddDesc("accessibility hint: ", BoolToString(nodeInfo.IsGivingHint())); + DumpLog::GetInstance().AddDesc("hint text: ", nodeInfo.GetHint()); + DumpLog::GetInstance().AddDesc("error text: ", nodeInfo.GetError()); + DumpLog::GetInstance().AddDesc("max text length: ", nodeInfo.GetTextLengthLimit()); + DumpLog::GetInstance().AddDesc("scroll offset: ", nodeInfo.GetOffset()); + DumpLog::GetInstance().AddDesc("text selection start: ", nodeInfo.GetSelectedBegin()); + DumpLog::GetInstance().AddDesc("text selection end: ", nodeInfo.GetSelectedEnd()); + DumpLog::GetInstance().AddDesc("is multi line: ", BoolToString(nodeInfo.IsPluraLineSupported())); + DumpLog::GetInstance().AddDesc("is password: ", BoolToString(nodeInfo.IsPassword())); + DumpLog::GetInstance().AddDesc( + "text input type: ", ConvertInputTypeToString(static_cast(nodeInfo.GetInputType()))); + DumpGridInfoNG(nodeInfo); + DumpRange(nodeInfo); + DumpIndex(nodeInfo); + DumpLog::GetInstance().AddDesc("collection item counts: ", nodeInfo.GetItemCounts()); + DumpLog::GetInstance().AddDesc("editable: ", BoolToString(nodeInfo.IsEditable())); + DumpLog::GetInstance().AddDesc("is essential: ", BoolToString(nodeInfo.IsEssential())); + DumpLog::GetInstance().AddDesc("deletable: ", nodeInfo.IsDeletable()); + DumpLog::GetInstance().AddDesc("live region: ", nodeInfo.GetLiveRegion()); + DumpLog::GetInstance().AddDesc("content description: ", nodeInfo.GetDescriptionInfo()); + DumpLog::GetInstance().AddDesc("content invalid: ", BoolToString(nodeInfo.GetContentInvalid())); + DumpLog::GetInstance().AddDesc("accessibility label: ", nodeInfo.GetLabeledAccessibilityId()); + DumpLog::GetInstance().AddDesc("isActive: ", nodeInfo.GetIsActive()); + DumpLog::GetInstance().AddDesc("accessibilityVisible: ", nodeInfo.GetAccessibilityVisible()); + DumpLog::GetInstance().AddDesc("accessibilityNextFocusInspectorKey: ", + nodeInfo.GetAccessibilityNextFocusInspectorKey()); + DumpLog::GetInstance().AddDesc("accessibilityScrollTriggerable: ", + nodeInfo.GetAccessibilityScrollable()); + DumpLog::GetInstance().AddDesc("accessibilityNextFocusId: ", nodeInfo.GetAccessibilityNextFocusId()); + DumpLog::GetInstance().AddDesc("accessibilityPreviousFocusId: ", nodeInfo.GetAccessibilityPreviousFocusId()); + DumpLog::GetInstance().AddDesc("clip: ", nodeInfo.GetClip()); + DumpExtraElementInfoNG(nodeInfo); + DumpLog::GetInstance().AddDesc( + "trigger action: ", + static_cast(AccessibilityManagerHidumper::ConvertAccessibilityAction(nodeInfo.GetTriggerAction()))); + DumpLog::GetInstance().AddDesc("text move step: " + std::to_string(nodeInfo.GetTextMovementStep())); + DumpSpanListNG(nodeInfo); + DumpSupportActionNG(nodeInfo); + DumpContentListNG(nodeInfo); + DumpLog::GetInstance().AddDesc("latest content: ", nodeInfo.GetLatestContent()); +} + +AceAction AccessibilityManagerHidumper::ConvertAccessibilityAction(ActionType accessibilityAction) +{ + static const std::unordered_map actionTypeTransMap = { + { ActionType::ACCESSIBILITY_ACTION_CLICK, AceAction::ACTION_CLICK }, + { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, AceAction::ACTION_LONG_CLICK }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, AceAction::ACTION_SCROLL_FORWARD }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, AceAction::ACTION_SCROLL_BACKWARD }, + { ActionType::ACCESSIBILITY_ACTION_FOCUS, AceAction::ACTION_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, AceAction::ACTION_CLEAR_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, AceAction::ACTION_ACCESSIBILITY_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY }, + { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, AceAction::ACTION_SET_TEXT }, + { ActionType::ACCESSIBILITY_ACTION_COPY, AceAction::ACTION_COPY }, + { ActionType::ACCESSIBILITY_ACTION_PASTE, AceAction::ACTION_PASTE }, + { ActionType::ACCESSIBILITY_ACTION_CUT, AceAction::ACTION_CUT }, + { ActionType::ACCESSIBILITY_ACTION_SELECT, AceAction::ACTION_SELECT }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, AceAction::ACTION_CLEAR_SELECTION }, + { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, AceAction::ACTION_SET_SELECTION }, + { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, AceAction::ACTION_SET_CURSOR_POSITION }, + { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, AceAction::ACTION_EXEC_SUB_COMPONENT }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM, AceAction::ACTION_NEXT_HTML_ITEM }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM, AceAction::ACTION_PREVIOUS_HTML_ITEM }, + }; + + if (auto it = actionTypeTransMap.find(accessibilityAction); it != actionTypeTransMap.end()) { + return it->second; + } + return AceAction::ACTION_NONE; +} + +std::string AccessibilityManagerHidumper::ConvertActionTypeToString(ActionType action) +{ + static const std::unordered_map actionTypeTransStrMap = { + { ActionType::ACCESSIBILITY_ACTION_FOCUS, "ACCESSIBILITY_ACTION_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ACCESSIBILITY_ACTION_CLEAR_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_SELECT, "ACCESSIBILITY_ACTION_SELECT" }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, "ACCESSIBILITY_ACTION_CLEAR_SELECTION" }, + { ActionType::ACCESSIBILITY_ACTION_CLICK, "ACCESSIBILITY_ACTION_CLICK" }, + { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, "ACCESSIBILITY_ACTION_LONG_CLICK" }, + { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, "ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, + "ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, "ACCESSIBILITY_ACTION_SCROLL_FORWARD" }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, "ACCESSIBILITY_ACTION_SCROLL_BACKWARD" }, + { ActionType::ACCESSIBILITY_ACTION_COPY, "ACCESSIBILITY_ACTION_COPY" }, + { ActionType::ACCESSIBILITY_ACTION_PASTE, "ACCESSIBILITY_ACTION_PASTE" }, + { ActionType::ACCESSIBILITY_ACTION_CUT, "ACCESSIBILITY_ACTION_CUT" }, + { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, "ACCESSIBILITY_ACTION_SET_SELECTION" }, + { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, "ACCESSIBILITY_ACTION_SET_TEXT" }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, "ACCESSIBILITY_ACTION_NEXT_TEXT" }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, "ACCESSIBILITY_ACTION_PREVIOUS_TEXT" }, + { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, "ACCESSIBILITY_ACTION_SET_CURSOR_POSITION" }, + { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, "ACCESSIBILITY_ACTION_SPAN_CLICK" }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM, "ACCESSIBILITY_ACTION_NEXT_HTML_ITEM" }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM, "ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM" } + }; + + if (auto it = actionTypeTransStrMap.find(action); it != actionTypeTransStrMap.end()) { + return it->second; + } + return ACTION_DEFAULT_PARAM; +} +} // namespace OHOS::Ace::Framework diff --git a/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h b/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h new file mode 100644 index 0000000000000000000000000000000000000000..edeb7f52768a606681e0dc64e0272f593baa8faa --- /dev/null +++ b/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef FOUNDATION_ACE_ADAPTER_OHOS_OSAL_ACCESSIBILITY_ACCESSIBILITY_HIDUMPER_OSAL_H +#define FOUNDATION_ACE_ADAPTER_OHOS_OSAL_ACCESSIBILITY_ACCESSIBILITY_HIDUMPER_OSAL_H + +#include +#include "accessibility_element_info.h" + +#include "core/accessibility/accessibility_utils.h" + +namespace OHOS::Accessibility { + class AccessibilityElementInfo; +} + +namespace OHOS::Ace::Framework { +struct ActionTable { + AceAction aceAction; + Accessibility::ActionType action; +}; + +using ToInfoFunc = std::function; + +struct ActionStrTable { + Accessibility::ActionType action; + std::string actionStr; +}; + +enum class ToInfoMode { + TO_STRING, + DUMPLOG_ADD, +}; + +class AccessibilityElementInfoUtils { +public: + AccessibilityElementInfoUtils() = default; + ~AccessibilityElementInfoUtils() = default; + + static void ToKeyInfo( + const Accessibility::AccessibilityElementInfo& accessibilityElementInfo, + int32_t treeId); + static void ToCommonInfo( + const Accessibility::AccessibilityElementInfo& accessibilityElementInfo, + int32_t treeId); + static void ToDetailInfo( + const Accessibility::AccessibilityElementInfo& accessibilityElementInfo, + int32_t treeId); +}; + +class AccessibilityManagerHidumper { +public: + AccessibilityManagerHidumper() = default; + ~AccessibilityManagerHidumper() = default; + + static AceAction ConvertAccessibilityAction(Accessibility::ActionType accessibilityAction); + static std::string ConvertActionTypeToString(Accessibility::ActionType action); +}; +} // OHOS::Ace::Framework +#endif // FOUNDATION_ACE_ADAPTER_OHOS_OSAL_ACCESSIBILITY_ACCESSIBILITY_HIDUMPER_OSAL_H \ No newline at end of file diff --git a/adapter/ohos/osal/js_accessibility_manager.cpp b/adapter/ohos/osal/js_accessibility_manager.cpp index 4aca3dc74b573f339bb5f3a4c9a54feb171a6fac..f3ecfe9afd5aa8314bfc15e10c86f18c86035714 100644 --- a/adapter/ohos/osal/js_accessibility_manager.cpp +++ b/adapter/ohos/osal/js_accessibility_manager.cpp @@ -19,10 +19,12 @@ #include "js_third_provider_interaction_operation.h" #include "perf_monitor_adapter.h" +#include "adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h" #include "adapter/ohos/entrance/ace_container.h" #include "base/log/event_report.h" #include "core/components_ng/pattern/scrollable/scrollable_utils.h" #include "core/components_ng/base/frame_node.h" +#include "frameworks/core/accessibility/hidumper/accessibility_hidumper.h" #include "frameworks/core/accessibility/utils/accessibility_action_function_utils.h" #include "frameworks/core/components_ng/pattern/ui_extension/platform_container_handler.h" #include "frameworks/core/components_ng/pattern/overlay/accessibility_focus_paint_node_pattern.h" @@ -63,7 +65,6 @@ constexpr size_t MIN_PARAMS_SIZE = 2; constexpr int64_t INVALID_NODE_ID = -1; const std::string ACTION_ARGU_SCROLL_STUB = "scrolltype"; // wait for change -const std::string ACTION_DEFAULT_PARAM = "ACCESSIBILITY_ACTION_INVALID"; const std::set TAGS_EMBED_COMPONENT = { "embeddedObject", @@ -2752,190 +2753,6 @@ inline std::string GetSupportAction(const std::unordered_set& support return actionForDump; } -static std::string ConvertActionTypeToString(ActionType action) -{ - static const ActionStrTable actionStrTable[] = { - { ActionType::ACCESSIBILITY_ACTION_FOCUS, "ACCESSIBILITY_ACTION_FOCUS" }, - { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ACCESSIBILITY_ACTION_CLEAR_FOCUS" }, - { ActionType::ACCESSIBILITY_ACTION_SELECT, "ACCESSIBILITY_ACTION_SELECT" }, - { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, "ACCESSIBILITY_ACTION_CLEAR_SELECTION" }, - { ActionType::ACCESSIBILITY_ACTION_CLICK, "ACCESSIBILITY_ACTION_CLICK" }, - { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, "ACCESSIBILITY_ACTION_LONG_CLICK" }, - { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, "ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS" }, - { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, - "ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS" }, - { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, "ACCESSIBILITY_ACTION_SCROLL_FORWARD" }, - { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, "ACCESSIBILITY_ACTION_SCROLL_BACKWARD" }, - { ActionType::ACCESSIBILITY_ACTION_COPY, "ACCESSIBILITY_ACTION_COPY" }, - { ActionType::ACCESSIBILITY_ACTION_PASTE, "ACCESSIBILITY_ACTION_PASTE" }, - { ActionType::ACCESSIBILITY_ACTION_CUT, "ACCESSIBILITY_ACTION_CUT" }, - { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, "ACCESSIBILITY_ACTION_SET_SELECTION" }, - { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, "ACCESSIBILITY_ACTION_SET_TEXT" }, - { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, "ACCESSIBILITY_ACTION_NEXT_TEXT" }, - { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, "ACCESSIBILITY_ACTION_PREVIOUS_TEXT" }, - { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, "ACCESSIBILITY_ACTION_SET_CURSOR_POSITION" }, - { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, "ACCESSIBILITY_ACTION_SPAN_CLICK" }, - { ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM, "ACCESSIBILITY_ACTION_NEXT_HTML_ITEM" }, - { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM, "ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM" }, - }; - for (const auto& item : actionStrTable) { - if (action == item.action) { - return item.actionStr; - } - } - return ACTION_DEFAULT_PARAM; -} - -static AceAction ConvertAccessibilityAction(ActionType accessibilityAction) -{ - static const ActionTable actionTable[] = { - { AceAction::ACTION_CLICK, ActionType::ACCESSIBILITY_ACTION_CLICK }, - { AceAction::ACTION_LONG_CLICK, ActionType::ACCESSIBILITY_ACTION_LONG_CLICK }, - { AceAction::ACTION_SCROLL_FORWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD }, - { AceAction::ACTION_SCROLL_BACKWARD, ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD }, - { AceAction::ACTION_FOCUS, ActionType::ACCESSIBILITY_ACTION_FOCUS }, - { AceAction::ACTION_CLEAR_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS }, - { AceAction::ACTION_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS }, - { AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS, ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS }, - { AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT }, - { AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT }, - { AceAction::ACTION_SET_TEXT, ActionType::ACCESSIBILITY_ACTION_SET_TEXT }, - { AceAction::ACTION_COPY, ActionType::ACCESSIBILITY_ACTION_COPY }, - { AceAction::ACTION_PASTE, ActionType::ACCESSIBILITY_ACTION_PASTE }, - { AceAction::ACTION_CUT, ActionType::ACCESSIBILITY_ACTION_CUT }, - { AceAction::ACTION_SELECT, ActionType::ACCESSIBILITY_ACTION_SELECT }, - { AceAction::ACTION_CLEAR_SELECTION, ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION }, - { AceAction::ACTION_SET_SELECTION, ActionType::ACCESSIBILITY_ACTION_SET_SELECTION }, - { AceAction::ACTION_SET_CURSOR_POSITION, ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION }, - { AceAction::ACTION_EXEC_SUB_COMPONENT, ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK }, - { AceAction::ACTION_NEXT_HTML_ITEM, ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM }, - { AceAction::ACTION_PREVIOUS_HTML_ITEM, ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM }, - }; - for (const auto& item : actionTable) { - if (accessibilityAction == item.action) { - return item.aceAction; - } - } - return AceAction::ACTION_NONE; -} - -static void DumpSupportActionNG(const AccessibilityElementInfo& nodeInfo) -{ - DumpLog::GetInstance().AddDesc( - "support action instructions: use command to make application components perform corresponding action"); - DumpLog::GetInstance().AddDesc( - "use support action command: aa dump -i [AbilityRecord] -c -inspector [AccessibilityId] [AceAction]"); - std::string actionForDump; - for (const auto& action : nodeInfo.GetActionList()) { - if (!actionForDump.empty()) { - actionForDump.append(","); - } - actionForDump.append(ConvertActionTypeToString(action.GetActionType())); - actionForDump.append(": "); - actionForDump.append(std::to_string(static_cast(ConvertAccessibilityAction(action.GetActionType())))); - } - DumpLog::GetInstance().AddDesc("support action: ", actionForDump); -} - -static void DumpGridInfoNG(const AccessibilityElementInfo& nodeInfo) -{ - DumpLog::GetInstance().AddDesc("grid info rows: ", nodeInfo.GetGrid().GetRowCount()); - DumpLog::GetInstance().AddDesc("grid info columns: ", nodeInfo.GetGrid().GetColumnCount()); - DumpLog::GetInstance().AddDesc("grid info select mode: ", nodeInfo.GetGrid().GetSelectionMode()); - DumpLog::GetInstance().AddDesc("grid item info, row: ", nodeInfo.GetGridItem().GetRowIndex()); - DumpLog::GetInstance().AddDesc("grid item info, column: ", nodeInfo.GetGridItem().GetColumnIndex()); - DumpLog::GetInstance().AddDesc("grid item info, rowSpan: ", nodeInfo.GetGridItem().GetRowSpan()); - DumpLog::GetInstance().AddDesc("grid item info, columnSpan: ", nodeInfo.GetGridItem().GetColumnSpan()); - DumpLog::GetInstance().AddDesc("grid item info, is heading: ", nodeInfo.GetGridItem().IsHeading()); - DumpLog::GetInstance().AddDesc("grid item info, selected: ", nodeInfo.GetGridItem().IsSelected()); -} - -inline void DumpContentListNG(const AccessibilityElementInfo& nodeInfo) -{ - std::vector contentList; - nodeInfo.GetContentList(contentList); - std::string contents; - for (const auto& content : contentList) { - if (!contents.empty()) { - contents.append(","); - } - contents.append(content); - } - DumpLog::GetInstance().AddDesc("content list: ", contents); -} - -static void DumpExtraElementInfoNG(const AccessibilityElementInfo& nodeInfo) -{ - ExtraElementInfo extraElementInfo = nodeInfo.GetExtraElement(); - if (!extraElementInfo.GetExtraElementInfoValueStr().empty()) { - for (auto i = extraElementInfo.GetExtraElementInfoValueStr().begin(); - i != extraElementInfo.GetExtraElementInfoValueStr().end(); ++i) { - DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second); - } - } - if (!extraElementInfo.GetExtraElementInfoValueInt().empty()) { - for (auto i = extraElementInfo.GetExtraElementInfoValueInt().begin(); - i != extraElementInfo.GetExtraElementInfoValueInt().end(); ++i) { - DumpLog::GetInstance().AddDesc("extra element info: ", i->first, i->second); - } - } -} - -static void UpdateSpanList(std::vector& spansInfosList, std::string& spans) -{ - for (const auto& span : spansInfosList) { - if (!spans.empty()) { - spans.append(","); - } - spans.append("\n\t span id: "); - spans.append(std::to_string(span.GetSpanId())); - spans.append(", span text: "); - spans.append(span.GetSpanText()); - spans.append(", accessibility text: "); - spans.append(span.GetAccessibilityText()); - spans.append(", accessibility description: "); - spans.append(span.GetAccessibilityDescription()); - spans.append(", accessibility level: "); - spans.append(span.GetAccessibilityLevel()); - } -} - -inline void DumpSpanListNG(const AccessibilityElementInfo& nodeInfo) -{ - std::string spans; - std::vector spansInfosList = nodeInfo.GetSpanList(); - std::size_t spanCount = spansInfosList.size(); - UpdateSpanList(spansInfosList, spans); - DumpLog::GetInstance().AddDesc("span list count: ", static_cast(spanCount)); - DumpLog::GetInstance().AddDesc("span list: ", spans); -} - -inline std::string ChildrenToString(const std::vector& children, int32_t treeId) -{ - std::string ids; - for (auto child : children) { - if (!ids.empty()) { - ids.append(","); - } - int64_t childId = child; - AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, childId); - ids.append(std::to_string(childId)); - } - return ids; -} - -inline void DumpRectNG(const Accessibility::Rect& rect) -{ - DumpLog::GetInstance().AddDesc( - "width: ", std::to_string(rect.GetRightBottomXScreenPostion() - rect.GetLeftTopXScreenPostion())); - DumpLog::GetInstance().AddDesc( - "height: ", std::to_string(rect.GetRightBottomYScreenPostion() - rect.GetLeftTopYScreenPostion())); - DumpLog::GetInstance().AddDesc("left: ", std::to_string(rect.GetLeftTopXScreenPostion())); - DumpLog::GetInstance().AddDesc("top: ", std::to_string(rect.GetLeftTopYScreenPostion())); - DumpLog::GetInstance().AddDesc("right: ", std::to_string(rect.GetRightBottomXScreenPostion())); - DumpLog::GetInstance().AddDesc("bottom: ", std::to_string(rect.GetRightBottomYScreenPostion())); -} - void GenerateAccessibilityEventInfo(const AccessibilityEvent& accessibilityEvent, AccessibilityEventInfo& eventInfo) { Accessibility::EventType type = Accessibility::EventType::TYPE_VIEW_INVALID; @@ -2977,94 +2794,12 @@ void GenerateAccessibilityEventInfo(const AccessibilityEvent& accessibilityEvent void JsAccessibilityManager::DumpAccessibilityPropertyNG(const AccessibilityElementInfo& nodeInfo) { - DumpLog::GetInstance().AddDesc("checked: ", BoolToString(nodeInfo.IsChecked())); - DumpLog::GetInstance().AddDesc("selected: ", BoolToString(nodeInfo.IsSelected())); - DumpLog::GetInstance().AddDesc("checkable: ", BoolToString(nodeInfo.IsCheckable())); - DumpLog::GetInstance().AddDesc("scrollable: ", BoolToString(nodeInfo.IsScrollable())); - DumpLog::GetInstance().AddDesc("accessibility hint: ", BoolToString(nodeInfo.IsGivingHint())); - DumpLog::GetInstance().AddDesc("hint text: ", nodeInfo.GetHint()); - DumpLog::GetInstance().AddDesc("error text: ", nodeInfo.GetError()); - DumpLog::GetInstance().AddDesc("max text length: ", nodeInfo.GetTextLengthLimit()); - DumpLog::GetInstance().AddDesc("scroll offset: ", nodeInfo.GetOffset()); - DumpLog::GetInstance().AddDesc("text selection start: ", nodeInfo.GetSelectedBegin()); - DumpLog::GetInstance().AddDesc("text selection end: ", nodeInfo.GetSelectedEnd()); - DumpLog::GetInstance().AddDesc("is multi line: ", BoolToString(nodeInfo.IsPluraLineSupported())); - DumpLog::GetInstance().AddDesc("is password: ", BoolToString(nodeInfo.IsPassword())); - DumpLog::GetInstance().AddDesc( - "text input type: ", ConvertInputTypeToString(static_cast(nodeInfo.GetInputType()))); - DumpGridInfoNG(nodeInfo); - DumpLog::GetInstance().AddDesc("min value: ", nodeInfo.GetRange().GetMin()); - DumpLog::GetInstance().AddDesc("max value: ", nodeInfo.GetRange().GetMax()); - DumpLog::GetInstance().AddDesc("current value: ", nodeInfo.GetRange().GetCurrent()); - DumpLog::GetInstance().AddDesc("current index: ", nodeInfo.GetCurrentIndex()); - DumpLog::GetInstance().AddDesc("begin index: ", nodeInfo.GetBeginIndex()); - DumpLog::GetInstance().AddDesc("end index: ", nodeInfo.GetEndIndex()); - DumpLog::GetInstance().AddDesc("collection item counts: ", nodeInfo.GetItemCounts()); - DumpLog::GetInstance().AddDesc("editable: ", BoolToString(nodeInfo.IsEditable())); - DumpLog::GetInstance().AddDesc("is essential: ", BoolToString(nodeInfo.IsEssential())); - DumpLog::GetInstance().AddDesc("deletable: ", nodeInfo.IsDeletable()); - DumpLog::GetInstance().AddDesc("live region: ", nodeInfo.GetLiveRegion()); - DumpLog::GetInstance().AddDesc("content description: ", nodeInfo.GetDescriptionInfo()); - DumpLog::GetInstance().AddDesc("content invalid: ", BoolToString(nodeInfo.GetContentInvalid())); - DumpLog::GetInstance().AddDesc("accessibility label: ", nodeInfo.GetLabeledAccessibilityId()); - DumpLog::GetInstance().AddDesc("isActive: ", nodeInfo.GetIsActive()); - DumpLog::GetInstance().AddDesc("accessibilityVisible: ", nodeInfo.GetAccessibilityVisible()); - DumpLog::GetInstance().AddDesc("accessibilityNextFocusInspectorKey: ", - nodeInfo.GetAccessibilityNextFocusInspectorKey()); - DumpLog::GetInstance().AddDesc("accessibilityScrollTriggerable: ", - nodeInfo.GetAccessibilityScrollable()); - DumpLog::GetInstance().AddDesc("accessibilityNextFocusId: ", nodeInfo.GetAccessibilityNextFocusId()); - DumpLog::GetInstance().AddDesc("accessibilityPreviousFocusId: ", nodeInfo.GetAccessibilityPreviousFocusId()); - DumpLog::GetInstance().AddDesc("clip: ", nodeInfo.GetClip()); - DumpExtraElementInfoNG(nodeInfo); - DumpLog::GetInstance().AddDesc( - "trigger action: ", static_cast(ConvertAccessibilityAction(nodeInfo.GetTriggerAction()))); - DumpLog::GetInstance().AddDesc("text move step: " + std::to_string(nodeInfo.GetTextMovementStep())); - DumpSpanListNG(nodeInfo); - DumpSupportActionNG(nodeInfo); - DumpContentListNG(nodeInfo); - DumpLog::GetInstance().AddDesc("latest content: ", nodeInfo.GetLatestContent()); + AccessibilityElementInfoUtils::ToDetailInfo(nodeInfo, treeId_); } void JsAccessibilityManager::DumpCommonPropertyNG(const AccessibilityElementInfo& nodeInfo, int32_t treeId) { - int64_t elementId = nodeInfo.GetAccessibilityId(); - AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, elementId); - DumpLog::GetInstance().AddDesc("ID: ", elementId); - DumpLog::GetInstance().AddDesc("UniqueID: ", nodeInfo.GetUniqueId()); - int64_t parentId = nodeInfo.GetParentNodeId(); - AccessibilitySystemAbilityClient::SetSplicElementIdTreeId(treeId, parentId); - DumpLog::GetInstance().AddDesc("parent ID: ", parentId); - DumpLog::GetInstance().AddDesc("child IDs: ", ChildrenToString(nodeInfo.GetChildIds(), treeId)); - DumpLog::GetInstance().AddDesc("component type: ", nodeInfo.GetComponentType()); - DumpLog::GetInstance().AddDesc("accessibilityCustomRole: " + nodeInfo.GetCustomComponentType()); - DumpLog::GetInstance().AddDesc("text: ", nodeInfo.GetContent()); - DumpLog::GetInstance().AddDesc("originText: ", nodeInfo.GetOriginalText()); - DumpLog::GetInstance().AddDesc("window id: " + std::to_string(nodeInfo.GetWindowId())); - DumpRectNG(nodeInfo.GetRectInScreen()); - - DumpLog::GetInstance().AddDesc("enabled: ", BoolToString(nodeInfo.IsEnabled())); - DumpLog::GetInstance().AddDesc("focusable: ", BoolToString(nodeInfo.IsFocusable())); - DumpLog::GetInstance().AddDesc("focused: ", BoolToString(nodeInfo.IsFocused())); - DumpLog::GetInstance().AddDesc("visible: ", BoolToString(nodeInfo.IsVisible())); - DumpLog::GetInstance().AddDesc("accessibility focused: ", BoolToString(nodeInfo.HasAccessibilityFocus())); - DumpLog::GetInstance().AddDesc("accessibilityText: " + nodeInfo.GetAccessibilityText()); - DumpLog::GetInstance().AddDesc("accessibilityGroup: " + BoolToString(nodeInfo.GetAccessibilityGroup())); - DumpLog::GetInstance().AddDesc("accessibilityLevel: " + nodeInfo.GetAccessibilityLevel()); - DumpLog::GetInstance().AddDesc("accessibilityDescription: " + nodeInfo.GetDescriptionInfo()); - DumpLog::GetInstance().AddDesc("hitTestBehavior: " + nodeInfo.GetHitTestBehavior()); - - DumpLog::GetInstance().AddDesc("inspector key: ", nodeInfo.GetInspectorKey()); - DumpLog::GetInstance().AddDesc("bundle name: ", nodeInfo.GetBundleName()); - DumpLog::GetInstance().AddDesc("page id: " + std::to_string(nodeInfo.GetPageId())); - DumpLog::GetInstance().AddDesc("page path: ", nodeInfo.GetPagePath()); - DumpLog::GetInstance().AddDesc("is valid element: ", BoolToString(nodeInfo.IsValidElement())); - DumpLog::GetInstance().AddDesc("resource name: ", nodeInfo.GetComponentResourceId()); - - DumpLog::GetInstance().AddDesc("clickable: ", BoolToString(nodeInfo.IsClickable())); - DumpLog::GetInstance().AddDesc("long clickable: ", BoolToString(nodeInfo.IsLongClickable())); - DumpLog::GetInstance().AddDesc("popup supported: ", BoolToString(nodeInfo.IsPopupSupported())); - DumpLog::GetInstance().AddDesc("zindex: ", std::to_string(nodeInfo.GetZIndex())); + AccessibilityElementInfoUtils::ToCommonInfo(nodeInfo, treeId_); } void JsAccessibilityManager::UpdateVirtualNodeFocus() @@ -4286,84 +4021,6 @@ RefPtr JsAccessibilityManager::GetPipelineByWindowId(uint32 // DFX related namespace { -enum class InjectActionType : uint32_t { - UNDEFINED_ACTION = 0, - NOTIFY_CHILD_ACTION = 1, - SECURITY_CLICK_ACTION = 2, -}; - -bool CheckAndGetEventTestArgument(std::vector::const_iterator start, - const std::vector& params, DumpInfoArgument& argument) -{ - auto arg = start; - argument.mode = DumpMode::EVENT_TEST; - constexpr int32_t NUM_EVENT_DIMENSION = 2; - if (std::distance(arg, params.end()) <= NUM_EVENT_DIMENSION) { - DumpLog::GetInstance().Print(std::string("Error: --event-test is used to send event with node ") + - "need elementId and eventId, e.g. '--event-test ${elementId} ${eventId}'!"); - return false; - } - ++arg; - argument.nodeId = StringUtils::StringToLongInt(*arg); - ++arg; - argument.eventId = StringUtils::StringToInt(*arg); - return true; -} - -bool CheckAndGetHoverTestArgument(std::vector::const_iterator start, - const std::vector& params, DumpInfoArgument& argument) -{ - auto arg = start; - argument.mode = DumpMode::HOVER_TEST; - static constexpr int32_t NUM_POINT_DIMENSION = 2; - if (std::distance(arg, params.end()) <= NUM_POINT_DIMENSION) { - DumpLog::GetInstance().Print(std::string("Error: --hover-test is used to get nodes at a point ") + - "relative to the root node, e.g. '--hover-test ${x} ${y}'!"); - return false; - } - ++arg; - argument.pointX = StringUtils::StringToInt(*arg); - ++arg; - argument.pointY = StringUtils::StringToInt(*arg); - return true; -} - -bool DumpProcessInjectActionParameters( - const std::vector& params, - int64_t& nodeId, - int32_t& result, - InjectActionType& actionType) -{ - constexpr int32_t NUM_PARAMETERS_DIMENSION = 1; - if (params.size() < 1) { - return false; - } - - for (auto arg = params.begin() + 1; arg != params.end(); ++arg) { - if (*arg == "--inject-action") { - if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) { - DumpLog::GetInstance().Print(std::string("Error: parameters need with data")); - return false; - } - ++arg; - nodeId = StringUtils::StringToLongInt(*arg); - } else if (*arg == "--NotifyChildAction") { - if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) { - DumpLog::GetInstance().Print(std::string("Error: parameters need with data")); - return false; - } - ++arg; - result = StringUtils::StringToInt(*arg); - actionType = InjectActionType::NOTIFY_CHILD_ACTION; - return true; - } else if (*arg == "--SecurityClickAction") { - actionType = InjectActionType::SECURITY_CLICK_ACTION; - return true; - } - } - return false; -} - bool DumpProcessEmbedSearchParameters( const std::vector& params, int64_t& nodeId, @@ -4486,8 +4143,8 @@ void JsAccessibilityManager::DumpInjectActionTest(const std::vector int64_t nodeId = 0; int32_t result = 0; InjectActionType actionType = InjectActionType::UNDEFINED_ACTION; - - if (!DumpProcessInjectActionParameters(params, nodeId, result, actionType)) { + + if (!AccessibilityHidumper::DumpProcessInjectActionParameters(params, nodeId, result, actionType)) { return; } @@ -4801,69 +4458,6 @@ bool JsAccessibilityManager::CheckDumpInfoParams(const std::vector return true; } -bool JsAccessibilityManager::GetDumpInfoArgument(const std::vector& params, DumpInfoArgument& argument) -{ - if (params.size() < 1) { - return false; - } - argument.isDumpSimplify = params[0].compare("-simplify") == 0; - bool isArgument = DumpInfoParams(params, argument); - return isArgument; -} - -bool JsAccessibilityManager::DumpInfoParams(const std::vector& params, DumpInfoArgument& argument) -{ - for (auto arg = params.begin() + 1; arg != params.end(); ++arg) { - if (*arg == "-w") { - argument.useWindowId = true; - } else if (*arg == "--root") { - ++arg; - if (arg == params.end()) { - DumpLog::GetInstance().Print(std::string("Error: --root is used to set the root node, ") + - "e.g. '--root ${AccessibilityId}'!"); - return false; - } - argument.rootId = StringUtils::StringToLongInt(*arg); - } else if (*arg == "--hover-test") { - if (!CheckAndGetHoverTestArgument(arg, params, argument)) { - return false; - } - } else if (*arg == "--event-test") { - return CheckAndGetEventTestArgument(arg, params, argument); - } else if (*arg == "--inject-action") { - argument.mode = DumpMode::INJECT_ACTION_TEST; - break; - } else if (*arg == "--embed-search") { - argument.mode = DumpMode::EMBED_SEARCH_TEST; - break; - } else if (*arg == "--embed-hover") { - argument.mode = DumpMode::EMBED_HOVER_TEST; - break; - } else if (*arg == "--set-whitelist") { - argument.mode = DumpMode::SET_CHECKLIST_TEST; - break; - } else if (*arg == "--get-whitelist") { - argument.mode = DumpMode::GET_CHECKLIST_TEST; - break; - } else if (*arg == "--specific-search") { - argument.mode = DumpMode::SPECIFIC_SEARCH_TEST; - break; - } else if (*arg == "-v") { - argument.verbose = true; - } else if (*arg == "-json") { - argument.mode = DumpMode::TREE; - } else { - if (argument.mode == DumpMode::NODE) { - argument.mode = DumpMode::HANDLE_EVENT; - break; - } else { - argument.mode = DumpMode::NODE; - argument.nodeId = StringUtils::StringToLongInt(*arg); - } - } - } - return true; -} void JsAccessibilityManager::OnDumpInfoNG(const std::vector& params, uint32_t windowId, bool hasJson) { @@ -4872,7 +4466,7 @@ void JsAccessibilityManager::OnDumpInfoNG(const std::vector& params return; } DumpInfoArgument argument; - if (!GetDumpInfoArgument(params, argument)) { + if (!AccessibilityHidumper::GetDumpInfoArgument(params, argument)) { return; } std::vector info; @@ -6869,7 +6463,7 @@ bool JsAccessibilityManager::ExecuteActionNG(int64_t elementId, CHECK_NULL_RETURN(accessibilityProperty, false); result = ActAccessibilityAction(action, actionArguments, accessibilityProperty); if (!result) { - EventReport::ReportAccessibilityFailEvent(ConvertActionTypeToString(action)); + EventReport::ReportAccessibilityFailEvent(AccessibilityManagerHidumper::ConvertActionTypeToString(action)); } } return result; @@ -7227,7 +6821,8 @@ bool JsAccessibilityManager::ExecuteWebActionNG(int64_t elementId, ActionType ac const std::map& actionArguments, const RefPtr& webPattern) { CHECK_NULL_RETURN(webPattern, false); - return webPattern->ExecuteAction(elementId, ConvertAccessibilityAction(action), actionArguments); + return webPattern->ExecuteAction( + elementId, AccessibilityManagerHidumper::ConvertAccessibilityAction(action), actionArguments); } void JsAccessibilityManager::ExecuteWebAction(const int64_t elementId, const ActionParam& param, diff --git a/adapter/ohos/osal/js_accessibility_manager.h b/adapter/ohos/osal/js_accessibility_manager.h index c8af3a4da05ba506021b226ee8eb0ebfe532e9c7..032ab6265ebacdd57f80aa5e7a0c63e761b1a0cd 100644 --- a/adapter/ohos/osal/js_accessibility_manager.h +++ b/adapter/ohos/osal/js_accessibility_manager.h @@ -27,6 +27,7 @@ #include "core/accessibility/accessibility_manager.h" #include "core/accessibility/accessibility_utils.h" +#include "core/accessibility/hidumper/accessibility_hidumper.h" #include "core/accessibility/utils/accessibility_manager_utils.h" #include "frameworks/bridge/common/accessibility/accessibility_node_manager.h" @@ -69,16 +70,6 @@ struct CommonProperty { float_t scaleY = 1.0f; }; -struct ActionTable { - AceAction aceAction; - ActionType action; -}; - -struct ActionStrTable { - ActionType action; - std::string actionStr; -}; - struct FillEventInfoParam { int64_t elementId = 0; int64_t stackNodeId = 0; @@ -110,33 +101,6 @@ struct AccessibilityFocusInfo { : currentFocusNodeId(nodeId), currentFocusVirtualNodeParentId(parentId) {} }; -enum class DumpMode { - TREE, - NODE, - HANDLE_EVENT, - HOVER_TEST, - EVENT_TEST, - INJECT_ACTION_TEST, - EMBED_SEARCH_TEST, - EMBED_HOVER_TEST, - SET_CHECKLIST_TEST, - GET_CHECKLIST_TEST, - SPECIFIC_SEARCH_TEST, -}; - -struct DumpInfoArgument { - bool useWindowId = false; - DumpMode mode = DumpMode::TREE; - bool isDumpSimplify = false; - bool verbose = false; - int64_t rootId = -1; - int32_t pointX = 0; - int32_t pointY = 0; - int64_t nodeId = -1; - int32_t action = 0; - int32_t eventId = -1; -}; - struct GetInfoByNodeId { std::string componentType; int32_t pageId = -1; @@ -400,8 +364,6 @@ public: ActionType& actionOp); bool DumpProcessEventParameters( AccessibilityEvent& event, const std::vector& params); - bool GetDumpInfoArgument(const std::vector& params, DumpInfoArgument& argument); - bool DumpInfoParams(const std::vector& params, DumpInfoArgument& argument); void FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter) override; AccessibilityWindowInfo GenerateWindowInfo(const RefPtr& node, diff --git a/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp b/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp index e53c710a39cbc8d74209c11b55a9b090bfd52c26..f69a32112b62dbeb1360c2aa1053078eca26ed9d 100644 --- a/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp +++ b/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp @@ -15,12 +15,12 @@ #include "js_third_provider_interaction_operation.h" #include "accessibility_system_ability_client.h" +#include "frameworks/core/accessibility/hidumper/accessibility_hidumper.h" #include "frameworks/core/components_ng/pattern/web/web_pattern.h" #include "js_third_accessibility_hover_ng.h" using namespace OHOS::Accessibility; using namespace OHOS::AccessibilityConfig; -using namespace std; namespace OHOS::Ace::Framework { constexpr int32_t ACCESSIBILITY_FOCUS_WITHOUT_EVENT = -2100001; @@ -351,54 +351,6 @@ void AccessibilityHoverManagerForThirdNG::DeregisterJsThirdProviderInteractionOp } namespace { - -bool GetDumpInfoArgument(const std::vector& params, DumpInfoArgument& argument) -{ - if (params.empty()) { - return false; - } - argument.isDumpSimplify = params[0].compare("-simplify") == 0; - for (auto arg = params.begin() + 1; arg != params.end(); ++arg) { - if (*arg == "-w") { - argument.useWindowId = true; - } else if (*arg == "--root") { - ++arg; - if (arg == params.end()) { - DumpLog::GetInstance().Print(std::string("Error: --root is used to set the root node, ") + - "e.g. '--root ${AccessibilityId}'!"); - return false; - } - argument.rootId = StringUtils::StringToLongInt(*arg); - } else if (*arg == "--hover-test") { - argument.mode = DumpMode::HOVER_TEST; - static constexpr int32_t NUM_POINT_DIMENSION = 2; - if (std::distance(arg, params.end()) <= NUM_POINT_DIMENSION) { - DumpLog::GetInstance().Print(std::string("Error: --hover-test is used to get nodes at a point ") + - "relative to the root node, e.g. '--hover-test ${x} ${y}'!"); - return false; - } - ++arg; - argument.pointX = StringUtils::StringToInt(*arg); - ++arg; - argument.pointY = StringUtils::StringToInt(*arg); - } else if (*arg == "-v") { - argument.verbose = true; - } else if (*arg == "-json") { - argument.mode = DumpMode::TREE; - } else { - if (argument.mode == DumpMode::NODE) { - argument.mode = DumpMode::HANDLE_EVENT; - argument.action = StringUtils::StringToInt(*arg); - break; - } else { - argument.mode = DumpMode::NODE; - argument.nodeId = StringUtils::StringToLongInt(*arg); - } - } - } - return true; -} - void DumpTreeNodeInfoForThird( Accessibility::AccessibilityElementInfo& info, int32_t depth) { @@ -581,7 +533,7 @@ bool AccessibilityHoverManagerForThirdNG::OnDumpChildInfoForThirdRecursive( const WeakPtr& jsAccessibilityManager) { DumpInfoArgument argument; - if (GetDumpInfoArgument(params, argument) == false) { + if (!AccessibilityHidumper::GetDumpInfoArgument(params, argument)) { return true; } auto jsThirdProviderOperator = diff --git a/frameworks/core/BUILD.gn b/frameworks/core/BUILD.gn index 9b5b8c777747995caf015059cfb2c6100e6ff28f..4b4c3f63a0f00c63c6d78fb498fe71233aa9dae5 100644 --- a/frameworks/core/BUILD.gn +++ b/frameworks/core/BUILD.gn @@ -504,6 +504,10 @@ template("ace_core_source_set") { "$ace_root/frameworks/core/components_ng/pattern/text_field:ace_core_components_text_field_pattern_ng_$platform", ] + deps += [ + "$ace_root/frameworks/core/accessibility:ace_core_accessibility_ng_$platform", + ] + if (qrcodegen_support) { deps += [ "$ace_root/frameworks/core/components/qrcode:ace_core_components_qrcode_$platform", @@ -1044,6 +1048,10 @@ template("ace_core_ng_source_set") { "$ace_root/frameworks/core/components_ng/token_theme:ace_core_components_token_theme_ng_$platform", ] + deps += [ + "$ace_root/frameworks/core/accessibility:ace_core_accessibility_ng_$platform", + ] + if (defined(config.use_components_lib) && config.use_components_lib) { deps += [ "$ace_root/frameworks/core/components_ng/common_napi_utils:ace_core_components_common_napi_utils_$platform" ] } else { diff --git a/frameworks/core/accessibility/BUILD.gn b/frameworks/core/accessibility/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..daaabd799e72ef2b7a319c3a1557d71116a6177b --- /dev/null +++ b/frameworks/core/accessibility/BUILD.gn @@ -0,0 +1,74 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/arkui/ace_engine/ace_config.gni") + +# build core sources +template("ace_core_accessibility_ng_source_set") { + forward_variables_from(invoker, "*") + + ohos_source_set(target_name) { + subsystem_name = ace_engine_subsystem + part_name = ace_engine_part + if (current_os == "ohos") { + sanitize = { + integer_overflow = true + boundary_sanitize = true + debug = ace_sanitize_debug + } + } + defines += invoker.defines + + # add common source file needed by all product platform here + sources = [ + # dfx + "hidumper/accessibility_hidumper.cpp", + ] + + configs = [ "$ace_root:ace_config" ] + + deps = [] + external_deps = [ + ] + if (use_hilog) { + external_deps += [ "hilog:libhilog" ] + } + cflags_cc = [] + cflags_cc += invoker.cflags_cc + } +} + +foreach(item, ace_platforms) { + ace_core_accessibility_ng_source_set("ace_core_accessibility_ng_" + item.name) { + + if (defined(item.config)) { + config = item.config + } else { + config = { + } + } + + if (defined(config.defines)) { + defines = config.defines + } else { + defines = [] + } + + if (defined(config.cflags_cc)) { + cflags_cc = config.cflags_cc + } else { + cflags_cc = [] + } + } +} diff --git a/frameworks/core/accessibility/hidumper/accessibility_hidumper.cpp b/frameworks/core/accessibility/hidumper/accessibility_hidumper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4faf45a2e8bfa3db63ea54f320b1eb28671f6fff --- /dev/null +++ b/frameworks/core/accessibility/hidumper/accessibility_hidumper.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "base/log/dump_log.h" +#include "core/accessibility/hidumper/accessibility_hidumper.h" +#include "core/components_ng/base/frame_node.h" + +namespace OHOS::Ace { + +namespace { +bool CheckAndGetHoverTestArgument( + std::vector::const_iterator start, + const std::vector& params, DumpInfoArgument& argument) +{ + auto arg = start; + argument.mode = DumpMode::HOVER_TEST; + static constexpr int32_t NUM_POINT_DIMENSION = 2; + if (std::distance(arg, params.end()) <= NUM_POINT_DIMENSION) { + DumpLog::GetInstance().Print(std::string("Error: --hover-test is used to get nodes at a point ") + + "relative to the root node, e.g. '--hover-test ${x} ${y}'!"); + return false; + } + ++arg; + argument.pointX = StringUtils::StringToInt(*arg); + ++arg; + argument.pointY = StringUtils::StringToInt(*arg); + return true; +} + +bool CheckAndGetEventTestArgument ( + std::vector::const_iterator start, + const std::vector& params, + DumpInfoArgument& argument) +{ + auto arg = start; + argument.mode = DumpMode::EVENT_TEST; + constexpr int32_t NUM_EVENT_DIMENSION = 2; + if (std::distance(arg, params.end()) <= NUM_EVENT_DIMENSION) { + DumpLog::GetInstance().Print(std::string("Error: --event-test is used to send event with node ") + + "need elementId and eventId, e.g. '--event-test ${elementId} ${eventId}'!"); + return false; + } + ++arg; + argument.nodeId = StringUtils::StringToLongInt(*arg); + ++arg; + argument.eventId = StringUtils::StringToInt(*arg); + return true; +} + +bool DumpInfoParams(const std::vector& params, DumpInfoArgument& argument) +{ + for (auto arg = params.begin() + 1; arg != params.end(); ++arg) { + if (*arg == "-w") { + argument.useWindowId = true; + } else if (*arg == "--root") { + ++arg; + if (arg == params.end()) { + DumpLog::GetInstance().Print(std::string("Error: --root is used to set the root node, ") + + "e.g. '--root ${AccessibilityId}'!"); + return false; + } + argument.rootId = StringUtils::StringToLongInt(*arg); + } else if (*arg == "--hover-test") { + if (!CheckAndGetHoverTestArgument(arg, params, argument)) { + return false; + } + } else if (*arg == "--event-test") { + return CheckAndGetEventTestArgument(arg, params, argument); + } else if (*arg == "--inject-action") { + argument.mode = DumpMode::INJECT_ACTION_TEST; + break; + } else if (*arg == "--embed-search") { + argument.mode = DumpMode::EMBED_SEARCH_TEST; + break; + } else if (*arg == "--embed-hover") { + argument.mode = DumpMode::EMBED_HOVER_TEST; + break; + } else if (*arg == "--set-whitelist") { + argument.mode = DumpMode::SET_CHECKLIST_TEST; + break; + } else if (*arg == "--get-whitelist") { + argument.mode = DumpMode::GET_CHECKLIST_TEST; + break; + } else if (*arg == "--specific-search") { + argument.mode = DumpMode::SPECIFIC_SEARCH_TEST; + break; + } else if (*arg == "-v") { + argument.verbose = true; + } else if (*arg == "-json") { + argument.mode = DumpMode::TREE; + } else { + if (argument.mode == DumpMode::NODE) { + argument.mode = DumpMode::HANDLE_EVENT; + break; + } else { + argument.mode = DumpMode::NODE; + argument.nodeId = StringUtils::StringToLongInt(*arg); + } + } + } + return true; +} +} // namespace + +bool AccessibilityHidumper::DumpProcessInjectActionParameters( + const std::vector& params, + int64_t& nodeId, + int32_t& result, + InjectActionType& actionType) +{ + constexpr int32_t NUM_PARAMETERS_DIMENSION = 1; + if (params.size() < 1) { + return false; + } + + for (auto arg = params.begin() + 1; arg != params.end(); ++arg) { + if (*arg == "--inject-action") { + if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) { + DumpLog::GetInstance().Print(std::string("Error: parameters need with data")); + return false; + } + ++arg; + nodeId = StringUtils::StringToLongInt(*arg); + } else if (*arg == "--NotifyChildAction") { + if (std::distance(arg, params.end()) <= NUM_PARAMETERS_DIMENSION) { + DumpLog::GetInstance().Print(std::string("Error: parameters need with data")); + return false; + } + ++arg; + result = StringUtils::StringToInt(*arg); + actionType = InjectActionType::NOTIFY_CHILD_ACTION; + return true; + } else if (*arg == "--SecurityClickAction") { + actionType = InjectActionType::SECURITY_CLICK_ACTION; + return true; + } + } + return false; +} + + +bool AccessibilityHidumper::GetDumpInfoArgument(const std::vector& params, DumpInfoArgument& argument) +{ + if (params.size() < 1) { + return false; + } + argument.isDumpSimplify = params[0].compare("-simplify") == 0; + bool isArgument = DumpInfoParams(params, argument); + return isArgument; +} +} // namespace OHOS::Ace diff --git a/frameworks/core/accessibility/hidumper/accessibility_hidumper.h b/frameworks/core/accessibility/hidumper/accessibility_hidumper.h new file mode 100644 index 0000000000000000000000000000000000000000..aa1697355508a7ceb455760ac41a57e4d3ce8dd8 --- /dev/null +++ b/frameworks/core/accessibility/hidumper/accessibility_hidumper.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_ACCESSIBILITY_HIDUMPER_ACCESSIBILITY_HIDUMPER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_ACCESSIBILITY_HIDUMPER_ACCESSIBILITY_HIDUMPER_H + +#include "base/memory/ace_type.h" +#include "core/components_ng/base/ui_node.h" + +namespace OHOS::Accessibility { +} + +namespace OHOS::Ace { +class FrameNode; + +enum class InjectActionType : uint32_t { + UNDEFINED_ACTION = 0, + NOTIFY_CHILD_ACTION = 1, + SECURITY_CLICK_ACTION = 2, +}; + +enum class DumpMode { + TREE, + NODE, + HANDLE_EVENT, + HOVER_TEST, + EVENT_TEST, + INJECT_ACTION_TEST, + EMBED_SEARCH_TEST, + EMBED_HOVER_TEST, + SET_CHECKLIST_TEST, + GET_CHECKLIST_TEST, + SPECIFIC_SEARCH_TEST, +}; + +struct DumpInfoArgument { + bool useWindowId = false; + DumpMode mode = DumpMode::TREE; + bool isDumpSimplify = false; + bool verbose = false; + int64_t rootId = -1; + int32_t pointX = 0; + int32_t pointY = 0; + int64_t nodeId = -1; + int32_t action = 0; + int32_t eventId = -1; +}; + +class AccessibilityHidumper { +public: + static bool DumpProcessInjectActionParameters( + const std::vector& params, + int64_t& nodeId, + int32_t& result, + InjectActionType& actionType); + + static bool GetDumpInfoArgument( + const std::vector& params, + DumpInfoArgument& argument); +}; +} // OHOS::Ace + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ACCESSIBILITY_HIDUMPER_ACCESSIBILITY_HIDUMPER_H diff --git a/test/unittest/core/accessibility/BUILD.gn b/test/unittest/core/accessibility/BUILD.gn index 0873d9d00f8b40723228cfbd8baf323d94412ef7..c9ead8c7ced1ffc0381e0d354870dd18c2457731 100644 --- a/test/unittest/core/accessibility/BUILD.gn +++ b/test/unittest/core/accessibility/BUILD.gn @@ -51,6 +51,7 @@ ace_unittest("accessibility_adapter_test_ng") { type = "new" module_output = "basic" sources = [ + "$ace_root/adapter/ohos/osal/accessibility/accessibility_hidumper_osal.cpp", "$ace_root/adapter/ohos/osal/js_accessibility_manager.cpp", "$ace_root/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp", "$ace_root/adapter/ohos/osal/js_third_provider_interaction_operation.cpp", @@ -58,6 +59,7 @@ ace_unittest("accessibility_adapter_test_ng") { "$ace_root/frameworks/bridge/common/dom/dom_type.cpp", "$ace_root/frameworks/core/accessibility/accessibility_manager_ng.cpp", "$ace_root/frameworks/core/accessibility/accessibility_session_adapter.cpp", + "$ace_root/frameworks/core/accessibility/hidumper/accessibility_hidumper.cpp", "$ace_root/frameworks/core/accessibility/js_inspector/inspect_badge.cpp", "$ace_root/frameworks/core/accessibility/js_inspector/inspect_button.cpp", "$ace_root/frameworks/core/accessibility/js_inspector/inspect_camera.cpp", @@ -112,6 +114,8 @@ ace_unittest("accessibility_adapter_test_ng") { "$ace_root/interfaces/native/native_interface_accessibility.cpp", "$ace_root/test/unittest/core/accessibility/mock_ace_container.cpp", "accessibitlity_manager_utils_test.cpp", + "hidumper/accessibitlity_hidumper_test.cpp", + "hidumper/accessibitlity_hidumper_osal_test.cpp", "js_accessibitlity_manager_test.cpp", "js_third_accessibility_hover_ng_test.cpp", "js_third_provider_interaction_operation_test.cpp", diff --git a/test/unittest/core/accessibility/hidumper/accessibitlity_hidumper_osal_test.cpp b/test/unittest/core/accessibility/hidumper/accessibitlity_hidumper_osal_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e49c0e3e16b05922a2fd5bd6d11c2eee87ce181 --- /dev/null +++ b/test/unittest/core/accessibility/hidumper/accessibitlity_hidumper_osal_test.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "accessibility_element_info.h" +#include "adapter/ohos/osal/accessibility/accessibility_hidumper_osal.h" + +#include "base/log/dump_log.h" +#include "core/accessibility/accessibility_utils.h" + +#define private public +#define protected public + + +#include "base/log/dump_log.h" + +#include "base/log/dump_log.h" +#include "core/accessibility/hidumper/accessibility_hidumper.h" + +#include "core/components_ng/base/frame_node.h" + + +using namespace OHOS::Accessibility; +using namespace testing; +using namespace testing::ext; + +namespace OHOS::Ace { +} // namespace OHOS::Ace + +namespace OHOS::Ace::NG { +namespace { +} // namespace + + +class AccessibilityHidumperOsalTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); +}; + +const std::vector> actionTypeVector{ + { ActionType::ACCESSIBILITY_ACTION_CLICK, AceAction::ACTION_CLICK }, + { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, AceAction::ACTION_LONG_CLICK }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, AceAction::ACTION_SCROLL_FORWARD }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, AceAction::ACTION_SCROLL_BACKWARD }, + { ActionType::ACCESSIBILITY_ACTION_FOCUS, AceAction::ACTION_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, AceAction::ACTION_CLEAR_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, AceAction::ACTION_ACCESSIBILITY_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY }, + { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, AceAction::ACTION_SET_TEXT }, + { ActionType::ACCESSIBILITY_ACTION_COPY, AceAction::ACTION_COPY }, + { ActionType::ACCESSIBILITY_ACTION_PASTE, AceAction::ACTION_PASTE }, + { ActionType::ACCESSIBILITY_ACTION_CUT, AceAction::ACTION_CUT }, + { ActionType::ACCESSIBILITY_ACTION_SELECT, AceAction::ACTION_SELECT }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, AceAction::ACTION_CLEAR_SELECTION }, + { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, AceAction::ACTION_SET_SELECTION }, + { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, AceAction::ACTION_SET_CURSOR_POSITION }, + { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, AceAction::ACTION_EXEC_SUB_COMPONENT }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM, AceAction::ACTION_NEXT_HTML_ITEM }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM, AceAction::ACTION_PREVIOUS_HTML_ITEM }, +}; + +const std::vector> actionTypeStrVector{ + { ActionType::ACCESSIBILITY_ACTION_FOCUS, "ACCESSIBILITY_ACTION_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_FOCUS, "ACCESSIBILITY_ACTION_CLEAR_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_SELECT, "ACCESSIBILITY_ACTION_SELECT" }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_SELECTION, "ACCESSIBILITY_ACTION_CLEAR_SELECTION" }, + { ActionType::ACCESSIBILITY_ACTION_CLICK, "ACCESSIBILITY_ACTION_CLICK" }, + { ActionType::ACCESSIBILITY_ACTION_LONG_CLICK, "ACCESSIBILITY_ACTION_LONG_CLICK" }, + { ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS, "ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, "ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS" }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_FORWARD, "ACCESSIBILITY_ACTION_SCROLL_FORWARD" }, + { ActionType::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, "ACCESSIBILITY_ACTION_SCROLL_BACKWARD" }, + { ActionType::ACCESSIBILITY_ACTION_COPY, "ACCESSIBILITY_ACTION_COPY" }, + { ActionType::ACCESSIBILITY_ACTION_PASTE, "ACCESSIBILITY_ACTION_PASTE" }, + { ActionType::ACCESSIBILITY_ACTION_CUT, "ACCESSIBILITY_ACTION_CUT" }, + { ActionType::ACCESSIBILITY_ACTION_SET_SELECTION, "ACCESSIBILITY_ACTION_SET_SELECTION" }, + { ActionType::ACCESSIBILITY_ACTION_SET_TEXT, "ACCESSIBILITY_ACTION_SET_TEXT" }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_TEXT, "ACCESSIBILITY_ACTION_NEXT_TEXT" }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_TEXT, "ACCESSIBILITY_ACTION_PREVIOUS_TEXT" }, + { ActionType::ACCESSIBILITY_ACTION_SET_CURSOR_POSITION, "ACCESSIBILITY_ACTION_SET_CURSOR_POSITION" }, + { ActionType::ACCESSIBILITY_ACTION_SPAN_CLICK, "ACCESSIBILITY_ACTION_SPAN_CLICK" }, + { ActionType::ACCESSIBILITY_ACTION_NEXT_HTML_ITEM, "ACCESSIBILITY_ACTION_NEXT_HTML_ITEM" }, + { ActionType::ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM, "ACCESSIBILITY_ACTION_PREVIOUS_HTML_ITEM" } +}; + + +void AccessibilityHidumperOsalTest::SetUpTestCase() +{ + std::unique_ptr ostream = std::make_unique(); + ASSERT_NE(ostream, nullptr); + DumpLog::GetInstance().SetDumpFile(std::move(ostream)); +} + +void AccessibilityHidumperOsalTest::TearDownTestCase() +{ +} + +/** + * @tc.name: AccessibilityDfxOsalTest001 + * @tc.desc: ConvertAccessibilityAction + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperOsalTest, AccessibilityDfxOsalTest001, TestSize.Level1) +{ + for (auto &pair: actionTypeVector) { + EXPECT_EQ(Framework::AccessibilityManagerHidumper::ConvertAccessibilityAction(pair.first), pair.second); + } +} + +/** + * @tc.name: AccessibilityDfxOsalTest002 + * @tc.desc: ConvertActionTypeToString + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperOsalTest, AccessibilityDfxOsalTest002, TestSize.Level1) +{ + for (auto &pair: actionTypeStrVector) { + EXPECT_EQ(Framework::AccessibilityManagerHidumper::ConvertActionTypeToString(pair.first), pair.second); + } +} +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/test/unittest/core/accessibility/hidumper/accessibitlity_hidumper_test.cpp b/test/unittest/core/accessibility/hidumper/accessibitlity_hidumper_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90d7ef637c44ee8ca36fda6a3e3a22fed81b08e8 --- /dev/null +++ b/test/unittest/core/accessibility/hidumper/accessibitlity_hidumper_test.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#define private public +#define protected public + + +#include "base/log/dump_log.h" + +#include "base/log/dump_log.h" +#include "core/accessibility/hidumper/accessibility_hidumper.h" + +#include "core/components_ng/base/frame_node.h" + + +using namespace OHOS::Accessibility; +using namespace testing; +using namespace testing::ext; + +namespace OHOS::Ace { +} // namespace OHOS::Ace + +namespace OHOS::Ace::NG { +namespace { +} // namespace + +class AccessibilityHidumperTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); +}; + +void AccessibilityHidumperTest::SetUpTestCase() +{ + std::unique_ptr ostream = std::make_unique(); + ASSERT_NE(ostream, nullptr); + DumpLog::GetInstance().SetDumpFile(std::move(ostream)); +} + +void AccessibilityHidumperTest::TearDownTestCase() +{ +} + +/** + * @tc.name: AccessibilityDfxTest001 + * @tc.desc: GetDumpInfoArgument + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest001, TestSize.Level1) +{ + std::vector params = {"-simplify", "--event-test", "12345", "678"}; + DumpInfoArgument arg; + + bool result = AccessibilityHidumper::GetDumpInfoArgument(params, arg); + + // suppose to parse event test normal + EXPECT_TRUE(result); + EXPECT_EQ(arg.mode, DumpMode::EVENT_TEST); + EXPECT_EQ(arg.nodeId, 12345); + EXPECT_EQ(arg.eventId, 678); +} + +/** + * @tc.name: AccessibilityDfxTest002 + * @tc.desc: GetDumpInfoArgument + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest002, TestSize.Level1) +{ + std::vector params = {"-inspector", "--event-test", "123"}; + DumpInfoArgument arg; + bool result = AccessibilityHidumper::GetDumpInfoArgument(params, arg); + + // suppose to parse event test fail + EXPECT_FALSE(result); +} + +/** + * @tc.name: AccessibilityDfxTest003 + * @tc.desc: DumpProcessInjectActionParameters + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest003, TestSize.Level1) +{ + std::vector params = {"-inspector", "--inject-action", "999", "--NotifyChildAction", "5"}; + int64_t nodeId = 0; + int32_t resultVal = 0; + InjectActionType actionType{}; + + bool ret = AccessibilityHidumper::DumpProcessInjectActionParameters( + params, nodeId, resultVal, actionType); + + // suppose to parse inject-action normal + EXPECT_TRUE(ret); + EXPECT_EQ(nodeId, 999); + EXPECT_EQ(resultVal, 5); + EXPECT_EQ(actionType, InjectActionType::NOTIFY_CHILD_ACTION); +} + +/** + * @tc.name: AccessibilityDfxTest004 + * @tc.desc: DumpProcessInjectActionParameters + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest004, TestSize.Level1) +{ + std::vector params = {"-inspector", "--NotifyChildAction"}; + int64_t nodeId = 0; + int32_t resultVal = 0; + InjectActionType actionType{}; + + // suppose to parse inject-action fail + bool ret = AccessibilityHidumper::DumpProcessInjectActionParameters( + params, nodeId, resultVal, actionType); + + EXPECT_FALSE(ret); +} +/** + * @tc.name: AccessibilityDfxTest005 + * @tc.desc: GetDumpInfoArgument + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest005, TestSize.Level1) +{ + std::vector params = {"-simplify", "-w", "-v", "-json"}; + DumpInfoArgument arg; + + bool result = AccessibilityHidumper::GetDumpInfoArgument(params, arg); + + // suppose to parse json type normal + EXPECT_TRUE(result); + EXPECT_TRUE(arg.isDumpSimplify); + EXPECT_TRUE(arg.useWindowId); + EXPECT_TRUE(arg.verbose); + EXPECT_EQ(arg.mode, DumpMode::TREE); +} +/** + * @tc.name: AccessibilityDfxTest006 + * @tc.desc: GetDumpInfoArgument + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest006, TestSize.Level1) +{ + std::vector params = {"-inspector", "--hover-test", "100", "200"}; + DumpInfoArgument arg; + + bool result = AccessibilityHidumper::GetDumpInfoArgument(params, arg); + + // suppose to parse hover-test normal + EXPECT_TRUE(result); + EXPECT_EQ(arg.mode, DumpMode::HOVER_TEST); + EXPECT_EQ(arg.pointX, 100); + EXPECT_EQ(arg.pointY, 200); +} +/** + * @tc.name: AccessibilityDfxTest007 + * @tc.desc: GetDumpInfoArgument + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest007, TestSize.Level1) +{ + std::vector params = {"-inspector", "--root", "987654321"}; + DumpInfoArgument arg; + + bool result = AccessibilityHidumper::GetDumpInfoArgument(params, arg); + + // suppose to parse root ID normal + EXPECT_TRUE(result); + EXPECT_EQ(arg.rootId, 987654321); +} + +/** + * @tc.name: AccessibilityDfxTest008 + * @tc.desc: GetDumpInfoArgument + * @tc.type: FUNC + */ +HWTEST_F(AccessibilityHidumperTest, AccessibilityDfxTest008, TestSize.Level1) +{ + std::vector params = {"12345"}; + DumpInfoArgument arg; + + bool result = AccessibilityHidumper::GetDumpInfoArgument(params, arg); + // suppose to parse fail + EXPECT_TRUE(result); +} +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/test/unittest/core/accessibility/js_accessibitlity_manager_test.cpp b/test/unittest/core/accessibility/js_accessibitlity_manager_test.cpp index 26c7df3b60e524d150507bac1e1258bb98e548ce..a38b2000defe89a569623816cf634d030bd6124c 100644 --- a/test/unittest/core/accessibility/js_accessibitlity_manager_test.cpp +++ b/test/unittest/core/accessibility/js_accessibitlity_manager_test.cpp @@ -816,9 +816,9 @@ HWTEST_F(JsAccessibilityManagerTest, JsAccessibilityManager016, TestSize.Level1) int64_t elementId = 0; int64_t rootId = 0; EXPECT_FALSE( - jsAccessibilityManager->CheckIsChildElement(elementId, params, info, Framework::DumpMode::TREE, rootId)); + jsAccessibilityManager->CheckIsChildElement(elementId, params, info, DumpMode::TREE, rootId)); EXPECT_FALSE( - jsAccessibilityManager->CheckIsChildElement(elementId, params, info, Framework::DumpMode::NODE, rootId)); + jsAccessibilityManager->CheckIsChildElement(elementId, params, info, DumpMode::NODE, rootId)); } /**