• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/accessibility/accessibility_manager_ng.h"
17 
18 #include "core/accessibility/accessibility_constants.h"
19 #include "core/accessibility/accessibility_session_adapter.h"
20 #include "core/components_ng/pattern/pattern.h"
21 #include "core/pipeline_ng/pipeline_context.h"
22 
23 namespace OHOS::Ace::NG {
24 namespace {
AddTouchEventAllFingersInfo(const RefPtr<NG::FrameNode> & node,TouchEventInfo & eventInfo,const TouchEvent & event)25 void AddTouchEventAllFingersInfo(const RefPtr<NG::FrameNode>& node, TouchEventInfo& eventInfo, const TouchEvent& event)
26 {
27     // all fingers collection
28     for (const auto& item : event.pointers) {
29         float globalX = item.x;
30         float globalY = item.y;
31         float screenX = item.screenX;
32         float screenY = item.screenY;
33         double globalDisplayX = item.globalDisplayX;
34         double globalDisplayY = item.globalDisplayY;
35         PointF localPoint(globalX, globalY);
36         NGGestureRecognizer::Transform(localPoint, node, false, false);
37         auto localX = static_cast<float>(localPoint.GetX());
38         auto localY = static_cast<float>(localPoint.GetY());
39         TouchLocationInfo info("onTouch", item.originalId);
40         info.SetGlobalLocation(Offset(globalX, globalY));
41         info.SetLocalLocation(Offset(localX, localY));
42         info.SetScreenLocation(Offset(screenX, screenY));
43         info.SetGlobalDisplayLocation(Offset(globalDisplayX, globalDisplayY));
44         info.SetTouchType(event.type);
45         info.SetForce(item.force);
46         info.SetPressedTime(item.downTime);
47         info.SetWidth(item.width);
48         info.SetHeight(item.height);
49         if (item.tiltX.has_value()) {
50             info.SetTiltX(item.tiltX.value());
51         }
52         if (item.tiltY.has_value()) {
53             info.SetTiltY(item.tiltY.value());
54         }
55         info.SetSourceTool(item.sourceTool);
56         eventInfo.AddTouchLocationInfo(std::move(info));
57     }
58 }
59 
ConvertTouchEvent2TouchEventInfo(const RefPtr<NG::FrameNode> & node,const TouchEvent & event,TouchEventInfo & eventInfo)60 void ConvertTouchEvent2TouchEventInfo(const RefPtr<NG::FrameNode>& node, const TouchEvent& event,
61     TouchEventInfo& eventInfo)
62 {
63     eventInfo.SetTimeStamp(event.time);
64     eventInfo.SetDeviceId(event.deviceId);
65     eventInfo.SetPointerEvent(event.GetTouchEventPointerEvent());
66     TouchLocationInfo changedInfo("onTouch", event.originalId);
67     PointF lastLocalPoint(event.x, event.y);
68     NGGestureRecognizer::Transform(lastLocalPoint, node, false, false);
69     auto localX = static_cast<float>(lastLocalPoint.GetX());
70     auto localY = static_cast<float>(lastLocalPoint.GetY());
71     changedInfo.SetLocalLocation(Offset(localX, localY));
72     changedInfo.SetGlobalLocation(Offset(event.x, event.y));
73     changedInfo.SetScreenLocation(Offset(event.screenX, event.screenY));
74     changedInfo.SetGlobalDisplayLocation(Offset(event.globalDisplayX, event.globalDisplayY));
75     changedInfo.SetTouchType(event.type);
76     changedInfo.SetForce(event.force);
77     changedInfo.SetPressedTime(event.pressedTime);
78     changedInfo.SetWidth(event.width);
79     changedInfo.SetHeight(event.height);
80     if (event.tiltX.has_value()) {
81         changedInfo.SetTiltX(event.tiltX.value());
82     }
83     if (event.tiltY.has_value()) {
84         changedInfo.SetTiltY(event.tiltY.value());
85     }
86     changedInfo.SetSourceTool(event.sourceTool);
87     eventInfo.AddChangedTouchLocationInfo(std::move(changedInfo));
88 
89     AddTouchEventAllFingersInfo(node, eventInfo, event);
90     eventInfo.SetSourceDevice(event.sourceType);
91     eventInfo.SetForce(event.force);
92     if (event.tiltX.has_value()) {
93         eventInfo.SetTiltX(event.tiltX.value());
94     }
95     if (event.tiltY.has_value()) {
96         eventInfo.SetTiltY(event.tiltY.value());
97     }
98     if (event.rollAngle.has_value()) {
99         eventInfo.SetRollAngle(event.rollAngle.value());
100     }
101     eventInfo.SetSourceTool(event.sourceTool);
102     EventTarget eventTarget;
103     eventTarget.id = node->GetInspectorId().value_or("").c_str();
104     eventInfo.SetTarget(eventTarget);
105 }
106 
CheckAndSendHoverEnterByAncestor(const RefPtr<NG::FrameNode> & ancestor)107 bool CheckAndSendHoverEnterByAncestor(const RefPtr<NG::FrameNode>& ancestor)
108 {
109     CHECK_NULL_RETURN(ancestor, false);
110     auto pipeline = ancestor->GetContext();
111     CHECK_NULL_RETURN(pipeline, false);
112     // Inter Process is showed as a component with rect like form process,
113     // need send hover enter when no component hovered to focus outside
114     if (pipeline->IsFormRender() || pipeline->IsJsCard() || pipeline->IsJsPlugin()) {
115         TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "SendHoverEnterByAncestor");
116         ancestor->OnAccessibilityEvent(AccessibilityEventType::HOVER_ENTER_EVENT);
117         return true;
118     }
119     return false;
120 }
121 
IsTouchExplorationEnabled(const RefPtr<FrameNode> & root)122 bool IsTouchExplorationEnabled(const RefPtr<FrameNode>& root)
123 {
124     CHECK_NULL_RETURN(root, true);
125     auto pipeline = root->GetContext();
126     CHECK_NULL_RETURN(pipeline, true);
127     auto jsAccessibilityManager = pipeline->GetAccessibilityManager();
128     CHECK_NULL_RETURN(jsAccessibilityManager, true);
129     auto accessibilityWorkMode = jsAccessibilityManager->GenerateAccessibilityWorkMode();
130     return accessibilityWorkMode.isTouchExplorationEnabled;
131 }
132 
GetEmbedNodeBySurfaceId(const std::string & surfaceId)133 WeakPtr<NG::FrameNode> GetEmbedNodeBySurfaceId(const std::string& surfaceId)
134 {
135     std::stringstream ss(surfaceId);
136     uint64_t id;
137     if (ss >> id) {
138         return ElementRegister::GetInstance()->GetEmbedNodeBySurfaceId(id);
139     }
140     return nullptr;
141 }
142 }
143 
HandleAccessibilityHoverEvent(const RefPtr<FrameNode> & root,const MouseEvent & event)144 void AccessibilityManagerNG::HandleAccessibilityHoverEvent(const RefPtr<FrameNode>& root, const MouseEvent& event)
145 {
146     if (root == nullptr || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled() ||
147         !IsTouchExplorationEnabled(root) || event.sourceType != SourceType::MOUSE) {
148         return;
149     }
150     AccessibilityHoverEventType type = AccessibilityHoverEventType::MOVE;
151     switch (event.action) {
152         case MouseAction::WINDOW_ENTER:
153             type = AccessibilityHoverEventType::ENTER;
154             break;
155         case MouseAction::MOVE:
156             type = AccessibilityHoverEventType::MOVE;
157             break;
158         case MouseAction::WINDOW_LEAVE:
159             type = AccessibilityHoverEventType::EXIT;
160             break;
161         default:
162             return;
163     }
164     PointF point(event.x, event.y);
165     HandleHoverEventParam param {point, SourceType::MOUSE, type, event.time};
166     TouchEvent touchEvent;
167     HandleAccessibilityHoverEventInner(root, param, touchEvent);
168 }
169 
HandleAccessibilityHoverEvent(const RefPtr<FrameNode> & root,const TouchEvent & event)170 void AccessibilityManagerNG::HandleAccessibilityHoverEvent(const RefPtr<FrameNode>& root, const TouchEvent& event)
171 {
172     if (root == nullptr ||
173         !AceApplicationInfo::GetInstance().IsAccessibilityEnabled() ||
174         !IsTouchExplorationEnabled(root) ||
175         event.sourceType == SourceType::MOUSE) {
176         return;
177     }
178     AccessibilityHoverEventType type = AccessibilityHoverEventType::MOVE;
179     switch (event.type) {
180         case TouchType::HOVER_ENTER:
181             type = AccessibilityHoverEventType::ENTER;
182             break;
183         case TouchType::HOVER_MOVE:
184             type = AccessibilityHoverEventType::MOVE;
185             break;
186         case TouchType::HOVER_EXIT:
187             type = AccessibilityHoverEventType::EXIT;
188             break;
189         default:
190             return;
191     }
192     PointF point(event.x, event.y);
193     auto& hoverState = hoverStateManager_.GetHoverState(root->GetAccessibilityId());
194     if (event.pointers.size() > 1 && event.sourceType == SourceType::TOUCH) {
195         if (hoverState.source == SourceType::TOUCH) {
196             hoverStateManager_.ResetHoverState(hoverState);
197             return;
198         }
199     }
200     HandleHoverEventParam param {point, event.sourceType, type, event.time};
201     HandleAccessibilityHoverEventInner(root, param, event);
202 }
203 
HandleAccessibilityHoverEvent(const RefPtr<FrameNode> & root,float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)204 void AccessibilityManagerNG::HandleAccessibilityHoverEvent(const RefPtr<FrameNode>& root, float pointX, float pointY,
205     int32_t sourceType, int32_t eventType, int64_t timeMs)
206 {
207     if (root == nullptr ||
208         !AceApplicationInfo::GetInstance().IsAccessibilityEnabled() ||
209         !IsTouchExplorationEnabled(root) ||
210         eventType < 0 || eventType >= static_cast<int32_t>(AccessibilityHoverEventType::Count)) {
211         return;
212     }
213     PointF point(pointX, pointY);
214     TimeStamp time((std::chrono::milliseconds(timeMs)));
215 
216     if (IsHandlePipelineAccessibilityHoverEnter(root)) {
217         TouchEvent event;
218         event.x = pointX;
219         event.y = pointY;
220         event.sourceType = static_cast<SourceType>(sourceType);
221         event.time = time;
222         HandlePipelineAccessibilityHoverEnter(root, event, eventType);
223     }
224     HandleHoverEventParam param {point, static_cast<SourceType>(sourceType),
225         static_cast<AccessibilityHoverEventType>(eventType), time};
226     TouchEvent touchEvent;
227     HandleAccessibilityHoverEventInner(root, param, touchEvent);
228 }
229 
IsHoverTransparentCallbackListEmpty(const RefPtr<NG::FrameNode> & node)230 bool IsHoverTransparentCallbackListEmpty(const RefPtr<NG::FrameNode>& node)
231 {
232     CHECK_NULL_RETURN(node, true);
233     auto pipeline = node->GetContextRefPtr();
234     CHECK_NULL_RETURN(pipeline, true);
235     auto accessibilityManager = pipeline->GetAccessibilityManager();
236     CHECK_NULL_RETURN(accessibilityManager, true);
237     auto containerId = pipeline->GetInstanceId();
238     return accessibilityManager->CheckHoverTransparentCallbackListEmpty(containerId);
239 }
240 
ExecuteChildNodeHoverTransparentCallback(const RefPtr<FrameNode> & root,const PointF & point,const TouchEvent & event)241 bool AccessibilityManagerNG::ExecuteChildNodeHoverTransparentCallback(const RefPtr<FrameNode>& root,
242     const PointF& point, const TouchEvent& event)
243 {
244     CHECK_NULL_RETURN(root, false);
245     auto renderContext = root->GetRenderContext();
246     auto accessibilityProperty = root->GetAccessibilityProperty<NG::AccessibilityProperty>();
247     PointF selfPoint = point;
248     if (accessibilityProperty) {
249         bool isInHoverArea = false;
250         if (renderContext) {
251             auto rect = AccessibilityProperty::UpdateHoverTestRect(root);
252             renderContext->GetPointWithRevert(selfPoint);
253             isInHoverArea = rect.IsInnerRegion(selfPoint);
254         }
255         auto callback = accessibilityProperty->GetAccessibilityTransparentCallbackFunc();
256         if (callback && isInHoverArea) {
257             TouchEventInfo eventInfo("touchEvent");
258             ConvertTouchEvent2TouchEventInfo(root, event, eventInfo);
259             callback(eventInfo);
260         }
261     }
262     auto children = root->GetFrameChildren();
263     for (auto childWeak = children.rbegin(); childWeak != children.rend(); ++childWeak) {
264         auto child = childWeak->Upgrade();
265         if (child == nullptr) {
266             continue;
267         }
268         PointF noOffsetPoint = selfPoint;
269         if (renderContext) {
270             auto orginRect = renderContext->GetPaintRectWithoutTransform();
271             noOffsetPoint = selfPoint - orginRect.GetOffset();
272         }
273         ExecuteChildNodeHoverTransparentCallback(child, noOffsetPoint, event);
274     }
275     return true;
276 }
277 
HandleAccessibilityHoverTransparentCallback(bool transformed,const RefPtr<FrameNode> & root,const HandleTransparentCallbackParam & param,const PointF & point,const TouchEvent & event)278 bool AccessibilityManagerNG::HandleAccessibilityHoverTransparentCallback(bool transformed,
279     const RefPtr<FrameNode>& root,
280     const HandleTransparentCallbackParam& param,
281     const PointF& point,
282     const TouchEvent& event)
283 {
284     static constexpr int32_t INVALID_NODE_ID = -1;
285     if (transformed) {
286         return false;
287     }
288     if ((param.currentHoveringId == INVALID_NODE_ID) && (param.lastHoveringId == INVALID_NODE_ID)
289         && !IsHoverTransparentCallbackListEmpty(root)) {
290         return ExecuteChildNodeHoverTransparentCallback(root, point, event);
291     }
292     return false;
293 }
294 
HandleAccessibilityHoverEventInner(const RefPtr<FrameNode> & root,const HandleHoverEventParam & param,const TouchEvent & event)295 HandleHoverRet AccessibilityManagerNG::HandleAccessibilityHoverEventInner(
296     const RefPtr<FrameNode>& root,
297     const HandleHoverEventParam& param,
298     const TouchEvent& event)
299 {
300     CHECK_NULL_RETURN(root, HandleHoverRet::HOVER_FAIL);
301     auto& hoverState = hoverStateManager_.GetHoverState(root->GetAccessibilityId());
302     auto sourceType = param.sourceType;
303     auto eventType = param.eventType;
304     auto time = param.time;
305     static constexpr size_t THROTTLE_INTERVAL_HOVER_EVENT = 10;
306     uint64_t duration =
307         static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(time - hoverState.time).count());
308     if (!hoverState.idle) {
309         if ((!IsEventTypeChangeDirectHandleHover(eventType, hoverState.eventType))
310             && (duration < THROTTLE_INTERVAL_HOVER_EVENT)) {
311             return HandleHoverRet::IN_TIME_LIMIT;
312         }
313     }
314 
315     static constexpr size_t MIN_SOURCE_CHANGE_GAP_MS = 1000;
316     if (sourceType != hoverState.source && !hoverState.idle) {
317         if (duration < MIN_SOURCE_CHANGE_GAP_MS) {
318             return HandleHoverRet::IN_TIME_LIMIT;
319         }
320         hoverStateManager_.ResetHoverState(hoverState);
321     }
322 
323     ACE_SCOPED_TRACE("HandleAccessibilityHoverEventInner");
324     if (eventType == AccessibilityHoverEventType::ENTER) {
325         hoverStateManager_.ResetHoverState(hoverState);
326     }
327     std::vector<WeakPtr<FrameNode>> currentNodesHovering;
328     std::vector<RefPtr<FrameNode>> lastNodesHovering;
329     std::vector<int32_t> lastNodesHoveringId;
330     for (const auto& nodeWeak: hoverState.nodesHovering) {
331         auto node = nodeWeak.Upgrade();
332         if (node != nullptr) {
333             lastNodesHovering.push_back(node);
334             lastNodesHoveringId.push_back(node->GetId());
335         }
336     }
337     if (eventType != AccessibilityHoverEventType::EXIT) {
338         std::unique_ptr<AccessibilityProperty::HoverTestDebugTraceInfo> debugInfo = nullptr;
339         AccessibilityHoverTestPath path = AccessibilityProperty::HoverTest(param.point, root, debugInfo);
340         for (const auto& node: path) {
341             auto id = node->GetId();
342             if (std::find(lastNodesHoveringId.begin(), lastNodesHoveringId.end(), id) != lastNodesHoveringId.end() ||
343                 AccessibilityProperty::IsAccessibilityFocusable(node)) {
344                 currentNodesHovering.push_back(node);
345             }
346         }
347     }
348     auto sendHoverEnter = false;
349     static constexpr int32_t INVALID_NODE_ID = -1;
350     int32_t lastHoveringId = INVALID_NODE_ID;
351     RefPtr<FrameNode> lastHovering = nullptr;
352     if (!lastNodesHovering.empty()) {
353         lastHovering = lastNodesHovering.back();
354         lastHoveringId = lastHovering->GetId();
355     }
356     int32_t currentHoveringId = INVALID_NODE_ID;
357     RefPtr<FrameNode> currentHovering = nullptr;
358     if (!currentNodesHovering.empty()) {
359         currentHovering = currentNodesHovering.back().Upgrade();
360         currentHoveringId = currentHovering->GetId();
361     }
362     bool transformHover = false;
363     if (lastHoveringId != INVALID_NODE_ID && lastHoveringId != currentHoveringId) {
364         lastHovering->OnAccessibilityEvent(AccessibilityEventType::HOVER_EXIT_EVENT);
365         transformHover = NotifyHoverEventToNodeSession(lastHovering, root, param.point,
366             sourceType, AccessibilityHoverEventType::EXIT, time);
367     }
368     if (currentHovering && (currentHoveringId != INVALID_NODE_ID)) {
369         if (currentHoveringId != lastHoveringId && (!IgnoreCurrentHoveringNode(currentHovering))) {
370             currentHovering->OnAccessibilityEvent(AccessibilityEventType::HOVER_ENTER_EVENT);
371             sendHoverEnter = true;
372         }
373         transformHover = NotifyHoverEventToNodeSession(currentHovering, root, param.point,
374             sourceType, eventType, time);
375     }
376 
377     if (!sendHoverEnter && (eventType == AccessibilityHoverEventType::ENTER)) {
378         // check need send hover enter when no component hovered to focus outside
379         transformHover |= CheckAndSendHoverEnterByAncestor(root);
380     }
381 
382     if ((sourceType != SourceType::MOUSE) && (!param.ignoreTransparent)) {
383         HandleTransparentCallbackParam callbackParam = {currentHoveringId, lastHoveringId};
384         HandleAccessibilityHoverTransparentCallback(transformHover, root, callbackParam, param.point, event);
385     }
386 
387     hoverState.nodesHovering = std::move(currentNodesHovering);
388     hoverState.time = time;
389     hoverState.source = sourceType;
390     hoverState.idle = eventType == AccessibilityHoverEventType::EXIT;
391     hoverState.eventType = eventType;
392     if (sendHoverEnter && !transformHover) {
393         return HandleHoverRet::HOVER_HIT;
394     }
395     return HandleHoverRet::HOVER_FAIL;
396 }
397 
HandleAccessibilityHoverEventBySurfaceId(const std::string & surfaceId,HandleHoverEventParam & param)398 HandleHoverRet AccessibilityManagerNG::HandleAccessibilityHoverEventBySurfaceId(
399     const std::string& surfaceId,
400     HandleHoverEventParam& param)
401 {
402     auto root = GetEmbedNodeBySurfaceId(surfaceId).Upgrade();
403     CHECK_NULL_RETURN(root, HandleHoverRet::HOVER_FAIL);
404     TouchEvent event;
405     param.ignoreTransparent = true;
406     return HandleAccessibilityHoverEventInner(root, param, event);
407 }
408 
IgnoreCurrentHoveringNode(const RefPtr<FrameNode> & node)409 bool AccessibilityManagerNG::IgnoreCurrentHoveringNode(const RefPtr<FrameNode> &node)
410 {
411     auto sessionAdapter = AccessibilitySessionAdapter::GetSessionAdapter(node);
412     CHECK_NULL_RETURN(sessionAdapter, false);
413     return sessionAdapter->IgnoreHostNode();
414 }
415 
NotifyHoverEventToNodeSession(const RefPtr<FrameNode> & node,const RefPtr<FrameNode> & rootNode,const PointF & pointRoot,SourceType sourceType,AccessibilityHoverEventType eventType,TimeStamp time)416 bool AccessibilityManagerNG::NotifyHoverEventToNodeSession(const RefPtr<FrameNode>& node,
417     const RefPtr<FrameNode>& rootNode, const PointF& pointRoot,
418     SourceType sourceType, AccessibilityHoverEventType eventType, TimeStamp time)
419 {
420     auto eventHub = node->GetOrCreateEventHub<EventHub>();
421     if (!eventHub->IsEnabled()) {
422         // If the host component is disabled, do not transfer hover event.
423         return false;
424     }
425     auto sessionAdapter = AccessibilitySessionAdapter::GetSessionAdapter(node);
426     CHECK_NULL_RETURN(sessionAdapter, false);
427     // mouse event will not be hover and may be transformed by component self through touch event transform
428     if ((sourceType == SourceType::MOUSE) && (sessionAdapter->IgnoreTransformMouseEvent())) {
429         return false;
430     }
431     PointF pointNode(pointRoot);
432     if (AccessibilityManagerNG::ConvertPointFromAncestorToNode(rootNode, node, pointRoot, pointNode)) {
433         sessionAdapter->TransferHoverEvent(pointNode, sourceType, eventType, time);
434         return true;
435     }
436     return false;
437 }
438 
HoverTestDebug(const RefPtr<FrameNode> & root,const PointF & point,std::string & summary,std::string & detail) const439 void AccessibilityManagerNG::HoverTestDebug(const RefPtr<FrameNode>& root, const PointF& point,
440     std::string& summary, std::string& detail) const
441 {
442     auto summaryJson = JsonUtil::Create();
443     auto detailJson = JsonUtil::Create();
444     std::stringstream summaryNodesSearched;
445     auto debugInfo = std::make_unique<AccessibilityProperty::HoverTestDebugTraceInfo>();
446     AccessibilityHoverTestPath path = AccessibilityProperty::HoverTest(point, root, debugInfo);
447     auto summaryPath = JsonUtil::CreateArray();
448     auto summarySelected = JsonUtil::CreateArray();
449 
450     auto detaiSelectionInfo = JsonUtil::CreateArray();
451     size_t numNodesSelected = 0;
452     for (size_t i = 0; i < path.size(); ++i) {
453         summaryPath->Put(std::to_string(i).c_str(), path[i]->GetAccessibilityId());
454         auto detailNodeSelection = JsonUtil::Create();
455         if (AccessibilityProperty::IsAccessibilityFocusableDebug(path[i], detailNodeSelection)) {
456             summarySelected->Put(std::to_string(numNodesSelected).c_str(), path[i]->GetAccessibilityId());
457             ++numNodesSelected;
458         }
459         detaiSelectionInfo->PutRef(std::move(detailNodeSelection));
460     }
461     summaryJson->PutRef("path", std::move(summaryPath));
462     summaryJson->PutRef("nodesSelected", std::move(summarySelected));
463 
464     auto detailSearchInfo = JsonUtil::CreateArray();
465     for (size_t i = 0; i < debugInfo->trace.size(); ++i) {
466         auto detailNodeSearch = std::move(debugInfo->trace[i]);
467         detailSearchInfo->Put(std::to_string(i).c_str(), detailNodeSearch);
468     }
469     detailJson->PutRef("detailSearch", std::move(detailSearchInfo));
470     detailJson->PutRef("detailSelection", std::move(detaiSelectionInfo));
471     summary = summaryJson->ToString();
472     detail = detailJson->ToString();
473 }
474 
ConvertPointFromAncestorToNode(const RefPtr<NG::FrameNode> & ancestor,const RefPtr<NG::FrameNode> & endNode,const PointF & pointAncestor,PointF & pointNode)475 bool AccessibilityManagerNG::ConvertPointFromAncestorToNode(
476     const RefPtr<NG::FrameNode>& ancestor, const RefPtr<NG::FrameNode>& endNode,
477     const PointF& pointAncestor, PointF& pointNode)
478 {
479     CHECK_NULL_RETURN(ancestor, false);
480     CHECK_NULL_RETURN(endNode, false);
481     // revert scale from endNode to ancestor
482     std::vector<RefPtr<NG::FrameNode>> path;
483     RefPtr<NG::FrameNode> curr = endNode;
484     while (curr != nullptr && curr->GetId() != ancestor->GetId()) {
485         path.push_back(curr);
486         curr = curr->GetAncestorNodeOfFrame(true);
487     }
488     CHECK_NULL_RETURN(curr, false);
489     pointNode = pointAncestor;
490     for (auto nodePtr = path.rbegin(); nodePtr != path.rend(); ++nodePtr) {
491         auto renderContext = (*nodePtr)->GetRenderContext();
492         CHECK_NULL_CONTINUE(renderContext);
493         renderContext->GetPointWithRevert(pointNode);
494         auto rect = renderContext->GetPaintRectWithoutTransform();
495         pointNode = pointNode - rect.GetOffset();
496     }
497     return true;
498 }
499 
IsEventTypeChangeDirectHandleHover(AccessibilityHoverEventType eventType,AccessibilityHoverEventType prevEventType)500 bool AccessibilityManagerNG::IsEventTypeChangeDirectHandleHover(
501     AccessibilityHoverEventType eventType,
502     AccessibilityHoverEventType prevEventType)
503 {
504     if ((prevEventType == AccessibilityHoverEventType::MOVE)
505         && (eventType == AccessibilityHoverEventType::EXIT)) {
506         return true;
507     }
508     return false;
509 }
510 
IsHandlePipelineAccessibilityHoverEnter(const RefPtr<NG::FrameNode> & root)511 bool AccessibilityManagerNG::IsHandlePipelineAccessibilityHoverEnter(const RefPtr<NG::FrameNode>& root)
512 {
513     auto pipeline = root->GetContext();
514     CHECK_NULL_RETURN(pipeline, false);
515     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipeline);
516     CHECK_NULL_RETURN(ngPipeline, false);
517 
518     auto container = Container::GetContainer(ngPipeline->GetInstanceId());
519     if (container && (container->IsUIExtensionWindow())) {
520         return true;
521     }
522     return false;
523 }
524 
HandlePipelineAccessibilityHoverEnter(const RefPtr<NG::FrameNode> & root,TouchEvent & event,int32_t eventType)525 void AccessibilityManagerNG::HandlePipelineAccessibilityHoverEnter(
526     const RefPtr<NG::FrameNode>& root,
527     TouchEvent& event,
528     int32_t eventType)
529 {
530     CHECK_NULL_VOID(root);
531     AccessibilityHoverEventType eventHoverType = static_cast<AccessibilityHoverEventType>(eventType);
532     event.type = TouchType::HOVER_MOVE;
533     switch (eventHoverType) {
534         case AccessibilityHoverEventType::ENTER:
535             event.type = TouchType::HOVER_ENTER;
536             break;
537         case AccessibilityHoverEventType::MOVE:
538             event.type = TouchType::HOVER_MOVE;
539             break;
540         case AccessibilityHoverEventType::EXIT:
541             event.type = TouchType::HOVER_EXIT;
542             break;
543         default:
544             break;
545     }
546 
547     auto pipeline = root->GetContext();
548     CHECK_NULL_VOID(pipeline);
549     pipeline->OnAccessibilityHoverEvent(event, root);
550 }
551 
GetHoverState(int64_t accessibilityId)552 AccessibilityHoverState& AccessibilityHoverStateManager::GetHoverState(int64_t accessibilityId)
553 {
554     auto it = hoverStateMap_.find(accessibilityId);
555     if (it != hoverStateMap_.end()) {
556         return it->second;
557     }
558     hoverStateMap_.emplace(accessibilityId, AccessibilityHoverState {});
559     return hoverStateMap_[accessibilityId];
560 }
561 
ResetHoverState(AccessibilityHoverState & hoverState)562 void AccessibilityHoverStateManager::ResetHoverState(AccessibilityHoverState& hoverState)
563 {
564     hoverState.idle = true;
565     hoverState.nodesHovering.clear();
566 }
567 } // namespace OHOS::Ace::NG
568