diff --git a/adapter/ohos/osal/js_accessibility_manager.cpp b/adapter/ohos/osal/js_accessibility_manager.cpp index 89d8aa1b6c13c9f2b3ab9e8e9920bfc8eb5fef19..dcf1e011f46cc7f98f949ab7ebf173e41df5953b 100644 --- a/adapter/ohos/osal/js_accessibility_manager.cpp +++ b/adapter/ohos/osal/js_accessibility_manager.cpp @@ -2425,6 +2425,11 @@ void JsAccessibilityManager::UpdateCacheInfoNG(std::list& eventList) +{ + eventWhiteList_ = eventList; +} + namespace { bool CanAccessibilityFocusedNG(const RefPtr& node) { @@ -3092,6 +3097,7 @@ JsAccessibilityManager::~JsAccessibilityManager() { UnsubscribeStateObserver(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED); UnsubscribeStateObserver(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED); + UnsubscribeStateObserver(AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED); DeregisterInteractionOperation(); } @@ -3200,7 +3206,12 @@ void JsAccessibilityManager::InitializeCallback() bool isEnabled = false; client->IsEnabled(isEnabled); AceApplicationInfo::GetInstance().SetAccessibilityEnabled(isEnabled); + + client->SearchNeedEvents(eventWhiteList_); + + SubscribeStateObserver(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED); SubscribeStateObserver(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED); + SubscribeStateObserver(AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED); auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId()); if (container != nullptr && container->IsDynamicRender()) { @@ -3219,7 +3230,6 @@ void JsAccessibilityManager::InitializeCallback() return; } - SubscribeStateObserver(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED); if (isEnabled) { RegisterInteractionOperation(windowId_); } @@ -3947,9 +3957,17 @@ bool JsAccessibilityManager::IsEventIgnoredByWorkMode(const AccessibilityEvent& void JsAccessibilityManager::SendEventToAccessibilityWithNode( const AccessibilityEvent& accessibilityEvent, const RefPtr& node, const RefPtr& context) { + auto eventType = GetEventTypeByAccessibilityEvent(accessibilityEvent); + if (!CheckWhiteList(eventType)) { + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, + "send accessibility check whitelist failed event:%{public}d" PRId64, eventType); + return; + } + if (IsEventIgnoredByWorkMode(accessibilityEvent) || !IsSendAccessibilityEvent(accessibilityEvent)) { return; } + auto delayTime = GetDelayTimeBeforeSendEvent(accessibilityEvent, node); if ((delayTime > 0) && context) { context->GetTaskExecutor()->PostDelayedTask( @@ -4032,9 +4050,16 @@ void GetRealEventWindowId( void JsAccessibilityManager::SendAccessibilityAsyncEvent(const AccessibilityEvent& accessibilityEvent) { + auto eventType = GetEventTypeByAccessibilityEvent(accessibilityEvent); + if (!CheckWhiteList(eventType)) { + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, + "send accessibility check whitelist failed event:%{public}d" PRId64, eventType); + return; + } if (IsEventIgnoredByWorkMode(accessibilityEvent) || !IsSendAccessibilityEvent(accessibilityEvent)) { return; } + auto delayTime = GetDelayTimeBeforeSendEvent(accessibilityEvent, nullptr); if (delayTime > 0) { auto context = GetPipelineContext().Upgrade(); @@ -4399,6 +4424,65 @@ bool DumpProcessEmbedHoverParameters( } return false; } + +bool DumpProcessSpecificSearchParameters( + const std::vector& params, + int64_t& nodeId, + std::string& propertyTarget, + int32_t& propertyType) +{ + constexpr int32_t NUM_PARAMETERS_DIMENSION = 3; + if (params.size() < 2) { + return false; + } + + for (auto arg = params.begin() + 1; arg != params.end(); ++arg) { + if (*arg == "--specific-search") { + 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); + ++arg; + propertyTarget = *arg; + ++arg; + propertyType = StringUtils::StringToInt(*arg); + return true; + } + } + return false; +} + +bool DumpProcessSetCheckListParameters( + const std::vector& params, + std::vector& vec) +{ + if (params.size() < 2) { + return false; + } + auto arg = params.begin() + 1; + if (*arg != "--set-whitelist") { + return false; + } + for (++arg; arg != params.end(); ) { + vec.emplace_back(StringUtils::StringToUint(*arg++)); + } + return true; +} + +bool DumpProcessGetCheckListParameters( + const std::vector& params) +{ + if (params.size() < 2) { + return false; + } + auto arg = params.begin() + 1; + if (*arg != "--get-whitelist") { + return false; + } + return true; +} } // DFX related void JsAccessibilityManager::DumpInjectActionTest(const std::vector& params) @@ -4534,6 +4618,68 @@ void JsAccessibilityManager::DumpEmbedHoverTestNG(const std::vector accessibilityManagerNG->HandleAccessibilityHoverEventBySurfaceId(surfaceId, param); } +void JsAccessibilityManager::DumpSpecificPropertySearchTest(const std::vector& params, uint32_t windowId) +{ + int64_t nodeId = INVALID_NODE_ID; + std::string propertyTarget; + int32_t propertyType = 0; + if (!DumpProcessSpecificSearchParameters(params, nodeId, propertyTarget, propertyType)) { + return; + } + + if (propertyType != SEARCH_TYPE::CUSTOMID) { + return; + } + + auto pipeline = GetPipelineByWindowId(windowId); + CHECK_NULL_VOID(pipeline); + auto ngPipeline = AceType::DynamicCast(pipeline); + CHECK_NULL_VOID(ngPipeline); + + RefPtr frameNode; + ngPipeline = FindPipelineByElementId(nodeId, frameNode); + CHECK_NULL_VOID(frameNode); + + std::list infos; + std::list treeInfos; + SpecificPropertyParam propertyParam { + .propertyTarget = propertyTarget, .propertyType = static_cast(propertyType)}; + SearchElementInfoByCustomIdNG(nodeId, propertyParam.propertyTarget, infos, treeInfos, ngPipeline); + DumpLog::GetInstance().Print(std::string("customId search start")); + DumpLog::GetInstance().Print("info size: " + std::to_string(infos.size())); + for (const auto& info : infos) { + DumpLog::GetInstance().Print("info Element ID: " + std::to_string(info.GetAccessibilityId())); + } + DumpLog::GetInstance().Print("treeInfos size: " + std::to_string(treeInfos.size())); + for (const auto& treeInfo : treeInfos) { + DumpLog::GetInstance().Print("treeInfo Element ID " + std::to_string(treeInfo.GetAccessibilityId())); + } + DumpLog::GetInstance().Print(std::string("Result: customId search done")); +} + +void JsAccessibilityManager::DumpSetCheckListTest(const std::vector& params) +{ + std::vector vec; + if (!DumpProcessSetCheckListParameters(params, vec)) { + return; + } + UpdateEventWhiteList(vec); + DumpLog::GetInstance().Print("white list size: " + std::to_string(eventWhiteList_.size())); + DumpLog::GetInstance().Print(std::string("Result: Set White List Done")); +} + +void JsAccessibilityManager::DumpGetCheckListTest(const std::vector& params) +{ + if (!DumpProcessGetCheckListParameters(params)) { + return; + } + DumpLog::GetInstance().Print("white list size: " + std::to_string(eventWhiteList_.size())); + for (const auto& event : eventWhiteList_) { + DumpLog::GetInstance().Print("white list No: "+ std::to_string(event)); + } + DumpLog::GetInstance().Print(std::string("Result: Get White List Done")); +} + void JsAccessibilityManager::DumpTreeNG(bool useWindowId, uint32_t windowId, int64_t rootId, bool isDumpSimplify) { if (!useWindowId && rootId == -1) { @@ -4692,6 +4838,15 @@ bool JsAccessibilityManager::GetDumpInfoArgument(const std::vector& } 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") { @@ -4751,6 +4906,15 @@ void JsAccessibilityManager::OnDumpInfoNG(const std::vector& params case DumpMode::EMBED_HOVER_TEST: DumpEmbedHoverTestNG(params, windowId); break; + case DumpMode::SET_CHECKLIST_TEST: + DumpSetCheckListTest(params); + break; + case DumpMode::GET_CHECKLIST_TEST: + DumpGetCheckListTest(params); + break; + case DumpMode::SPECIFIC_SEARCH_TEST: + DumpSpecificPropertySearchTest(params, windowId); + break; default: DumpLog::GetInstance().Print("Error: invalid arguments!"); break; @@ -5421,7 +5585,7 @@ RetError JsAccessibilityManager::JsInteractionOperation::SearchElementInfoByAcce if (!jsAccessibilityManager) { std::list infos; callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId); - TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d", + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d", requestId); return RET_OK; } @@ -5429,7 +5593,7 @@ RetError JsAccessibilityManager::JsInteractionOperation::SearchElementInfoByAcce if (!context) { std::list infos; callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId); - TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d", + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d", requestId); return RET_OK; } @@ -5440,7 +5604,7 @@ RetError JsAccessibilityManager::JsInteractionOperation::SearchElementInfoByAcce if (!jsAccessibilityManager) { std::list infos; callback.SetSearchElementInfoByAccessibilityIdResult(infos, requestId); - TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoByAccessibilityIdResult, requestId: %{public}d", requestId); return; } @@ -5451,6 +5615,66 @@ RetError JsAccessibilityManager::JsInteractionOperation::SearchElementInfoByAcce TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoById"); return RET_OK; } + +void JsAccessibilityManager::JsInteractionOperation::SearchElementInfoBySpecificProperty(const int64_t elementId, + const SpecificPropertyParam ¶m, const int32_t requestId, AccessibilityElementOperatorCallback &callback) +{ + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ArkUI search by id: %{public}" PRId64 ", target: %{public}s," + "type: %{public}d", elementId, param.propertyTarget.c_str(), param.propertyType); + + int64_t splitElementId = AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID; + int32_t splitTreeId = AccessibilityElementInfo::UNDEFINED_TREE_ID; + AccessibilitySystemAbilityClient::GetTreeIdAndElementIdBySplitElementId(elementId, splitElementId, splitTreeId); + + auto jsAccessibilityManager = GetHandler().Upgrade(); + if (!jsAccessibilityManager) { + std::list infos; + std::list treeInfos; + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d", + requestId); + return; + } + + auto windowId = windowId_; + auto context = jsAccessibilityManager->GetPipelineContext().Upgrade(); + if (!context) { + std::list infos; + std::list treeInfos; + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d", + requestId); + return; + } + auto executor = context->GetTaskExecutor(); + if(!executor) { + std::list infos; + std::list treeInfos; + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, + "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d", + requestId); + return; + } + + executor->PostTask( + [weak = GetHandler(), splitElementId, ¶m, requestId, &callback, windowId]() { + auto jsAccessibilityManager = weak.Upgrade(); + if (!jsAccessibilityManager) { + std::list infos; + std::list treeInfos; + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, + "SetSearchElementInfoBySpecificPropertyResult, requestId: %{public}d", requestId); + } + ACE_SCOPED_TRACE("SearchElementInfoBySpecificProperty"); + jsAccessibilityManager->SearchElementInfoBySpecificProperty( + splitElementId, param, requestId, callback, windowId); + }, + TaskExecutor::TaskType::UI, "ArkUIAccessibilitySearchElementInfoByProperty"); + return; +} + #ifdef WEB_SUPPORTED RetError JsAccessibilityManager::WebInteractionOperation::SearchElementInfoByAccessibilityId(const int64_t elementId, @@ -5487,6 +5711,15 @@ RetError JsAccessibilityManager::WebInteractionOperation::SearchElementInfoByAcc return RET_OK; } +void JsAccessibilityManager::WebInteractionOperation::SearchElementInfoBySpecificProperty( + const int64_t elementId, const SpecificPropertyParam ¶m, const int32_t requestId, + AccessibilityElementOperatorCallback &callback) +{ + std::list infos; + std::list treeInfos; + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); +} + void JsAccessibilityManager::WebInteractionOperation::SearchElementInfosByText(const int64_t elementId, const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback) { @@ -5720,6 +5953,78 @@ void JsAccessibilityManager::SearchElementInfoByAccessibilityIdNG(int64_t elemen UpdateWebEmbedParent(infos, node, commonProperty); } +void JsAccessibilityManager::SearchElementInfoByCustomIdNG(const int64_t elementId, const std::string &customId, + std::list &infos, std::list &treeInfos, + const RefPtr& context) +{ + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", customId: %{public}s", + elementId, customId.c_str()); + auto mainContext = context_.Upgrade(); + CHECK_NULL_VOID(mainContext); + + auto ngPipeline = AceType::DynamicCast(context); + CHECK_NULL_VOID(ngPipeline); + auto rootNode = ngPipeline->GetRootElement(); + CHECK_NULL_VOID(rootNode); + + CommonProperty commonProperty; + GenerateCommonProperty(ngPipeline, commonProperty, mainContext, rootNode); + int64_t nodeId = elementId; + if (elementId == -1) { + nodeId = rootNode->GetAccessibilityId(); + } + auto node = GetFramenodeByAccessibilityId(rootNode, elementId); + CHECK_NULL_VOID(node); + + std::list> children { node }; + while (!children.empty()) { + auto checkNode = children.front(); + children.pop_front(); + if (checkNode->GetInspectorId().value_or("") == customId) { + AccessibilityElementInfo nodeInfo; + UpdateAccessibilityElementInfo(checkNode, commonProperty, nodeInfo, ngPipeline); + SetRootAccessibilityVisible(checkNode, nodeInfo); + SetRootAccessibilityNextFocusId(checkNode, rootNode, nodeInfo); + SetRootAccessibilityPreFocusId(checkNode, rootNode, nodeInfo, + nextFocusMapWithSubWindow_[context->GetInstanceId()]); + infos.emplace_back(nodeInfo); + treeInfos.clear(); + break; + } +#ifdef WINDOW_SCENE_SUPPORTED + auto nodeId = checkNode->GetAccessibilityId(); + auto uiExtensionManager = ngPipeline->GetUIExtensionManager(); + if (uiExtensionManager && uiExtensionManager->IsWrapExtensionAbilityId(nodeId)) { + std::list ueaInfos; + int32_t mode = static_cast(PREFETCH_RECURSIVE_CHILDREN); + SearchParameter param {nodeId, "", mode, NG::UI_EXTENSION_OFFSET_MAX}; + SearchExtensionElementInfoByAccessibilityIdNG(param, rootNode, ueaInfos, context, ngPipeline); + for (auto& ueaInfo : ueaInfos) { + if (ueaInfo.GetInspectorKey() == customId) { + infos.emplace_back(ueaInfo); + treeInfos.clear(); + break; + } + } + if (!infos.empty()) { + break; + } + } +#endif + auto accessibilityProperty = checkNode->GetAccessibilityProperty(); + if (accessibilityProperty && accessibilityProperty->GetChildTreeId() != -1) { + AccessibilityElementInfo nodeInfo; + UpdateAccessibilityElementInfo(checkNode, commonProperty, nodeInfo, ngPipeline); + SetRootAccessibilityVisible(checkNode, nodeInfo); + SetRootAccessibilityNextFocusId(checkNode, rootNode, nodeInfo); + SetRootAccessibilityPreFocusId(checkNode, rootNode, nodeInfo, + nextFocusMapWithSubWindow_[context->GetInstanceId()]); + treeInfos.emplace_back(nodeInfo); + } + GetChildrenFromFrameNode(checkNode, children, commonProperty); + } +} + void JsAccessibilityManager::SearchExtensionElementInfoByAccessibilityIdNG(const SearchParameter& searchParam, const RefPtr& node, std::list& infos, const RefPtr& context, const RefPtr& ngPipeline) @@ -5793,6 +6098,31 @@ void JsAccessibilityManager::SearchElementInfosByTextNG(const SearchParameter& s #endif } +void JsAccessibilityManager::SearchElementInfoBySpecificProperty(const int64_t elementId, + const SpecificPropertyParam ¶m, const int32_t requestId, + AccessibilityElementOperatorCallback &callback, const int32_t windowId) +{ + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", propType: %{public}d," + "propTarget: %{public}s", elementId, param.propertyType, param.propertyTarget.c_str()); + std::list infos; + std::list treeInfos; + + auto pipeline = GetPipelineByWindowId(windowId); + if (pipeline) { + auto ngPipeline = AceType::DynamicCast(pipeline); + if (ngPipeline) { + if (param.propertyType == SEARCH_TYPE::CUSTOMID) { + SearchElementInfoByCustomIdNG(elementId, param.propertyTarget, infos, treeInfos, pipeline); + } + } else { + SearchAccessibilityNodeBySpecificProperty(elementId, param, requestId, callback, windowId); + } + } + + SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId); + return; +} + RefPtr JsAccessibilityManager::FindNodeFromRootByExtensionId( const RefPtr& root, const int64_t uiExtensionId) { @@ -6196,13 +6526,13 @@ void JsAccessibilityManager::JsInteractionOperation::ExecuteAction(const int64_t auto jsAccessibilityManager = GetHandler().Upgrade(); if (!jsAccessibilityManager) { - TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId); callback.SetExecuteActionResult(false, requestId); return; } auto context = jsAccessibilityManager->GetPipelineContext().Upgrade(); if (!context) { - TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId); callback.SetExecuteActionResult(false, requestId); return; } @@ -6213,7 +6543,7 @@ void JsAccessibilityManager::JsInteractionOperation::ExecuteAction(const int64_t [weak = GetHandler(), splitElementId, param, requestId, &callback, windowId] { auto jsAccessibilityManager = weak.Upgrade(); if (!jsAccessibilityManager) { - TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "ExecuteAction failed, requestId: %{public}d", requestId); callback.SetExecuteActionResult(false, requestId); return; } @@ -7532,15 +7862,25 @@ void JsAccessibilityManager::JsAccessibilityStateObserver::OnStateChanged(const { TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "accessibility state changed:%{public}d, event type:%{public}u", state, eventType_); - - // Do not upgrade jsAccessibilityManager on async thread, destructor will cause freeze auto pipelineRef = pipeline_.Upgrade(); CHECK_NULL_VOID(pipelineRef); pipelineRef->GetTaskExecutor()->PostTask( [weak = accessibilityManager_, state, eventType = eventType_]() { auto jsAccessibilityManager = weak.Upgrade(); CHECK_NULL_VOID(jsAccessibilityManager); + if (eventType == AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED) { + auto client = AccessibilitySystemAbilityClient::GetInstance(); + if (client) { + std::vector needEvents; + client->SearchNeedEvents(needEvents); + jsAccessibilityManager->UpdateEventWhiteList(needEvents); + } + auto pipelineRef = jsAccessibilityManager->GetPipelineContext().Upgrade(); + CHECK_NULL_VOID(pipelineRef); + if (jsAccessibilityManager->ShouldSkipAccessibilityStateChange(pipelineRef)) { + return; + } if (state) { jsAccessibilityManager->RegisterInteractionOperation(jsAccessibilityManager->GetWindowId()); } else { @@ -7549,8 +7889,20 @@ void JsAccessibilityManager::JsAccessibilityStateObserver::OnStateChanged(const AceApplicationInfo::GetInstance().SetAccessibilityEnabled(state); jsAccessibilityManager->NotifyAccessibilitySAStateChange(state); } else if (eventType == AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED) { + auto pipelineRef = jsAccessibilityManager->GetPipelineContext().Upgrade(); + CHECK_NULL_VOID(pipelineRef); + if (jsAccessibilityManager->ShouldSkipAccessibilityStateChange(pipelineRef)) { + return; + } + jsAccessibilityManager->isScreenReaderEnabledInitialized_ = true; jsAccessibilityManager->isScreenReaderEnabled_ = state; + } else if (eventType == AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED) { + std::vector needEvents; + auto client = AccessibilitySystemAbilityClient::GetInstance(); + CHECK_NULL_VOID(client); + client->SearchNeedEvents(needEvents); + jsAccessibilityManager->UpdateEventWhiteList(needEvents); } }, TaskExecutor::TaskType::UI, "ArkUIAccessibilityStateChanged"); @@ -7580,6 +7932,24 @@ void JsAccessibilityManager::JsInteractionOperation::FocusMoveSearch( TaskExecutor::TaskType::UI, "ArkUIAccessibilityFocusMoveSearch"); } +bool JsAccessibilityManager::ShouldSkipAccessibilityStateChange(const RefPtr& pipelineRef) +{ + CHECK_NULL_RETURN(pipelineRef, true); + auto pipelineContext = AceType::DynamicCast(pipelineRef); + CHECK_NULL_RETURN(pipelineContext, true); + auto container = Platform::AceContainer::GetContainer(pipelineContext->GetInstanceId()); + if (container != nullptr && container->IsDynamicRender()) { + return true; + } + if (pipelineContext->IsFormRender() || pipelineContext->IsJsCard() || pipelineContext->IsJsPlugin()) { + return true; + } + if (container != nullptr && container->IsUIExtensionWindow()) { + return true; + } + return false; +} + void JsAccessibilityManager::FocusMoveSearch(const int64_t elementId, const int32_t direction, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId) { @@ -8012,6 +8382,31 @@ void JsAccessibilityManager::SetSearchElementInfoByAccessibilityIdResult(Accessi }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoById"); } +void JsAccessibilityManager::SetSearchElementInfoByCustomIdResult(AccessibilityElementOperatorCallback& callback, + std::list &infos, const std::list &treeInfos, + const int32_t requestId) +{ + if (!IsRegister()) { + return; + } + auto context = GetPipelineContext().Upgrade(); + CHECK_NULL_VOID(context); + context->GetTaskExecutor()->PostTask( + [weak = WeakClaim(this), infos = std::move(infos), treeInfos = std::move(treeInfos), + &callback, requestId] () mutable { + auto jsAccessibilityManager = weak.Upgrade(); + CHECK_NULL_VOID(jsAccessibilityManager); + TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "winId: %{public}d, treeId: %{public}d, reqId: %{public}d", + jsAccessibilityManager->windowId_, jsAccessibilityManager->treeId_, requestId); + if (!jsAccessibilityManager->IsRegister()) { + return; + } + jsAccessibilityManager->UpdateElementInfosTreeId(infos); + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); + }, TaskExecutor::TaskType::BACKGROUND, "ArkUIAccessibilitySetSearchElementInfoById"); + return; +} + void JsAccessibilityManager::SetSearchElementInfoByTextResult(AccessibilityElementOperatorCallback& callback, std::list&& infos, const int32_t requestId) { @@ -8679,4 +9074,81 @@ void JsAccessibilityManager::RemoveWebPatternBySurfaceId(const std::string& surf } } } + +bool JsAccessibilityManager::CheckWhiteList(const uint32_t& eventType) +{ + auto whiteList = eventWhiteList_; + if (whiteList.size() == 0) { + return true; + } + + if (whiteList.size() == 1) { + if (whiteList[0] == Accessibility::EventType::TYPE_VIEW_INVALID) { + return false; + } + else if (whiteList[0] == Accessibility::EventType::TYPES_ALL_MASK) { + return true; + } + } + return std::find(whiteList.begin(), whiteList.end(), eventType) != whiteList.end(); +} + +void JsAccessibilityManager::SearchAccessibilityNodeBySpecificProperty(const int64_t elementId, + const SpecificPropertyParam ¶m, const int32_t requestId, + AccessibilityElementOperatorCallback &callback, const int32_t windowId) +{ + std::list infos; + std::list treeInfos; + + if (param.propertyType != SEARCH_TYPE::CUSTOMID) { + SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId); + return; + } + + auto pipeline = GetPipelineByWindowId(windowId); + auto ngPipeline = AceType::DynamicCast(pipeline); + if(!ngPipeline) { + SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId); + return; + } + auto rootNode = ngPipeline->GetRootElement(); + + if(!ngPipeline) { + SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId); + return; + } + + int64_t nodeId = elementId; + if (elementId == -1) { + nodeId = rootNode->GetAccessibilityId(); + } + auto weak = WeakClaim(this); + auto jsAccessibilityManager = weak.Upgrade(); + CHECK_NULL_VOID(jsAccessibilityManager); + auto node = jsAccessibilityManager->GetAccessibilityNodeFromPage(nodeId); + if (!node) { + SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId); + return; + } + std::list nodeInfos; + AccessibilityElementInfo nodeInfo; + UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager, jsAccessibilityManager->windowId_); + nodeInfos.push_back(nodeInfo); + // cache parent/siblings/children infos + UpdateCacheInfo( + infos, + static_cast(PREFETCH_RECURSIVE_CHILDREN), + node, + jsAccessibilityManager, + jsAccessibilityManager->windowId_); + + for (auto& nodeInfo : nodeInfos) { + if (nodeInfo.GetInspectorKey() == param.propertyTarget) { + infos.emplace_back(nodeInfo); + break; + } + } + SetSearchElementInfoByCustomIdResult(callback, infos, treeInfos, requestId); + return; +} } // namespace OHOS::Ace::Framework diff --git a/adapter/ohos/osal/js_accessibility_manager.h b/adapter/ohos/osal/js_accessibility_manager.h index bec7d5b8aa0cb34bde2b67a3bf48f30c01198d86..a264a2b4508c62c79498bc5a5ac5ed93cefdfb6c 100644 --- a/adapter/ohos/osal/js_accessibility_manager.h +++ b/adapter/ohos/osal/js_accessibility_manager.h @@ -119,6 +119,9 @@ enum class DumpMode { INJECT_ACTION_TEST, EMBED_SEARCH_TEST, EMBED_HOVER_TEST, + SET_CHECKLIST_TEST, + GET_CHECKLIST_TEST, + SPECIFIC_SEARCH_TEST, }; struct DumpInfoArgument { @@ -272,12 +275,15 @@ public: int64_t uiExtensionOffset) override; void SearchElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode, const int32_t windowId); + void SearchElementInfoBySpecificProperty(const int64_t elementId, const SpecificPropertyParam ¶m, + const int32_t requestId, AccessibilityElementOperatorCallback &callback, const int32_t windowId); void SearchElementInfosByText(const int64_t elementId, const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId); void SearchDefaultFocusByWindowId(const int32_t windowId, int32_t pageId, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback); void FindFocusedElementInfo(const int64_t elementId, const int32_t focusType, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId); + bool ShouldSkipAccessibilityStateChange(const RefPtr& pipelineRef); void FocusMoveSearch(const int64_t elementId, const int32_t direction, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t windowId); bool IsUpdateWindowSceneInfo(const RefPtr& node, NG::WindowSceneInfo& windowSceneInfo); @@ -290,6 +296,9 @@ public: void SearchElementInfoByAccessibilityIdNG(int64_t elementId, int32_t mode, std::list& infos, const RefPtr& context, const int64_t uiExtensionOffset = 0) override; + void SearchElementInfoByCustomIdNG(const int64_t elementId, const std::string &customId, + std::list &infos, std::list &treeInfos, + const RefPtr& context); void SearchDefaultFocusByWindowIdNG(const int32_t pageId, std::list& infos, const RefPtr& context); void SearchElementInfosByTextNG(int64_t elementId, const std::string& text, @@ -406,7 +415,9 @@ public: WeakPtr GetWebPatternBySurfaceId(const std::string& surfaceId) override; void SetWebPatternBySurfaceId(const std::string& surfaceId, WeakPtr pattern) override; void RemoveWebPatternBySurfaceId(const std::string& surfaceId) override; - + void SearchAccessibilityNodeBySpecificProperty(const int64_t elementId, + const SpecificPropertyParam ¶m, const int32_t requestId, + AccessibilityElementOperatorCallback &callback, const int32_t windowId); void UpdateAccessibilityNodeRect(const RefPtr& frameNode) override; void OnAccessbibilityDetachFromMainTree(const RefPtr& frameNode) override; @@ -447,6 +458,8 @@ private: // Accessibility override. RetError SearchElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode) override; + void SearchElementInfoBySpecificProperty(const int64_t elementId, const SpecificPropertyParam ¶m, + const int32_t requestId, AccessibilityElementOperatorCallback &callback) override; void SearchElementInfosByText(const int64_t elementId, const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback) override; void SearchDefaultFocusByWindowId(const int32_t windowId, const int32_t requestId, @@ -488,6 +501,8 @@ private: // Accessibility override. RetError SearchElementInfoByAccessibilityId(const int64_t elementId, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode) override; + void SearchElementInfoBySpecificProperty(const int64_t elementId, const SpecificPropertyParam ¶m, + const int32_t requestId, AccessibilityElementOperatorCallback &callback) override; void SearchElementInfosByText(const int64_t elementId, const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback) override; void SearchDefaultFocusByWindowId(const int32_t windowId, const int32_t requestId, @@ -595,6 +610,10 @@ private: void SetSearchElementInfoByAccessibilityIdResult(Accessibility::AccessibilityElementOperatorCallback& callback, std::list&& infos, const int32_t requestId, bool checkEmbed = false); + void SetSearchElementInfoByCustomIdResult(Accessibility::AccessibilityElementOperatorCallback& callback, + std::list &infos, const std::list &treeInfos, + const int32_t requestId); + void SetSearchElementInfoByTextResult(Accessibility::AccessibilityElementOperatorCallback& callback, std::list&& infos, const int32_t requestId); @@ -655,6 +674,9 @@ private: void DumpInjectActionTest(const std::vector& params); void DumpEmbedSearchTest(const std::vector& params); void DumpEmbedHoverTestNG(const std::vector& params, uint32_t windowId); + void DumpSpecificPropertySearchTest(const std::vector& params, uint32_t windowId); + void DumpSetCheckListTest(const std::vector& params); + void DumpGetCheckListTest(const std::vector& params); void GenerateCommonProperty(const RefPtr& context, CommonProperty& output, const RefPtr& mainContext, const RefPtr& node = nullptr); @@ -697,6 +719,8 @@ private: void UpdateCacheInfoNG(std::list& infos, const RefPtr& node, CommonProperty& commonProperty, const RefPtr& ngPipeline, const SearchParameter& searchParam); + + void UpdateEventWhiteList(const std::vector& eventList); #ifdef WEB_SUPPORTED void WebSetScreenRect(const std::shared_ptr& node, const CommonProperty& commonProperty, @@ -779,6 +803,8 @@ private: const std::string& surfaceId, const int32_t windowId, const SearchSurfaceIdType searchType, std::list& infos); + bool CheckWhiteList(const int32_t& eventType); + std::string callbackKey_; uint32_t windowId_ = 0; std::unordered_map> stateObserver_; @@ -811,6 +837,7 @@ private: std::vector, bool>> extensionComponentStatusVec_; std::unordered_map> pageIdEventMap_; std::map> nextFocusMapWithSubWindow_; + std::vector eventWhiteList_; mutable std::mutex nextFocusMapWithSubWindowMutex_; AccessibilityParentRectInfo uecRectInfo_; diff --git a/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp b/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp index 9b431cb88ffcedadcc23b38d1bbb0bfd1ff2e7a7..e53c710a39cbc8d74209c11b55a9b090bfd52c26 100644 --- a/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp +++ b/adapter/ohos/osal/js_third_accessibility_hover_ng.cpp @@ -513,6 +513,11 @@ public: void SetCursorPositionResult(const int32_t cursorPosition, const int32_t requestId) override { } + + void SetSearchElementInfoBySpecificPropertyResult(const std::list &infos, + const std::list &treeInfos, const int32_t requestId) override + { + } }; void DumpHandleAction( diff --git a/adapter/ohos/osal/js_third_provider_interaction_operation.cpp b/adapter/ohos/osal/js_third_provider_interaction_operation.cpp index edd622911f381f7a4a7777fd06ae642942b920cf..12b86a914e15735fa8572f3cf60bb1a696dfd60e 100644 --- a/adapter/ohos/osal/js_third_provider_interaction_operation.cpp +++ b/adapter/ohos/osal/js_third_provider_interaction_operation.cpp @@ -260,6 +260,15 @@ void JsThirdProviderInteractionOperation::SetSearchElementInfoByAccessibilityIdR }, TaskExecutor::TaskType::BACKGROUND, "SearchElementInfoByAccessibilityId"); } +void JsThirdProviderInteractionOperation::SearchElementInfoBySpecificProperty(const int64_t elementId, + const SpecificPropertyParam ¶m, const int32_t requestId, + AccessibilityElementOperatorCallback &callback) +{ + std::list infos; + std::list treeInfos; + callback.SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId); +} + void JsThirdProviderInteractionOperation::SearchElementInfosByText( const int64_t elementId, const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback) diff --git a/adapter/ohos/osal/js_third_provider_interaction_operation.h b/adapter/ohos/osal/js_third_provider_interaction_operation.h index d51b89cb7ea5970eb88fa4e07849d2431bad45e4..0da1ed8dd3ac13283ea1f686c2ac41910f66d157 100644 --- a/adapter/ohos/osal/js_third_provider_interaction_operation.h +++ b/adapter/ohos/osal/js_third_provider_interaction_operation.h @@ -52,6 +52,8 @@ public: const int64_t elementId, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback, const int32_t mode) override; + void SearchElementInfoBySpecificProperty(const int64_t elementId, const SpecificPropertyParam ¶m, + const int32_t requestId, AccessibilityElementOperatorCallback &callback) override; void SearchElementInfosByText( const int64_t elementId, const std::string& text, const int32_t requestId, Accessibility::AccessibilityElementOperatorCallback& callback) override;