diff --git a/adapter/ohos/osal/js_accessibility_manager.cpp b/adapter/ohos/osal/js_accessibility_manager.cpp index 0cd479487dc..e45570a4b2e 100644 --- a/adapter/ohos/osal/js_accessibility_manager.cpp +++ b/adapter/ohos/osal/js_accessibility_manager.cpp @@ -65,6 +65,8 @@ constexpr int32_t UI_EXTENSION_OFFSET_MIN = 1000000; constexpr int32_t UI_EXTENSION_ID_21 = 21; constexpr int32_t UI_EXTENSION_ID_10 = 10; +constexpr int32_t UI_EXTENSION_LEVEL_MAX = 3; +constexpr int32_t UI_EXTENSION_LEVEL_OFFSET = 10; struct ActionTable { AceAction aceAction; @@ -1583,9 +1585,71 @@ bool JsAccessibilityManager::SendAccessibilitySyncEvent( eventInfo.SetItemCounts(static_cast(accessibilityEvent.itemCount)); eventInfo.SetBundleName(AceApplicationInfo::GetInstance().GetPackageName()); + auto pipeline = context_.Upgrade(); + CHECK_NULL_RETURN(pipeline, false); + RefPtr ngPipeline; + ngPipeline = AceType::DynamicCast(pipeline); + CHECK_NULL_RETURN(ngPipeline, false); + auto uiExtensionManager = ngPipeline->GetUIExtensionManager(); + CHECK_NULL_RETURN(uiExtensionManager, false); + if (uiExtensionManager->IsWindowTypeUIExtension(pipeline)) { + auto rootNode = ngPipeline->GetRootElement(); + CHECK_NULL_RETURN(rootNode, false); + auto node = GetInspectorById(rootNode, accessibilityEvent.nodeId); + CHECK_NULL_RETURN(node, false); + std::vector uiExtensionIdLevelList; + return node->SendAccessibilityEventInfo(eventInfo, uiExtensionIdLevelList, pipeline); + } + return client->SendEvent(eventInfo); } +bool JsAccessibilityManager::SendAccessibilitySyncEvent( + const AccessibilityEventInfo& eventInfo, std::vector& uiExtensionIdLevelList) +{ + if (!IsRegister()) { + return false; + } + + if (uiExtensionIdLevelList.size() > UI_EXTENSION_LEVEL_MAX) { + return false; + } + auto client = AccessibilitySystemAbilityClient::GetInstance(); + CHECK_NULL_RETURN(client, false); + bool isEnabled = false; + client->IsEnabled(isEnabled); + if (!isEnabled) { + return false; + } + + auto pipeline = context_.Upgrade(); + CHECK_NULL_RETURN(pipeline, false); + RefPtr ngPipeline; + ngPipeline = AceType::DynamicCast(pipeline); + CHECK_NULL_RETURN(ngPipeline, false); + auto uiExtensionManager = ngPipeline->GetUIExtensionManager(); + CHECK_NULL_RETURN(uiExtensionManager, false); + if (uiExtensionManager->IsWindowTypeUIExtension(pipeline)) { + auto rootNode = ngPipeline->GetRootElement(); + CHECK_NULL_RETURN(rootNode, false); + return rootNode->SendAccessibilityEventInfo(eventInfo, uiExtensionIdLevelList, pipeline); + } + + int32_t wrapLevelid = 0; + int32_t startLevelOffset = UI_EXTENSION_OFFSET_MAX; + for (auto uiExtensionId : uiExtensionIdLevelList) { + if ((startLevelOffset == UI_EXTENSION_OFFSET_MAX && uiExtensionId >= UI_EXTENSION_ID_21) || + (startLevelOffset != UI_EXTENSION_OFFSET_MAX && uiExtensionId >= UI_EXTENSION_ID_10)) { + return false; + } + wrapLevelid = wrapLevelid + uiExtensionId * startLevelOffset; + startLevelOffset = startLevelOffset / UI_EXTENSION_LEVEL_OFFSET; + } + AccessibilityEventInfo eventInfoNew = eventInfo; + eventInfoNew.SetSource(wrapLevelid + eventInfo.GetViewId()); + return client->SendEvent(eventInfoNew); +} + void JsAccessibilityManager::SendAccessibilityAsyncEvent(const AccessibilityEvent& accessibilityEvent) { auto context = GetPipelineContext().Upgrade(); diff --git a/adapter/ohos/osal/js_accessibility_manager.h b/adapter/ohos/osal/js_accessibility_manager.h index ed19935e813..522f5104601 100644 --- a/adapter/ohos/osal/js_accessibility_manager.h +++ b/adapter/ohos/osal/js_accessibility_manager.h @@ -92,7 +92,8 @@ public: void DeregisterInteractionOperation(); bool SendAccessibilitySyncEvent( const AccessibilityEvent& accessibilityEvent, Accessibility::AccessibilityEventInfo eventInfo); - + bool SendAccessibilitySyncEvent( + const Accessibility::AccessibilityEventInfo& eventInfo, std::vector& uiExtensionIdLevelList) override; void SearchElementInfoByAccessibilityId(const int32_t elementId, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode, const int32_t windowId); void SearchElementInfosByText(const int32_t elementId, const std::string& text, const int32_t requestId, diff --git a/frameworks/core/accessibility/accessibility_manager.h b/frameworks/core/accessibility/accessibility_manager.h index 12ecdbf65f4..c0470049017 100644 --- a/frameworks/core/accessibility/accessibility_manager.h +++ b/frameworks/core/accessibility/accessibility_manager.h @@ -23,7 +23,8 @@ namespace OHOS::Accessibility { class AccessibilityElementInfo; -} +class AccessibilityEventInfo; +} // namespace OHOS::Accessibility namespace OHOS::Ace { @@ -97,6 +98,11 @@ public: const RefPtr& context, const int32_t uiExtensionOffset = 0) = 0; virtual bool ExecuteExtensionActionNG(int32_t elementId, const std::map& actionArguments, int32_t action, const RefPtr& context, int32_t uiExtensionOffset) = 0; + virtual bool SendAccessibilitySyncEvent( + const Accessibility::AccessibilityEventInfo& eventInfo, std::vector& uiExtensionIdLevelList) + { + return false; + } #endif void SetVersion(AccessibilityVersion version) { diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index ee3d7a26e2c..170d7f3e86d 100644 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -2810,6 +2810,7 @@ void FrameNode::FocusMoveSearchNG(int32_t elementId, int32_t direction, pattern_->FocusMoveSearch(elementId, direction, offset, output); } } + bool FrameNode::TransferExecuteAction(int32_t elementId, const std::map& actionArguments, int32_t action, int32_t offset) { @@ -2819,4 +2820,13 @@ bool FrameNode::TransferExecuteAction(int32_t elementId, const std::map& uiExtensionIdLevelList, const RefPtr& pipeline) +{ + if (pattern_) { + return pattern_->SendAccessibilityEventInfo(eventInfo, uiExtensionIdLevelList, pipeline); + } + return false; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/base/frame_node.h b/frameworks/core/components_ng/base/frame_node.h index 7e35c222ef6..5c3745e17e8 100644 --- a/frameworks/core/components_ng/base/frame_node.h +++ b/frameworks/core/components_ng/base/frame_node.h @@ -51,6 +51,7 @@ namespace OHOS::Accessibility { class AccessibilityElementInfo; +class AccessibilityEventInfo; } namespace OHOS::Ace::NG { @@ -606,6 +607,9 @@ public: int32_t offset, Accessibility::AccessibilityElementInfo& output); bool TransferExecuteAction(int32_t elementId, const std::map& actionArguments, int32_t action, int32_t offset); + bool SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo& eventInfo, + std::vector& uiExtensionIdLevelList, const RefPtr& pipeline); + private: void MarkNeedRender(bool isRenderBoundary); std::pair ContextPositionConvertToPX( diff --git a/frameworks/core/components_ng/pattern/pattern.h b/frameworks/core/components_ng/pattern/pattern.h index 825a558aaa0..b5b1afd9a60 100644 --- a/frameworks/core/components_ng/pattern/pattern.h +++ b/frameworks/core/components_ng/pattern/pattern.h @@ -31,6 +31,7 @@ namespace OHOS::Accessibility { class AccessibilityElementInfo; +class AccessibilityEventInfo; } namespace OHOS::Ace::NG { @@ -419,11 +420,17 @@ public: int32_t baseParent, Accessibility::AccessibilityElementInfo& output) {} virtual void FocusMoveSearch(int32_t elementId, int32_t direction, int32_t baseParent, Accessibility::AccessibilityElementInfo& output) {} - virtual bool TransferExecuteAction(int32_t elementId, const std::map& actionArguments, - int32_t action, int32_t offset) + virtual bool TransferExecuteAction( + int32_t elementId, const std::map& actionArguments, int32_t action, int32_t offset) { return false; } + virtual bool SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo& eventInfo, + std::vector& uiExtensionIdLevelList, const RefPtr& pipeline) + { + return false; + } + virtual int32_t GetUiExtensionId() { return -1; diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.cpp b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.cpp index 7d6e181fa15..ee6a22f63e1 100644 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.cpp +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.cpp @@ -15,6 +15,8 @@ #include "core/components_ng/pattern/ui_extension/ui_extension_manager.h" #include "core/components_ng/pattern/ui_extension/ui_extension_pattern.h" +#include "adapter/ohos/entrance/ace_container.h" + namespace OHOS::Ace::NG { namespace { constexpr int32_t UI_EXTENSION_OFFSET_MIN = 1000000; @@ -37,6 +39,13 @@ bool UIExtensionManager::IsWrapExtensionAbilityId(int32_t elementId) return elementId > UI_EXTENSION_OFFSET_MIN; } +bool UIExtensionManager::IsWindowTypeUIExtension(const RefPtr& pipeline) +{ + auto instanceId = pipeline->GetInstanceId(); + auto window = Platform::AceContainer::GetUIWindow(instanceId); + return window->GetType() == OHOS::Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION; +} + std::pair UIExtensionManager::UnWrapExtensionAbilityId( int32_t extensionOffset, int32_t elementId) { diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.h b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.h index 8f172c8da5b..726520c532e 100644 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.h +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_manager.h @@ -33,6 +33,7 @@ public: bool OnBackPressed(); const RefPtr GetFocusUiExtensionNode(); bool IsWrapExtensionAbilityId(int32_t elementId); + bool IsWindowTypeUIExtension(const RefPtr& pipeline); std::pair UnWrapExtensionAbilityId(int32_t extensionOffset, int32_t elementId); private: diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp index 0978f9d120e..a553ac652bf 100755 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.cpp @@ -94,6 +94,22 @@ public: }, TaskExecutor::TaskType::UI); } + void OnAccessibilityEvent( + const Accessibility::AccessibilityEventInfo& info, const std::vector& uiExtensionIdLevelList) override + { + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto taskExecutor = pipeline->GetTaskExecutor(); + CHECK_NULL_VOID(taskExecutor); + taskExecutor->PostTask( + [weak = uiExtensionPattern_, &info, uiExtensionIdLevelList]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + pattern->OnAccessibilityEvent(info, uiExtensionIdLevelList); + }, + TaskExecutor::TaskType::UI); + } + private: int32_t instanceId_; WeakPtr uiExtensionPattern_; @@ -204,6 +220,32 @@ void UIExtensionPattern::OnConnect() } } +void UIExtensionPattern::OnAccessibilityEvent( + const Accessibility::AccessibilityEventInfo& info, std::vector uiExtensionIdLevelList) +{ + CHECK_RUN_ON(UI); + LOGI("UIExtension OnAccessibilityEvent called"); + CHECK_NULL_VOID(session_); + ContainerScope scope(instanceId_); + auto container = AceType::DynamicCast(Container::Current()); + CHECK_NULL_VOID(container); + auto pipelineContext = container->GetPipelineContext(); + auto ngPipeline = AceType::DynamicCast(pipelineContext); + if (ngPipeline) { + auto window = container->GetUIWindow(instanceId_); + CHECK_NULL_VOID(window); + if (window->GetType() == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION) { + uiExtensionIdLevelList.insert(uiExtensionIdLevelList.begin(), uiExtensionId_); + } + auto frontend = container->GetFrontend(); + CHECK_NULL_VOID(frontend); + auto accessibilityManager = frontend->GetAccessibilityManager(); + if (accessibilityManager) { + accessibilityManager->SendAccessibilitySyncEvent(info, uiExtensionIdLevelList); + } + } +} + void UIExtensionPattern::OnDisconnect() { CHECK_RUN_ON(UI); @@ -894,6 +936,16 @@ void UIExtensionPattern::FocusMoveSearch(int32_t elementId, int32_t direction, session_->TransferFocusMoveSearch(elementId, direction, baseParent, output); } +bool UIExtensionPattern::SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo& eventInfo, + std::vector& uiExtensionIdLevelList, const RefPtr& pipeline) +{ + auto instanceId = pipeline->GetInstanceId(); + auto window = Platform::AceContainer::GetUIWindow(instanceId); + CHECK_NULL_RETURN(window, false); + OHOS::Rosen::WMError ret = window->TransferAccessibilityEvent(eventInfo, uiExtensionIdLevelList); + return ret == OHOS::Rosen::WMError::WM_OK; +} + void UIExtensionPattern::ProcessUIExtensionSessionActivationResult(OHOS::Rosen::WSError errcode) { if (errcode != OHOS::Rosen::WSError::WS_OK) { diff --git a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h index 7724e3e3c13..2711473667d 100644 --- a/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h +++ b/frameworks/core/components_ng/pattern/ui_extension/ui_extension_pattern.h @@ -37,8 +37,9 @@ enum class WSError; } // namespace OHOS::Rosen namespace OHOS::Accessibility { - class AccessibilityElementInfo; -} +class AccessibilityElementInfo; +class AccessibilityEventInfo; +} // namespace OHOS::Accessibility namespace OHOS::MMI { class KeyEvent; @@ -107,6 +108,8 @@ public: int32_t baseParent, Accessibility::AccessibilityElementInfo& output) override; virtual bool TransferExecuteAction(int32_t elementId, const std::map& actionArguments, int32_t action, int32_t offset) override; + virtual bool SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo& eventInfo, + std::vector& uiExtensionIdLevelList, const RefPtr& pipeline) override; int32_t GetSessionId(); @@ -118,6 +121,9 @@ public: return contentNode_; } + void OnAccessibilityEvent( + const Accessibility::AccessibilityEventInfo& info, std::vector uiExtensionIdLevelList); + private: enum ReleaseCode { DESTROY_NORMAL = 0, diff --git a/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp b/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp index 2c9a7aebfa0..ace2ffc7178 100644 --- a/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp +++ b/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp @@ -74,6 +74,9 @@ public: void OnExtensionDied() override {} + void OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info, + const std::vector& uiExtensionIdLevelVec) override {}; + private: WeakPtr windowPattern_; }; diff --git a/test/mock/adapter/mock_ace_container.cpp b/test/mock/adapter/mock_ace_container.cpp index 408ec773dfb..f73bae48b06 100644 --- a/test/mock/adapter/mock_ace_container.cpp +++ b/test/mock/adapter/mock_ace_container.cpp @@ -31,4 +31,9 @@ std::shared_ptr AceContainer::GetAbilityContextByModule { return nullptr; } + +sptr AceContainer::GetUIWindow(int32_t instanceId) +{ + return nullptr; +} } // namespace OHOS::Ace::Platform