1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/xcomponent/xcomponent_pattern.h"
17 
18 #include <cmath>
19 #include <cstdlib>
20 
21 #include "interfaces/native/event/ui_input_event_impl.h"
22 #include "interfaces/native/ui_input_event.h"
23 
24 #include "base/geometry/ng/point_t.h"
25 #include "base/geometry/ng/size_t.h"
26 #include "base/log/dump_log.h"
27 #include "base/log/frame_report.h"
28 #include "base/log/log_wrapper.h"
29 #include "base/memory/ace_type.h"
30 #include "base/ressched/ressched_report.h"
31 #include "base/utils/system_properties.h"
32 #include "base/utils/utils.h"
33 #include "core/common/ai/image_analyzer_manager.h"
34 #include "core/components/common/layout/constants.h"
35 #include "core/components_ng/event/gesture_event_hub.h"
36 #include "core/components_ng/pattern/xcomponent/xcomponent_controller_ng.h"
37 #include "core/event/axis_event.h"
38 #ifdef NG_BUILD
39 #include "bridge/declarative_frontend/ng/declarative_frontend_ng.h"
40 #else
41 #include "bridge/declarative_frontend/declarative_frontend.h"
42 #endif
43 #ifdef ENABLE_ROSEN_BACKEND
44 #include "ui/rs_ext_node_operation.h"
45 
46 #include "core/components_ng/render/adapter/rosen_render_context.h"
47 #endif
48 
49 #include "core/components_ng/event/input_event.h"
50 #include "core/components_ng/pattern/xcomponent/xcomponent_accessibility_child_tree_callback.h"
51 #include "core/components_ng/pattern/xcomponent/xcomponent_accessibility_session_adapter.h"
52 #include "core/components_ng/pattern/xcomponent/xcomponent_event_hub.h"
53 #include "core/components_ng/pattern/xcomponent/xcomponent_ext_surface_callback_client.h"
54 #include "core/event/key_event.h"
55 #include "core/event/mouse_event.h"
56 #include "core/event/touch_event.h"
57 #include "core/pipeline_ng/pipeline_context.h"
58 
59 namespace OHOS::Ace::NG {
60 namespace {
XComponentTypeToString(XComponentType type)61 std::string XComponentTypeToString(XComponentType type)
62 {
63     switch (type) {
64         case XComponentType::UNKNOWN:
65             return "unknown";
66         case XComponentType::SURFACE:
67             return "surface";
68         case XComponentType::COMPONENT:
69             return "component";
70         case XComponentType::TEXTURE:
71             return "texture";
72         case XComponentType::NODE:
73             return "node";
74         default:
75             return "unknown";
76     }
77 }
78 
ConvertNativeXComponentTouchEvent(const TouchType & touchType)79 OH_NativeXComponent_TouchEventType ConvertNativeXComponentTouchEvent(const TouchType& touchType)
80 {
81     switch (touchType) {
82         case TouchType::DOWN:
83             return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_DOWN;
84         case TouchType::UP:
85             return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP;
86         case TouchType::MOVE:
87             return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE;
88         case TouchType::CANCEL:
89             return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_CANCEL;
90         default:
91             return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
92     }
93 }
94 
ConvertNativeXComponentTouchToolType(const SourceTool & toolType)95 OH_NativeXComponent_TouchPointToolType ConvertNativeXComponentTouchToolType(const SourceTool& toolType)
96 {
97     switch (toolType) {
98         case SourceTool::FINGER:
99             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_FINGER;
100         case SourceTool::PEN:
101             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_PEN;
102         case SourceTool::RUBBER:
103             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_RUBBER;
104         case SourceTool::BRUSH:
105             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_BRUSH;
106         case SourceTool::PENCIL:
107             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_PENCIL;
108         case SourceTool::AIRBRUSH:
109             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_AIRBRUSH;
110         case SourceTool::MOUSE:
111             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_MOUSE;
112         case SourceTool::LENS:
113             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS;
114         default:
115             return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
116     }
117 }
118 
ConvertNativeXComponentKeyAction(const KeyAction & keyAction)119 OH_NativeXComponent_KeyAction ConvertNativeXComponentKeyAction(const KeyAction& keyAction)
120 {
121     switch (keyAction) {
122         case KeyAction::DOWN:
123             return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_DOWN;
124         case KeyAction::UP:
125             return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_UP;
126         default:
127             return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_UNKNOWN;
128     }
129 }
130 
ConvertNativeXComponentEventSourceType(const SourceType & sourceType)131 OH_NativeXComponent_EventSourceType ConvertNativeXComponentEventSourceType(const SourceType& sourceType)
132 {
133     switch (sourceType) {
134         case SourceType::MOUSE:
135             return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_MOUSE;
136         case SourceType::TOUCH:
137             return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHSCREEN;
138         case SourceType::TOUCH_PAD:
139             return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHPAD;
140         case SourceType::KEYBOARD:
141             return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_KEYBOARD;
142         default:
143             return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_UNKNOWN;
144     }
145 }
146 
ConvertNativeXComponentKeyEvent(const KeyEvent & event)147 OH_NativeXComponent_KeyEvent ConvertNativeXComponentKeyEvent(const KeyEvent& event)
148 {
149     OH_NativeXComponent_KeyEvent nativeKeyEvent;
150     nativeKeyEvent.action = ConvertNativeXComponentKeyAction(event.action);
151     nativeKeyEvent.code = static_cast<OH_NativeXComponent_KeyCode>(event.code);
152     nativeKeyEvent.sourceType = ConvertNativeXComponentEventSourceType(event.sourceType);
153     nativeKeyEvent.deviceId = event.deviceId;
154     nativeKeyEvent.timestamp = event.timeStamp.time_since_epoch().count();
155     return nativeKeyEvent;
156 }
157 } // namespace
158 
XComponentPattern(const std::optional<std::string> & id,XComponentType type,const std::optional<std::string> & libraryname,const std::shared_ptr<InnerXComponentController> & xcomponentController,float initWidth,float initHeight,bool isTypedNode)159 XComponentPattern::XComponentPattern(const std::optional<std::string>& id, XComponentType type,
160     const std::optional<std::string>& libraryname,
161     const std::shared_ptr<InnerXComponentController>& xcomponentController, float initWidth, float initHeight,
162     bool isTypedNode)
163     : id_(id), type_(type), xcomponentController_(xcomponentController), initSize_(initWidth, initHeight),
164       isTypedNode_(isTypedNode)
165 {
166     SetLibraryName(libraryname);
167     if (!isTypedNode_) {
168         InitNativeXComponent();
169     }
170     RegisterSurfaceCallbackModeEvent();
171 }
172 
InitNativeXComponent()173 void XComponentPattern::InitNativeXComponent()
174 {
175     if ((type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE) && libraryname_.has_value()) {
176         isNativeXComponent_ = true;
177         nativeXComponentImpl_ = AceType::MakeRefPtr<NativeXComponentImpl>();
178         nativeXComponent_ = std::make_shared<OH_NativeXComponent>(AceType::RawPtr(nativeXComponentImpl_));
179     }
180 }
181 
InitXComponent()182 void XComponentPattern::InitXComponent()
183 {
184     // used for TypedNode, not for declareative
185     if (isTypedNode_) {
186         InitNativeXComponent();
187         if (isNativeXComponent_) {
188             LoadNative();
189         }
190     }
191 }
192 
InitSurface()193 void XComponentPattern::InitSurface()
194 {
195     auto host = GetHost();
196     CHECK_NULL_VOID(host);
197     auto renderContext = host->GetRenderContext();
198     CHECK_NULL_VOID(renderContext);
199 
200     // only xcomponent created by capi will set successfully, others will be set in FireExternalEvent
201     SetExpectedRateRangeInit();
202     OnFrameEventInit();
203     UnregisterOnFrameEventInit();
204 
205     renderContext->SetClipToFrame(true);
206     renderContext->SetClipToBounds(true);
207 #ifdef RENDER_EXTRACT_SUPPORTED
208         renderSurface_ = RenderSurface::Create(CovertToRenderSurfaceType(type_));
209 #else
210          renderSurface_ = RenderSurface::Create();
211 #endif
212     renderSurface_->SetInstanceId(GetHostInstanceId());
213     if (type_ == XComponentType::SURFACE) {
214         InitializeRenderContext();
215         if (!SystemProperties::GetExtSurfaceEnabled()) {
216             renderSurface_->SetRenderContext(renderContextForSurface_);
217         } else {
218             auto pipelineContext = host->GetContextRefPtr();
219             CHECK_NULL_VOID(pipelineContext);
220             pipelineContext->AddOnAreaChangeNode(host->GetId());
221             extSurfaceClient_ = MakeRefPtr<XComponentExtSurfaceCallbackClient>(WeakClaim(this));
222             renderSurface_->SetExtSurfaceCallback(extSurfaceClient_);
223 #ifdef RENDER_EXTRACT_SUPPORTED
224             RegisterRenderContextCallBack();
225 #endif
226         }
227         handlingSurfaceRenderContext_ = renderContextForSurface_;
228     } else if (type_ == XComponentType::TEXTURE) {
229         renderSurface_->SetRenderContext(renderContext);
230         renderSurface_->SetIsTexture(true);
231     }
232     renderSurface_->InitSurface();
233     renderSurface_->UpdateSurfaceConfig();
234     if (type_ == XComponentType::TEXTURE) {
235         renderSurface_->RegisterBufferCallback();
236     }
237     if (isTypedNode_) {
238         InitNativeWindow(initSize_.Width(), initSize_.Height());
239     }
240     surfaceId_ = renderSurface_->GetUniqueId();
241 
242     UpdateTransformHint();
243 }
244 
UpdateTransformHint()245 void XComponentPattern::UpdateTransformHint()
246 {
247     auto host = GetHost();
248     CHECK_NULL_VOID(host);
249     auto pipelineContext = host->GetContextRefPtr();
250     CHECK_NULL_VOID(pipelineContext);
251     pipelineContext->AddWindowStateChangedCallback(host->GetId());
252     SetRotation(pipelineContext->GetTransformHint());
253     auto callbackId =
254         pipelineContext->RegisterTransformHintChangeCallback([weak = WeakClaim(this)](uint32_t transform) {
255             auto pattern = weak.Upgrade();
256             if (pattern) {
257                 pattern->SetRotation(transform);
258             }
259         });
260     UpdateTransformHintChangedCallbackId(callbackId);
261 }
262 
Initialize()263 void XComponentPattern::Initialize()
264 {
265     if (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE) {
266         InitSurface();
267         InitEvent();
268         InitController();
269     } else if (type_ == XComponentType::NODE && id_.has_value()) {
270         auto host = GetHost();
271         CHECK_NULL_VOID(host);
272         auto context = host->GetContextRefPtr();
273         if (context) {
274             FireExternalEvent(context, id_.value(), host->GetId(), false);
275             InitNativeNodeCallbacks();
276         }
277     }
278 
279     InitializeAccessibility();
280 }
281 
OnAttachToMainTree()282 void XComponentPattern::OnAttachToMainTree()
283 {
284     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "XComponent[%{public}s] AttachToMainTree", GetId().c_str());
285     ACE_SCOPED_TRACE("XComponent[%s] AttachToMainTree", GetId().c_str());
286     if (isTypedNode_ && surfaceCallbackMode_ == SurfaceCallbackMode::DEFAULT) {
287         HandleSurfaceCreated();
288     }
289 }
290 
OnDetachFromMainTree()291 void XComponentPattern::OnDetachFromMainTree()
292 {
293     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "XComponent[%{public}s] DetachFromMainTree", GetId().c_str());
294     ACE_SCOPED_TRACE("XComponent[%s] DetachFromMainTree", GetId().c_str());
295     if (isTypedNode_ && surfaceCallbackMode_ == SurfaceCallbackMode::DEFAULT) {
296         HandleSurfaceDestroyed();
297     }
298 }
299 
InitializeRenderContext()300 void XComponentPattern::InitializeRenderContext()
301 {
302     renderContextForSurface_ = RenderContext::Create();
303 #ifdef RENDER_EXTRACT_SUPPORTED
304     auto contextType = type_ == XComponentType::TEXTURE ? RenderContext::ContextType::HARDWARE_TEXTURE
305                                                         : RenderContext::ContextType::HARDWARE_SURFACE;
306     RenderContext::ContextParam param = { contextType, GetId() + "Surface" };
307 #else
308     RenderContext::ContextParam param = { RenderContext::ContextType::HARDWARE_SURFACE, GetId() + "Surface" };
309 #endif
310 
311     renderContextForSurface_->InitContext(false, param);
312 
313     renderContextForSurface_->UpdateBackgroundColor(Color::BLACK);
314 }
315 
316 #ifdef RENDER_EXTRACT_SUPPORTED
CovertToRenderSurfaceType(const XComponentType & hostType)317 RenderSurface::RenderSurfaceType XComponentPattern::CovertToRenderSurfaceType(const XComponentType& hostType)
318 {
319     switch (hostType) {
320         case XComponentType::SURFACE:
321             return RenderSurface::RenderSurfaceType::SURFACE;
322         case XComponentType::TEXTURE:
323             return RenderSurface::RenderSurfaceType::TEXTURE;
324         default:
325             return RenderSurface::RenderSurfaceType::UNKNOWN;
326     }
327 }
328 
RegisterRenderContextCallBack()329 void XComponentPattern::RegisterRenderContextCallBack()
330 {
331     CHECK_NULL_VOID(renderContextForSurface_);
332     auto OnAreaChangedCallBack = [weak = WeakClaim(this)](float x, float y, float w, float h) mutable {
333         auto pattern = weak.Upgrade();
334         CHECK_NULL_VOID(pattern);
335         auto host = pattern->GetHost();
336         CHECK_NULL_VOID(host);
337         auto geometryNode = host->GetGeometryNode();
338         CHECK_NULL_VOID(geometryNode);
339         auto xcomponentNodeSize = geometryNode->GetContentSize();
340         auto xcomponentNodeOffset = geometryNode->GetContentOffset();
341         auto transformRelativeOffset = host->GetTransformRelativeOffset();
342         Rect rect = Rect(transformRelativeOffset.GetX() + xcomponentNodeOffset.GetX(),
343             transformRelativeOffset.GetY() + xcomponentNodeOffset.GetY(), xcomponentNodeSize.Width(),
344             xcomponentNodeSize.Height());
345         if (pattern->renderSurface_) {
346             pattern->renderSurface_->SetExtSurfaceBoundsSync(rect.Left(), rect.Top(),
347                 rect.Width(), rect.Height());
348         }
349     };
350     renderContextForSurface_->SetSurfaceChangedCallBack(OnAreaChangedCallBack);
351 }
352 
RequestFocus()353 void XComponentPattern::RequestFocus()
354 {
355     auto host = GetHost();
356     CHECK_NULL_VOID(host);
357     auto eventHub = host->GetEventHub<XComponentEventHub>();
358     CHECK_NULL_VOID(eventHub);
359     auto focusHub = eventHub->GetOrCreateFocusHub();
360     CHECK_NULL_VOID(focusHub);
361 
362     focusHub->RequestFocusImmediately();
363 }
364 #endif
365 
OnAttachToFrameNode()366 void XComponentPattern::OnAttachToFrameNode()
367 {
368     Initialize();
369     if (FrameReport::GetInstance().GetEnable()) {
370         FrameReport::GetInstance().EnableSelfRender();
371     }
372 }
373 
OnModifyDone()374 void XComponentPattern::OnModifyDone()
375 {
376     // if surface has been reset by pip, do not set backgroundColor
377     if (handlingSurfaceRenderContext_ != renderContextForSurface_) {
378         return;
379     }
380     auto host = GetHost();
381     CHECK_NULL_VOID(host);
382     auto renderContext = host->GetRenderContext();
383     CHECK_NULL_VOID(renderContext);
384     CHECK_NULL_VOID(handlingSurfaceRenderContext_);
385     auto bkColor = renderContext->GetBackgroundColor();
386     if (bkColor.has_value() && bkColor.value() != Color::BLACK) {
387         handlingSurfaceRenderContext_->UpdateBackgroundColor(Color::TRANSPARENT);
388     } else {
389         handlingSurfaceRenderContext_->UpdateBackgroundColor(Color::BLACK);
390     }
391 }
392 
OnAreaChangedInner()393 void XComponentPattern::OnAreaChangedInner()
394 {
395 #ifndef RENDER_EXTRACT_SUPPORTED
396     if (SystemProperties::GetExtSurfaceEnabled()) {
397         auto host = GetHost();
398         CHECK_NULL_VOID(host);
399         auto geometryNode = host->GetGeometryNode();
400         CHECK_NULL_VOID(geometryNode);
401         auto xcomponentNodeSize = geometryNode->GetContentSize();
402         auto xcomponentNodeOffset = geometryNode->GetContentOffset();
403         auto transformRelativeOffset = host->GetTransformRelativeOffset();
404         renderSurface_->SetExtSurfaceBounds(transformRelativeOffset.GetX() + xcomponentNodeOffset.GetX(),
405             transformRelativeOffset.GetY() + xcomponentNodeOffset.GetY(), xcomponentNodeSize.Width(),
406             xcomponentNodeSize.Height());
407     }
408 #endif
409 }
410 
SetSurfaceNodeToGraphic()411 void XComponentPattern::SetSurfaceNodeToGraphic()
412 {
413 #ifdef ENABLE_ROSEN_BACKEND
414     if (type_ != XComponentType::SURFACE || !id_.has_value() ||
415         !Rosen::RSExtNodeOperation::GetInstance().CheckNeedToProcess(id_.value())) {
416         return;
417     }
418     auto host = GetHost();
419     CHECK_NULL_VOID(host);
420     auto renderContext = host->GetRenderContext();
421     CHECK_NULL_VOID(renderContext);
422     auto rosenRenderContext = AceType::DynamicCast<NG::RosenRenderContext>(renderContext);
423     CHECK_NULL_VOID(rosenRenderContext);
424     std::shared_ptr<Rosen::RSNode> parentNode = rosenRenderContext->GetRSNode();
425     CHECK_NULL_VOID(parentNode);
426     RectF canvasRect = rosenRenderContext->GetPropertyOfPosition();
427 
428     CHECK_NULL_VOID(renderContextForSurface_);
429     auto context = AceType::DynamicCast<NG::RosenRenderContext>(renderContextForSurface_);
430     CHECK_NULL_VOID(context);
431     std::shared_ptr<Rosen::RSNode> rsNode = context->GetRSNode();
432     CHECK_NULL_VOID(rsNode);
433     std::shared_ptr<Rosen::RSSurfaceNode> rsSurfaceNode = std::static_pointer_cast<Rosen::RSSurfaceNode>(rsNode);
434     CHECK_NULL_VOID(rsSurfaceNode);
435 
436     Rosen::RSExtNodeOperation::GetInstance().ProcessRSExtNode(
437         GetId(), parentNode->GetId(), canvasRect.GetX(), canvasRect.GetY(), rsSurfaceNode);
438 #endif
439 }
440 
OnRebuildFrame()441 void XComponentPattern::OnRebuildFrame()
442 {
443     if (type_ != XComponentType::SURFACE) {
444         return;
445     }
446     if (!renderSurface_->IsSurfaceValid()) {
447         return;
448     }
449     auto host = GetHost();
450     CHECK_NULL_VOID(host);
451     auto renderContext = host->GetRenderContext();
452     CHECK_NULL_VOID(renderContext);
453     CHECK_NULL_VOID(handlingSurfaceRenderContext_);
454     renderContext->AddChild(handlingSurfaceRenderContext_, 0);
455     SetSurfaceNodeToGraphic();
456 }
457 
OnDetachFromFrameNode(FrameNode * frameNode)458 void XComponentPattern::OnDetachFromFrameNode(FrameNode* frameNode)
459 {
460     CHECK_NULL_VOID(frameNode);
461     UninitializeAccessibility();
462     if (isTypedNode_) {
463         if (surfaceCallbackMode_ == SurfaceCallbackMode::PIP) {
464             HandleSurfaceDestroyed();
465         }
466         if (isNativeXComponent_) {
467             OnNativeUnload(frameNode);
468         }
469     } else {
470         if (!hasXComponentInit_) {
471             return;
472         }
473         if (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE) {
474             OnSurfaceDestroyed();
475             auto eventHub = frameNode->GetEventHub<XComponentEventHub>();
476             CHECK_NULL_VOID(eventHub);
477             {
478                 ACE_SCOPED_TRACE("XComponent[%s] FireDestroyEvent", GetId().c_str());
479                 eventHub->FireDestroyEvent(GetId());
480             }
481             if (id_.has_value()) {
482                 eventHub->FireDetachEvent(id_.value());
483             }
484             {
485                 ACE_SCOPED_TRACE("XComponent[%s] FireControllerDestroyedEvent", GetId().c_str());
486                 eventHub->FireControllerDestroyedEvent(surfaceId_, GetId());
487             }
488 #ifdef RENDER_EXTRACT_SUPPORTED
489             if (renderContextForSurface_) {
490                 renderContextForSurface_->RemoveSurfaceChangedCallBack();
491             }
492 #endif
493         }
494     }
495     auto id = frameNode->GetId();
496     auto pipeline = frameNode->GetContextRefPtr();
497     CHECK_NULL_VOID(pipeline);
498     pipeline->RemoveWindowStateChangedCallback(id);
499     if (HasTransformHintChangedCallbackId()) {
500         pipeline->UnregisterTransformHintChangedCallback(transformHintChangedCallbackId_.value_or(-1));
501     }
502     if (FrameReport::GetInstance().GetEnable()) {
503         FrameReport::GetInstance().DisableSelfRender();
504     }
505 }
506 
InitController()507 void XComponentPattern::InitController()
508 {
509     CHECK_NULL_VOID(xcomponentController_);
510     auto host = GetHost();
511     CHECK_NULL_VOID(host);
512     auto pipelineContext = host->GetContextRefPtr();
513     CHECK_NULL_VOID(pipelineContext);
514     auto uiTaskExecutor = SingleTaskExecutor::Make(pipelineContext->GetTaskExecutor(), TaskExecutor::TaskType::UI);
515     auto* controllerNG = static_cast<XComponentControllerNG*>(xcomponentController_.get());
516     if (controllerNG) {
517         controllerNG->SetPattern(AceType::Claim(this));
518     }
519     xcomponentController_->SetConfigSurfaceImpl(
520         [weak = WeakClaim(this), uiTaskExecutor](uint32_t surfaceWidth, uint32_t surfaceHeight) {
521             uiTaskExecutor.PostSyncTask(
522                 [weak, surfaceWidth, surfaceHeight]() {
523                     auto pattern = weak.Upgrade();
524                     CHECK_NULL_VOID(pattern);
525                     pattern->ConfigSurface(surfaceWidth, surfaceHeight);
526                 },
527                 "ArkUIXComponentSurfaceConfigChange");
528         });
529     if (!isTypedNode_) {
530         xcomponentController_->SetSurfaceId(surfaceId_);
531     }
532 }
533 
ConfigSurface(uint32_t surfaceWidth,uint32_t surfaceHeight)534 void XComponentPattern::ConfigSurface(uint32_t surfaceWidth, uint32_t surfaceHeight)
535 {
536     renderSurface_->ConfigSurface(surfaceWidth, surfaceHeight);
537 }
538 
OnAttachContext(PipelineContext * context)539 void XComponentPattern::OnAttachContext(PipelineContext* context)
540 {
541     CHECK_NULL_VOID(context);
542     auto host = GetHost();
543     CHECK_NULL_VOID(host);
544     context->AddWindowStateChangedCallback(host->GetId());
545     CHECK_NULL_VOID(renderSurface_);
546     renderSurface_->SetInstanceId(context->GetInstanceId());
547 }
548 
OnDetachContext(PipelineContext * context)549 void XComponentPattern::OnDetachContext(PipelineContext* context)
550 {
551     CHECK_NULL_VOID(context);
552     auto host = GetHost();
553     CHECK_NULL_VOID(host);
554     context->RemoveWindowStateChangedCallback(host->GetId());
555 }
556 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const557 void XComponentPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
558 {
559     Pattern::ToJsonValue(json, filter);
560     if (filter.IsFastFilter()) {
561         return;
562     }
563     json->PutExtAttr("enableAnalyzer", isEnableAnalyzer_ ? "true" : "false", filter);
564     json->PutExtAttr("enableSecure", isEnableSecure_ ? "true" : "false", filter);
565 }
566 
SetRotation(uint32_t rotation)567 void XComponentPattern::SetRotation(uint32_t rotation)
568 {
569     if (type_ != XComponentType::SURFACE || isSurfaceLock_ || rotation_ == rotation) {
570         return;
571     }
572     rotation_ = rotation;
573     CHECK_NULL_VOID(renderSurface_);
574     renderSurface_->SetTransformHint(rotation);
575 }
576 
BeforeSyncGeometryProperties(const DirtySwapConfig & config)577 void XComponentPattern::BeforeSyncGeometryProperties(const DirtySwapConfig& config)
578 {
579     if (type_ == XComponentType::COMPONENT || type_ == XComponentType::NODE || config.skipMeasure) {
580         return;
581     }
582     auto host = GetHost();
583     CHECK_NULL_VOID(host);
584     auto geometryNode = host->GetGeometryNode();
585     CHECK_NULL_VOID(geometryNode);
586     drawSize_ = geometryNode->GetContentSize();
587     if (!drawSize_.IsPositive()) {
588         TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "XComponent[%{public}s]'s size is not positive", GetId().c_str());
589         return;
590     }
591     globalPosition_ = geometryNode->GetFrameOffset();
592     localPosition_ = geometryNode->GetContentOffset();
593 
594     if (IsSupportImageAnalyzerFeature()) {
595         UpdateAnalyzerUIConfig(geometryNode);
596     }
597     const auto& [offsetChanged, sizeChanged, needFireNativeEvent] = UpdateSurfaceRect();
598     if (!hasXComponentInit_) {
599         initSize_ = paintRect_.GetSize();
600         if (!SystemProperties::GetExtSurfaceEnabled() && !isTypedNode_) {
601             XComponentSizeInit();
602         }
603         auto offset = globalPosition_ + paintRect_.GetOffset();
604         NativeXComponentOffset(offset.GetX(), offset.GetY());
605         hasXComponentInit_ = true;
606     }
607 #ifndef RENDER_EXTRACT_SUPPORTED
608     if (SystemProperties::GetExtSurfaceEnabled()) {
609         auto transformRelativeOffset = host->GetTransformRelativeOffset();
610         renderSurface_->SetExtSurfaceBounds(
611             static_cast<int32_t>(transformRelativeOffset.GetX() + localPosition_.GetX()),
612             static_cast<int32_t>(transformRelativeOffset.GetY() + localPosition_.GetY()),
613             static_cast<int32_t>(drawSize_.Width()), static_cast<int32_t>(drawSize_.Height()));
614     }
615 #endif
616     HandleSurfaceChangeEvent(false, offsetChanged, sizeChanged, needFireNativeEvent, config.frameOffsetChange);
617     if (type_ == XComponentType::SURFACE && renderType_ == NodeRenderType::RENDER_TYPE_TEXTURE) {
618         AddAfterLayoutTaskForExportTexture();
619     }
620     host->MarkNeedSyncRenderTree();
621 }
622 
DumpInfo()623 void XComponentPattern::DumpInfo()
624 {
625     DumpLog::GetInstance().AddDesc(std::string("xcomponentId: ").append(id_.value_or("no id")));
626     DumpLog::GetInstance().AddDesc(std::string("xcomponentType: ").append(XComponentTypeToString(type_)));
627     DumpLog::GetInstance().AddDesc(std::string("libraryName: ").append(libraryname_.value_or("no library name")));
628     DumpLog::GetInstance().AddDesc(std::string("surfaceId: ").append(surfaceId_));
629     DumpLog::GetInstance().AddDesc(std::string("surfaceRect: ").append(paintRect_.ToString()));
630 }
631 
DumpAdvanceInfo()632 void XComponentPattern::DumpAdvanceInfo()
633 {
634     if (renderSurface_) {
635         renderSurface_->DumpInfo();
636     }
637 }
638 
NativeXComponentOffset(double x,double y)639 void XComponentPattern::NativeXComponentOffset(double x, double y)
640 {
641     CHECK_RUN_ON(UI);
642     CHECK_NULL_VOID(nativeXComponent_);
643     CHECK_NULL_VOID(nativeXComponentImpl_);
644     auto host = GetHost();
645     CHECK_NULL_VOID(host);
646     auto pipelineContext = host->GetContextRefPtr();
647     CHECK_NULL_VOID(pipelineContext);
648     float scale = pipelineContext->GetViewScale();
649     nativeXComponentImpl_->SetXComponentOffsetX(x * scale);
650     nativeXComponentImpl_->SetXComponentOffsetY(y * scale);
651 }
652 
NativeXComponentDispatchTouchEvent(const OH_NativeXComponent_TouchEvent & touchEvent,const std::vector<XComponentTouchPoint> & xComponentTouchPoints)653 void XComponentPattern::NativeXComponentDispatchTouchEvent(
654     const OH_NativeXComponent_TouchEvent& touchEvent, const std::vector<XComponentTouchPoint>& xComponentTouchPoints)
655 {
656     CHECK_RUN_ON(UI);
657     CHECK_NULL_VOID(nativeXComponent_);
658     CHECK_NULL_VOID(nativeXComponentImpl_);
659     nativeXComponentImpl_->SetTouchEvent(touchEvent);
660     nativeXComponentImpl_->SetTouchPoint(xComponentTouchPoints);
661     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
662     const auto* callback = nativeXComponentImpl_->GetCallback();
663     CHECK_NULL_VOID(callback);
664     CHECK_NULL_VOID(callback->DispatchTouchEvent);
665     callback->DispatchTouchEvent(nativeXComponent_.get(), surface);
666 }
667 
InitNativeWindow(float textureWidth,float textureHeight)668 void XComponentPattern::InitNativeWindow(float textureWidth, float textureHeight)
669 {
670     auto host = GetHost();
671     CHECK_NULL_VOID(host);
672     auto context = host->GetContextRefPtr();
673     CHECK_NULL_VOID(context);
674     if (renderSurface_->IsSurfaceValid() && (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE)) {
675         float viewScale = context->GetViewScale();
676         renderSurface_->CreateNativeWindow();
677         renderSurface_->AdjustNativeWindowSize(
678             static_cast<uint32_t>(textureWidth * viewScale), static_cast<uint32_t>(textureHeight * viewScale));
679         nativeWindow_ = renderSurface_->GetNativeWindow();
680     }
681 }
682 
XComponentSizeInit()683 void XComponentPattern::XComponentSizeInit()
684 {
685     CHECK_RUN_ON(UI);
686     auto host = GetHost();
687     CHECK_NULL_VOID(host);
688     InitNativeWindow(initSize_.Width(), initSize_.Height());
689 #ifdef RENDER_EXTRACT_SUPPORTED
690     if (xcomponentController_ && renderSurface_) {
691         xcomponentController_->SetSurfaceId(renderSurface_->GetUniqueId());
692     }
693 #endif
694     auto eventHub = host->GetEventHub<XComponentEventHub>();
695     CHECK_NULL_VOID(eventHub);
696     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "XComponent[%{public}s] triggers onLoad and OnSurfaceCreated callback",
697         GetId().c_str());
698     if (id_.has_value()) {
699         eventHub->FireSurfaceInitEvent(id_.value(), host->GetId());
700     }
701     {
702         ACE_SCOPED_TRACE("XComponent[%s] FireLoadEvent", GetId().c_str());
703         eventHub->FireLoadEvent(GetId());
704     }
705     {
706         ACE_SCOPED_TRACE("XComponent[%s] FireControllerCreatedEvent", GetId().c_str());
707         eventHub->FireControllerCreatedEvent(surfaceId_, GetId());
708     }
709 }
710 
XComponentSizeChange(const RectF & surfaceRect,bool needFireNativeEvent)711 void XComponentPattern::XComponentSizeChange(const RectF& surfaceRect, bool needFireNativeEvent)
712 {
713     auto host = GetHost();
714     CHECK_NULL_VOID(host);
715     renderSurface_->UpdateSurfaceSizeInUserData(
716         static_cast<uint32_t>(surfaceRect.Width()), static_cast<uint32_t>(surfaceRect.Height()));
717 
718     // In declarative mode: Native onSurfaceCreated callback is triggred
719     // when the component finish it's first layout, so do not trigger the native onSurfaceChanged callback
720     if (!isTypedNode_ && isNativeXComponent_ && !needFireNativeEvent) {
721         return;
722     }
723     // When creating the surface for the first time, needFireNativeEvent = false, other time needFireNativeEvent = true
724     // the first time change size no need to resize nativeWindow
725     OnSurfaceChanged(surfaceRect, needFireNativeEvent);
726 }
727 
GetAccessibilitySessionAdapter()728 RefPtr<AccessibilitySessionAdapter> XComponentPattern::GetAccessibilitySessionAdapter()
729 {
730     return accessibilitySessionAdapter_;
731 }
732 
InitializeAccessibility()733 void XComponentPattern::InitializeAccessibility()
734 {
735     if (accessibilityChildTreeCallback_) {
736         return;
737     }
738 
739     InitializeAccessibilityCallback();
740     auto host = GetHost();
741     CHECK_NULL_VOID(host);
742     int64_t accessibilityId = host->GetAccessibilityId();
743     TAG_LOGI(AceLogTag::ACE_XCOMPONENT,
744         "InitializeAccessibility accessibilityId: %{public}" PRId64 "", accessibilityId);
745     auto pipeline = host->GetContextRefPtr();
746     CHECK_NULL_VOID(pipeline);
747     auto accessibilityManager = pipeline->GetAccessibilityManager();
748     CHECK_NULL_VOID(accessibilityManager);
749     accessibilityChildTreeCallback_ = std::make_shared<XComponentAccessibilityChildTreeCallback>(
750         WeakClaim(this), host->GetAccessibilityId());
751     accessibilityManager->RegisterAccessibilityChildTreeCallback(
752         accessibilityId, accessibilityChildTreeCallback_);
753     if (accessibilityManager->IsRegister()) {
754         accessibilityChildTreeCallback_->OnRegister(
755             pipeline->GetWindowId(), accessibilityManager->GetTreeId());
756     }
757 }
758 
UninitializeAccessibility()759 void XComponentPattern::UninitializeAccessibility()
760 {
761     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "UninitializeAccessibility");
762     auto host = GetHost();
763     CHECK_NULL_VOID(host);
764     int64_t accessibilityId = host->GetAccessibilityId();
765     auto pipeline = host->GetContextRefPtr();
766     CHECK_NULL_VOID(pipeline);
767     auto accessibilityManager = pipeline->GetAccessibilityManager();
768     CHECK_NULL_VOID(accessibilityManager);
769     if (accessibilityManager->IsRegister() && accessibilityChildTreeCallback_) {
770         accessibilityChildTreeCallback_->OnDeregister();
771     }
772     accessibilityManager->DeregisterAccessibilityChildTreeCallback(accessibilityId);
773     accessibilityChildTreeCallback_ = nullptr;
774 }
775 
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId)776 bool XComponentPattern::OnAccessibilityChildTreeRegister(uint32_t windowId, int32_t treeId)
777 {
778     auto host = GetHost();
779     CHECK_NULL_RETURN(host, false);
780     auto pipeline = host->GetContextRefPtr();
781     CHECK_NULL_RETURN(pipeline, false);
782     auto accessibilityManager = pipeline->GetAccessibilityManager();
783     CHECK_NULL_RETURN(accessibilityManager, false);
784     if (accessibilityProvider_ == nullptr) {
785         accessibilityProvider_ =
786             AceType::MakeRefPtr<XComponentAccessibilityProvider>(WeakClaim(this));
787     }
788 
789     auto pair = GetNativeXComponent();
790     auto nativeXComponentImpl = pair.first;
791     CHECK_NULL_RETURN(nativeXComponentImpl, false);
792     auto nativeProvider = nativeXComponentImpl->GetAccessbilityProvider();
793     CHECK_NULL_RETURN(nativeProvider, false);
794     if (!nativeProvider->IsRegister()) {
795         TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "Not register native accessibility");
796         return false;
797     }
798 
799     nativeProvider->SetInnerAccessibilityProvider(accessibilityProvider_);
800     if (accessibilitySessionAdapter_ == nullptr) {
801         accessibilitySessionAdapter_ =
802             AceType::MakeRefPtr<XcomponentAccessibilitySessionAdapter>(host);
803     }
804     Registration registration;
805     registration.windowId = windowId;
806     registration.parentWindowId = windowId;
807     registration.parentTreeId = treeId;
808     registration.elementId = host->GetAccessibilityId();
809     registration.operatorType = OperatorType::JS_THIRD_PROVIDER;
810     registration.hostNode = WeakClaim(RawPtr(host));
811     registration.accessibilityProvider = WeakClaim(RawPtr(accessibilityProvider_));
812     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "OnAccessibilityChildTreeRegister, "
813         "windowId: %{public}d, treeId: %{public}d.", windowId, treeId);
814     return accessibilityManager->RegisterInteractionOperationAsChildTree(registration);
815 }
816 
OnAccessibilityChildTreeDeregister()817 bool XComponentPattern::OnAccessibilityChildTreeDeregister()
818 {
819     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "OnAccessibilityChildTreeDeregister, "
820         "windowId: %{public}u, treeId: %{public}d.", windowId_, treeId_);
821     auto host = GetHost();
822     CHECK_NULL_RETURN(host, false);
823     auto pipeline = host->GetContextRefPtr();
824     CHECK_NULL_RETURN(pipeline, false);
825     auto accessibilityManager = pipeline->GetAccessibilityManager();
826     CHECK_NULL_RETURN(accessibilityManager, false);
827     auto pair = GetNativeXComponent();
828     auto nativeXComponentImpl = pair.first;
829     CHECK_NULL_RETURN(nativeXComponentImpl, false);
830     auto nativeProvider = nativeXComponentImpl->GetAccessbilityProvider();
831     CHECK_NULL_RETURN(nativeProvider, false);
832     nativeProvider->SetInnerAccessibilityProvider(nullptr);
833     accessibilitySessionAdapter_ = nullptr;
834     accessibilityProvider_ = nullptr;
835     return accessibilityManager->DeregisterInteractionOperationAsChildTree(windowId_, treeId_);
836 }
837 
OnSetAccessibilityChildTree(int32_t childWindowId,int32_t childTreeId)838 void XComponentPattern::OnSetAccessibilityChildTree(
839     int32_t childWindowId, int32_t childTreeId)
840 {
841     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "OnSetAccessibilityChildTree, "
842         "windowId: %{public}d, treeId: %{public}d.", childWindowId, childTreeId);
843     windowId_ = static_cast<uint32_t>(childWindowId);
844     treeId_ = childTreeId;
845     auto host = GetHost();
846     CHECK_NULL_VOID(host);
847     auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
848     if (accessibilityProperty != nullptr) {
849         accessibilityProperty->SetChildWindowId(childWindowId);
850         accessibilityProperty->SetChildTreeId(childTreeId);
851     }
852 }
853 
InitializeAccessibilityCallback()854 void XComponentPattern::InitializeAccessibilityCallback()
855 {
856     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "InitializeAccessibilityCallback");
857     CHECK_NULL_VOID(nativeXComponentImpl_);
858     auto nativeProvider = nativeXComponentImpl_->GetAccessbilityProvider();
859     CHECK_NULL_VOID(nativeProvider);
860     nativeProvider->SetRegisterCallback(
861         [weak = WeakClaim(this)] (bool isRegister) {
862             auto pattern = weak.Upgrade();
863             CHECK_NULL_VOID(pattern);
864             pattern->HandleRegisterAccessibilityEvent(isRegister);
865         });
866 }
867 
HandleRegisterAccessibilityEvent(bool isRegister)868 void XComponentPattern::HandleRegisterAccessibilityEvent(bool isRegister)
869 {
870     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "HandleRegisterAccessibilityEvent, "
871         "isRegister: %{public}d.", isRegister);
872     CHECK_NULL_VOID(accessibilityChildTreeCallback_);
873     auto host = GetHost();
874     CHECK_NULL_VOID(host);
875     auto pipeline = host->GetContextRefPtr();
876     CHECK_NULL_VOID(pipeline);
877     auto accessibilityManager = pipeline->GetAccessibilityManager();
878     CHECK_NULL_VOID(accessibilityManager);
879     if (!isRegister) {
880         accessibilityChildTreeCallback_->OnDeregister();
881         return;
882     }
883 
884     if (accessibilityManager->IsRegister()) {
885         accessibilityChildTreeCallback_->OnRegister(
886             pipeline->GetWindowId(), accessibilityManager->GetTreeId());
887     }
888 }
889 
InitNativeNodeCallbacks()890 void XComponentPattern::InitNativeNodeCallbacks()
891 {
892     CHECK_NULL_VOID(nativeXComponent_);
893     CHECK_NULL_VOID(nativeXComponentImpl_);
894 
895     auto host = GetHost();
896     CHECK_NULL_VOID(host);
897     nativeXComponentImpl_->registerContaner(AceType::RawPtr(host));
898 
899     auto OnAttachRootNativeNode = [](void* container, void* root) {
900         ContainerScope scope(Container::CurrentIdSafely());
901         auto node = AceType::Claim(reinterpret_cast<NG::FrameNode*>(root));
902         CHECK_NULL_VOID(node);
903         auto host = AceType::Claim(reinterpret_cast<NG::FrameNode*>(container));
904         CHECK_NULL_VOID(host);
905         host->AddChild(node);
906         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
907     };
908 
909     auto OnDetachRootNativeNode = [](void* container, void* root) {
910         ContainerScope scope(Container::CurrentIdSafely());
911         auto node = AceType::Claim(reinterpret_cast<NG::FrameNode*>(root));
912         CHECK_NULL_VOID(node);
913         auto host = AceType::Claim(reinterpret_cast<NG::FrameNode*>(container));
914         CHECK_NULL_VOID(host);
915         host->RemoveChild(node);
916     };
917 
918     nativeXComponentImpl_->registerNativeNodeCallbacks(
919         std::move(OnAttachRootNativeNode), std::move(OnDetachRootNativeNode));
920 }
921 
InitEvent()922 void XComponentPattern::InitEvent()
923 {
924     auto host = GetHost();
925     CHECK_NULL_VOID(host);
926     auto eventHub = host->GetEventHub<XComponentEventHub>();
927     CHECK_NULL_VOID(eventHub);
928     if (id_.has_value()) {
929         eventHub->SetOnSurfaceInitEvent(CreateExternalEvent());
930     }
931     auto gestureHub = eventHub->GetOrCreateGestureEventHub();
932     CHECK_NULL_VOID(gestureHub);
933     InitTouchEvent(gestureHub);
934     InitOnTouchIntercept(gestureHub);
935     auto inputHub = eventHub->GetOrCreateInputEventHub();
936     InitMouseEvent(inputHub);
937     InitAxisEvent(inputHub);
938     InitMouseHoverEvent(inputHub);
939     auto focusHub = host->GetOrCreateFocusHub();
940     CHECK_NULL_VOID(focusHub);
941     InitFocusEvent(focusHub);
942 }
943 
InitFocusEvent(const RefPtr<FocusHub> & focusHub)944 void XComponentPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
945 {
946 #ifdef RENDER_EXTRACT_SUPPORTED
947     focusHub->SetFocusable(true);
948 #endif
949 
950     auto onFocusEvent = [weak = WeakClaim(this)]() {
951         auto pattern = weak.Upgrade();
952         CHECK_NULL_VOID(pattern);
953         return pattern->HandleFocusEvent();
954     };
955     focusHub->SetOnFocusInternal(std::move(onFocusEvent));
956 
957     auto onKeyEvent = [weak = WeakClaim(this)](const KeyEvent& event) -> bool {
958         TAG_LOGD(AceLogTag::ACE_XCOMPONENT, "HandleKeyEvent[%{public}d,%{public}d,%{public}d,%{public}" PRId64 "]",
959             event.action, event.code, event.sourceType, event.deviceId);
960         auto pattern = weak.Upgrade();
961         CHECK_NULL_RETURN(pattern, false);
962         return pattern->HandleKeyEvent(event);
963     };
964     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
965 
966     auto onBlurEvent = [weak = WeakClaim(this)]() {
967         auto pattern = weak.Upgrade();
968         CHECK_NULL_VOID(pattern);
969         return pattern->HandleBlurEvent();
970     };
971     focusHub->SetOnBlurInternal(std::move(onBlurEvent));
972 }
HandleFocusEvent()973 void XComponentPattern::HandleFocusEvent()
974 {
975     CHECK_NULL_VOID(nativeXComponent_);
976     CHECK_NULL_VOID(nativeXComponentImpl_);
977     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
978     const auto focusEventCallback = nativeXComponentImpl_->GetFocusEventCallback();
979     CHECK_NULL_VOID(focusEventCallback);
980     focusEventCallback(nativeXComponent_.get(), surface);
981 }
982 
HandleKeyEvent(const KeyEvent & event)983 bool XComponentPattern::HandleKeyEvent(const KeyEvent& event)
984 {
985     CHECK_NULL_RETURN(nativeXComponent_, false);
986     CHECK_NULL_RETURN(nativeXComponentImpl_, false);
987 
988     OH_NativeXComponent_KeyEvent keyEvent = ConvertNativeXComponentKeyEvent(event);
989     nativeXComponentImpl_->SetKeyEvent(keyEvent);
990 
991     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
992     const auto keyEventCallbackWithResult = nativeXComponentImpl_->GetKeyEventCallbackWithResult();
993     if (keyEventCallbackWithResult) {
994         return keyEventCallbackWithResult(nativeXComponent_.get(), surface);
995     }
996     const auto keyEventCallback = nativeXComponentImpl_->GetKeyEventCallback();
997     CHECK_NULL_RETURN(keyEventCallback, false);
998     keyEventCallback(nativeXComponent_.get(), surface);
999     return false;
1000 }
1001 
HandleBlurEvent()1002 void XComponentPattern::HandleBlurEvent()
1003 {
1004     CHECK_NULL_VOID(nativeXComponent_);
1005     CHECK_NULL_VOID(nativeXComponentImpl_);
1006     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
1007     const auto blurEventCallback = nativeXComponentImpl_->GetBlurEventCallback();
1008     CHECK_NULL_VOID(blurEventCallback);
1009     blurEventCallback(nativeXComponent_.get(), surface);
1010 }
1011 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)1012 void XComponentPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
1013 {
1014     CHECK_NULL_VOID(!touchEvent_);
1015 
1016     auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
1017         auto pattern = weak.Upgrade();
1018         CHECK_NULL_VOID(pattern);
1019         pattern->HandleTouchEvent(info);
1020     };
1021 
1022     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
1023     gestureHub->AddTouchEvent(touchEvent_);
1024 }
1025 
InitAxisEvent(const RefPtr<InputEventHub> & inputHub)1026 void XComponentPattern::InitAxisEvent(const RefPtr<InputEventHub>& inputHub)
1027 {
1028     CHECK_NULL_VOID(!axisEvent_);
1029 
1030     auto axisTask = [weak = WeakClaim(this)](const AxisInfo& info) {
1031         auto pattern = weak.Upgrade();
1032         CHECK_NULL_VOID(pattern);
1033         pattern->HandleAxisEvent(info);
1034     };
1035 
1036     axisEvent_ = MakeRefPtr<InputEvent>(std::move(axisTask));
1037     inputHub->AddOnAxisEvent(axisEvent_);
1038 }
1039 
InitOnTouchIntercept(const RefPtr<GestureEventHub> & gestureHub)1040 void XComponentPattern::InitOnTouchIntercept(const RefPtr<GestureEventHub>& gestureHub)
1041 {
1042     gestureHub->SetOnTouchIntercept([weak = WeakClaim(this)](const TouchEventInfo& touchEvent) -> HitTestMode {
1043         auto pattern = weak.Upgrade();
1044         CHECK_NULL_RETURN(pattern, NG::HitTestMode::HTMDEFAULT);
1045         auto hostNode = pattern->GetHost();
1046         CHECK_NULL_RETURN(hostNode, NG::HitTestMode::HTMDEFAULT);
1047         CHECK_NULL_RETURN(pattern->nativeXComponentImpl_, hostNode->GetHitTestMode());
1048         const auto onTouchInterceptCallback = pattern->nativeXComponentImpl_->GetOnTouchInterceptCallback();
1049         CHECK_NULL_RETURN(onTouchInterceptCallback, hostNode->GetHitTestMode());
1050         auto event = touchEvent.ConvertToTouchEvent();
1051         ArkUI_UIInputEvent uiEvent { ARKUI_UIINPUTEVENT_TYPE_TOUCH, TOUCH_EVENT_ID, &event };
1052         return static_cast<NG::HitTestMode>(onTouchInterceptCallback(pattern->nativeXComponent_.get(), &uiEvent));
1053     });
1054 }
1055 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)1056 void XComponentPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
1057 {
1058     CHECK_NULL_VOID(!mouseEvent_);
1059 
1060     auto mouseTask = [weak = WeakClaim(this)](const MouseInfo& info) {
1061         TAG_LOGD(AceLogTag::ACE_XCOMPONENT, "HandleMouseEvent[%{public}f,%{public}f,%{public}d,%{public}d]",
1062             info.GetLocalLocation().GetX(), info.GetLocalLocation().GetY(), info.GetAction(), info.GetButton());
1063         auto pattern = weak.Upgrade();
1064         CHECK_NULL_VOID(pattern);
1065         pattern->HandleMouseEvent(info);
1066     };
1067 
1068     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
1069     inputHub->AddOnMouseEvent(mouseEvent_);
1070 }
1071 
InitMouseHoverEvent(const RefPtr<InputEventHub> & inputHub)1072 void XComponentPattern::InitMouseHoverEvent(const RefPtr<InputEventHub>& inputHub)
1073 {
1074     CHECK_NULL_VOID(!mouseHoverEvent_);
1075     auto mouseHoverTask = [weak = WeakClaim(this)](bool isHover) {
1076         auto pattern = weak.Upgrade();
1077         CHECK_NULL_VOID(pattern);
1078         pattern->HandleMouseHoverEvent(isHover);
1079     };
1080     mouseHoverEvent_ = MakeRefPtr<InputEvent>(std::move(mouseHoverTask));
1081     inputHub->AddOnHoverEvent(mouseHoverEvent_);
1082 }
1083 
HandleTouchEvent(const TouchEventInfo & info)1084 void XComponentPattern::HandleTouchEvent(const TouchEventInfo& info)
1085 {
1086     auto touchInfoList = info.GetChangedTouches();
1087     if (touchInfoList.empty()) {
1088         return;
1089     }
1090     const auto& touchInfo = touchInfoList.front();
1091     const auto& screenOffset = touchInfo.GetGlobalLocation();
1092     const auto& localOffset = touchInfo.GetLocalLocation();
1093     touchEventPoint_.id = touchInfo.GetFingerId();
1094     touchEventPoint_.screenX = static_cast<float>(screenOffset.GetX());
1095     touchEventPoint_.screenY = static_cast<float>(screenOffset.GetY());
1096     touchEventPoint_.x = static_cast<float>(localOffset.GetX());
1097     touchEventPoint_.y = static_cast<float>(localOffset.GetY());
1098     touchEventPoint_.size = touchInfo.GetSize();
1099     touchEventPoint_.force = touchInfo.GetForce();
1100     touchEventPoint_.deviceId = touchInfo.GetTouchDeviceId();
1101     const auto timeStamp = info.GetTimeStamp().time_since_epoch().count();
1102     touchEventPoint_.timeStamp = timeStamp;
1103     auto touchType = touchInfoList.front().GetTouchType();
1104     touchEventPoint_.type = ConvertNativeXComponentTouchEvent(touchType);
1105     TAG_LOGD(AceLogTag::ACE_XCOMPONENT, "HandleTouchEvent[%{public}f,%{public}f,%{public}d,%{public}zu,%{public}u]",
1106         localOffset.GetX(), localOffset.GetY(), touchInfo.GetFingerId(), touchInfoList.front().GetTouchType(),
1107         static_cast<uint32_t>(touchInfo.GetSize()));
1108     SetTouchPoint(info.GetTouches(), timeStamp, touchType);
1109 
1110     if (nativeXComponent_ && nativeXComponentImpl_) {
1111         nativeXComponentImpl_->SetHistoricalPoint(SetHistoryPoint(info.GetHistory()));
1112         nativeXComponentImpl_->SetCurrentSourceType(
1113             { touchInfo.GetFingerId(), ConvertNativeXComponentEventSourceType(info.GetSourceDevice()) });
1114     }
1115     NativeXComponentDispatchTouchEvent(touchEventPoint_, nativeXComponentTouchPoints_);
1116 #ifdef RENDER_EXTRACT_SUPPORTED
1117     if (touchType == TouchType::DOWN) {
1118         RequestFocus();
1119     }
1120 #endif
1121 }
1122 
HandleMouseEvent(const MouseInfo & info)1123 void XComponentPattern::HandleMouseEvent(const MouseInfo& info)
1124 {
1125     OH_NativeXComponent_MouseEvent mouseEventPoint;
1126     mouseEventPoint.x = static_cast<float>(info.GetLocalLocation().GetX());
1127     mouseEventPoint.y = static_cast<float>(info.GetLocalLocation().GetY());
1128     mouseEventPoint.screenX = static_cast<float>(info.GetScreenLocation().GetX());
1129     mouseEventPoint.screenY = static_cast<float>(info.GetScreenLocation().GetY());
1130     switch (info.GetAction()) {
1131         case MouseAction::PRESS:
1132             mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_PRESS;
1133             break;
1134         case MouseAction::RELEASE:
1135             mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_RELEASE;
1136             break;
1137         case MouseAction::MOVE:
1138             mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_MOVE;
1139             break;
1140         default:
1141             mouseEventPoint.action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_NONE;
1142             break;
1143     }
1144     switch (info.GetButton()) {
1145         case MouseButton::LEFT_BUTTON:
1146             mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_LEFT_BUTTON;
1147             break;
1148         case MouseButton::RIGHT_BUTTON:
1149             mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_RIGHT_BUTTON;
1150             break;
1151         case MouseButton::MIDDLE_BUTTON:
1152             mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_MIDDLE_BUTTON;
1153             break;
1154         case MouseButton::BACK_BUTTON:
1155             mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_BACK_BUTTON;
1156             break;
1157         case MouseButton::FORWARD_BUTTON:
1158             mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_FORWARD_BUTTON;
1159             break;
1160         default:
1161             mouseEventPoint.button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_NONE_BUTTON;
1162             break;
1163     }
1164     mouseEventPoint.timestamp = info.GetTimeStamp().time_since_epoch().count();
1165     NativeXComponentDispatchMouseEvent(mouseEventPoint);
1166 }
1167 
HandleAxisEvent(const AxisInfo & info)1168 void XComponentPattern::HandleAxisEvent(const AxisInfo& info)
1169 {
1170     auto axisEvent = info.ConvertToAxisEvent();
1171     NativeXComponentDispatchAxisEvent(&axisEvent);
1172 }
1173 
HandleMouseHoverEvent(bool isHover)1174 void XComponentPattern::HandleMouseHoverEvent(bool isHover)
1175 {
1176     CHECK_RUN_ON(UI);
1177     CHECK_NULL_VOID(nativeXComponent_);
1178     CHECK_NULL_VOID(nativeXComponentImpl_);
1179     const auto* callback = nativeXComponentImpl_->GetMouseEventCallback();
1180     CHECK_NULL_VOID(callback);
1181     CHECK_NULL_VOID(callback->DispatchHoverEvent);
1182     callback->DispatchHoverEvent(nativeXComponent_.get(), isHover);
1183 }
1184 
NativeXComponentDispatchMouseEvent(const OH_NativeXComponent_MouseEvent & mouseEvent)1185 void XComponentPattern::NativeXComponentDispatchMouseEvent(const OH_NativeXComponent_MouseEvent& mouseEvent)
1186 {
1187     CHECK_RUN_ON(UI);
1188     CHECK_NULL_VOID(nativeXComponent_);
1189     CHECK_NULL_VOID(nativeXComponentImpl_);
1190     nativeXComponentImpl_->SetMouseEvent(mouseEvent);
1191     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
1192     const auto* callback = nativeXComponentImpl_->GetMouseEventCallback();
1193     CHECK_NULL_VOID(callback);
1194     CHECK_NULL_VOID(callback->DispatchMouseEvent);
1195     callback->DispatchMouseEvent(nativeXComponent_.get(), surface);
1196 }
1197 
NativeXComponentDispatchAxisEvent(AxisEvent * axisEvent)1198 void XComponentPattern::NativeXComponentDispatchAxisEvent(AxisEvent* axisEvent)
1199 {
1200     CHECK_RUN_ON(UI);
1201     CHECK_NULL_VOID(nativeXComponent_);
1202     CHECK_NULL_VOID(nativeXComponentImpl_);
1203     const auto callback = nativeXComponentImpl_->GetUIAxisEventCallback();
1204     CHECK_NULL_VOID(callback);
1205     ArkUI_UIInputEvent uiEvent { ARKUI_UIINPUTEVENT_TYPE_AXIS, AXIS_EVENT_ID, axisEvent };
1206     callback(nativeXComponent_.get(), &uiEvent, ArkUI_UIInputEvent_Type::ARKUI_UIINPUTEVENT_TYPE_AXIS);
1207 }
1208 
SetTouchPoint(const std::list<TouchLocationInfo> & touchInfoList,const int64_t timeStamp,const TouchType & touchType)1209 void XComponentPattern::SetTouchPoint(
1210     const std::list<TouchLocationInfo>& touchInfoList, const int64_t timeStamp, const TouchType& touchType)
1211 {
1212     touchEventPoint_.numPoints =
1213         touchInfoList.size() <= OH_MAX_TOUCH_POINTS_NUMBER ? touchInfoList.size() : OH_MAX_TOUCH_POINTS_NUMBER;
1214     nativeXComponentTouchPoints_.clear();
1215     uint32_t index = 0;
1216     for (auto iterator = touchInfoList.begin(); iterator != touchInfoList.end() && index < OH_MAX_TOUCH_POINTS_NUMBER;
1217          iterator++) {
1218         OH_NativeXComponent_TouchPoint ohTouchPoint;
1219         const auto& pointTouchInfo = *iterator;
1220         const auto& pointWindowOffset = pointTouchInfo.GetGlobalLocation();
1221         const auto& pointLocalOffset = pointTouchInfo.GetLocalLocation();
1222         const auto& pointDisplayOffset = pointTouchInfo.GetScreenLocation();
1223         ohTouchPoint.id = pointTouchInfo.GetFingerId();
1224         // screenX and screenY implementation wrong but should not modify for maintaining compatibility
1225         ohTouchPoint.screenX = static_cast<float>(pointWindowOffset.GetX());
1226         ohTouchPoint.screenY = static_cast<float>(pointWindowOffset.GetY());
1227         ohTouchPoint.x = static_cast<float>(pointLocalOffset.GetX());
1228         ohTouchPoint.y = static_cast<float>(pointLocalOffset.GetY());
1229         ohTouchPoint.type = ConvertNativeXComponentTouchEvent(touchType);
1230         ohTouchPoint.size = pointTouchInfo.GetSize();
1231         ohTouchPoint.force = pointTouchInfo.GetForce();
1232         ohTouchPoint.timeStamp = timeStamp;
1233         ohTouchPoint.isPressed = (touchType == TouchType::DOWN);
1234         touchEventPoint_.touchPoints[index++] = ohTouchPoint;
1235         // set tiltX, tiltY, windowX, windowY, displayX, displayY and sourceToolType
1236         XComponentTouchPoint xcomponentTouchPoint;
1237         xcomponentTouchPoint.tiltX = pointTouchInfo.GetTiltX().value_or(0.0f);
1238         xcomponentTouchPoint.tiltY = pointTouchInfo.GetTiltY().value_or(0.0f);
1239         xcomponentTouchPoint.windowX = static_cast<float>(pointWindowOffset.GetX());
1240         xcomponentTouchPoint.windowY = static_cast<float>(pointWindowOffset.GetY());
1241         xcomponentTouchPoint.displayX = static_cast<float>(pointDisplayOffset.GetX());
1242         xcomponentTouchPoint.displayY = static_cast<float>(pointDisplayOffset.GetY());
1243         xcomponentTouchPoint.sourceToolType = ConvertNativeXComponentTouchToolType(pointTouchInfo.GetSourceTool());
1244         nativeXComponentTouchPoints_.emplace_back(xcomponentTouchPoint);
1245     }
1246     while (index < OH_MAX_TOUCH_POINTS_NUMBER) {
1247         OH_NativeXComponent_TouchPoint ohTouchPoint;
1248         ohTouchPoint.id = 0;
1249         ohTouchPoint.screenX = 0;
1250         ohTouchPoint.screenY = 0;
1251         ohTouchPoint.x = 0;
1252         ohTouchPoint.y = 0;
1253         ohTouchPoint.type = OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
1254         ohTouchPoint.size = 0;
1255         ohTouchPoint.force = 0;
1256         ohTouchPoint.timeStamp = 0;
1257         ohTouchPoint.isPressed = false;
1258         touchEventPoint_.touchPoints[index++] = ohTouchPoint;
1259     }
1260 }
1261 
SetHistoryPoint(const std::list<TouchLocationInfo> & touchInfoList)1262 std::vector<OH_NativeXComponent_HistoricalPoint> XComponentPattern::SetHistoryPoint(
1263     const std::list<TouchLocationInfo>& touchInfoList)
1264 {
1265     std::vector<OH_NativeXComponent_HistoricalPoint> historicalPoints;
1266     for (auto&& item : touchInfoList) {
1267         OH_NativeXComponent_HistoricalPoint point;
1268         point.id = item.GetFingerId();
1269         point.x = item.GetLocalLocation().GetX();
1270         point.y = item.GetLocalLocation().GetY();
1271         point.screenX = item.GetScreenLocation().GetX();
1272         point.screenY = item.GetScreenLocation().GetY();
1273         point.type = static_cast<OH_NativeXComponent_TouchEventType>(item.GetTouchType());
1274         point.size = item.GetSize();
1275         point.force = item.GetForce();
1276         point.timeStamp = item.GetTimeStamp().time_since_epoch().count();
1277         point.titlX = item.GetTiltX().value_or(0.0f);
1278         point.titlY = item.GetTiltY().value_or(0.0f);
1279         point.sourceTool = static_cast<OH_NativeXComponent_TouchEvent_SourceTool>(item.GetSourceTool());
1280 
1281         historicalPoints.push_back(point);
1282     }
1283     return historicalPoints;
1284 }
1285 
FireExternalEvent(RefPtr<NG::PipelineContext> context,const std::string & componentId,const uint32_t nodeId,const bool isDestroy)1286 void XComponentPattern::FireExternalEvent(
1287     RefPtr<NG::PipelineContext> context, const std::string& componentId, const uint32_t nodeId, const bool isDestroy)
1288 {
1289     CHECK_NULL_VOID(context);
1290 #ifdef NG_BUILD
1291     auto frontEnd = AceType::DynamicCast<DeclarativeFrontendNG>(context->GetFrontend());
1292 #else
1293     auto frontEnd = AceType::DynamicCast<DeclarativeFrontend>(context->GetFrontend());
1294 #endif
1295     CHECK_NULL_VOID(frontEnd);
1296     auto jsEngine = frontEnd->GetJsEngine();
1297     jsEngine->FireExternalEvent(componentId, nodeId, isDestroy);
1298 }
1299 
CreateExternalEvent()1300 ExternalEvent XComponentPattern::CreateExternalEvent()
1301 {
1302     return
1303         [weak = AceType::WeakClaim(this)](const std::string& componentId, const uint32_t nodeId, const bool isDestroy) {
1304             auto pattern = weak.Upgrade();
1305             CHECK_NULL_VOID(pattern);
1306             auto host = pattern->GetHost();
1307             CHECK_NULL_VOID(host);
1308             auto context = host->GetContextRefPtr();
1309             CHECK_NULL_VOID(context);
1310             pattern->FireExternalEvent(context, componentId, nodeId, isDestroy);
1311         };
1312 }
1313 
SetHandlingRenderContextForSurface(const RefPtr<RenderContext> & otherRenderContext)1314 void XComponentPattern::SetHandlingRenderContextForSurface(const RefPtr<RenderContext>& otherRenderContext)
1315 {
1316     CHECK_NULL_VOID(otherRenderContext);
1317     handlingSurfaceRenderContext_ = otherRenderContext;
1318     auto host = GetHost();
1319     CHECK_NULL_VOID(host);
1320     auto renderContext = host->GetRenderContext();
1321     renderContext->ClearChildren();
1322     renderContext->AddChild(handlingSurfaceRenderContext_, 0);
1323     handlingSurfaceRenderContext_->SetBounds(
1324         paintRect_.GetX(), paintRect_.GetY(), paintRect_.Width(), paintRect_.Height());
1325     host->MarkModifyDone();
1326 }
1327 
GetOffsetRelativeToWindow()1328 OffsetF XComponentPattern::GetOffsetRelativeToWindow()
1329 {
1330     auto host = GetHost();
1331     CHECK_NULL_RETURN(host, OffsetF());
1332     return host->GetTransformRelativeOffset();
1333 }
1334 
RestoreHandlingRenderContextForSurface()1335 void XComponentPattern::RestoreHandlingRenderContextForSurface()
1336 {
1337     SetHandlingRenderContextForSurface(renderContextForSurface_);
1338 }
1339 
SetExtController(const RefPtr<XComponentPattern> & extPattern)1340 XComponentControllerErrorCode XComponentPattern::SetExtController(const RefPtr<XComponentPattern>& extPattern)
1341 {
1342     if (!extPattern) {
1343         return XCOMPONENT_CONTROLLER_BAD_PARAMETER;
1344     }
1345     if (extPattern_.Upgrade()) {
1346         return XCOMPONENT_CONTROLLER_REPEAT_SET;
1347     }
1348     if (handlingSurfaceRenderContext_) {
1349         // backgroundColor of pip's surface is black
1350         handlingSurfaceRenderContext_->UpdateBackgroundColor(Color::BLACK);
1351     }
1352     extPattern->SetHandlingRenderContextForSurface(handlingSurfaceRenderContext_);
1353     extPattern_ = extPattern;
1354     handlingSurfaceRenderContext_.Reset();
1355     return XCOMPONENT_CONTROLLER_NO_ERROR;
1356 }
1357 
ResetExtController(const RefPtr<XComponentPattern> & extPattern)1358 XComponentControllerErrorCode XComponentPattern::ResetExtController(const RefPtr<XComponentPattern>& extPattern)
1359 {
1360     if (!extPattern) {
1361         return XCOMPONENT_CONTROLLER_BAD_PARAMETER;
1362     }
1363     auto curExtPattern = extPattern_.Upgrade();
1364     if (!curExtPattern || curExtPattern != extPattern) {
1365         return XCOMPONENT_CONTROLLER_RESET_ERROR;
1366     }
1367     RestoreHandlingRenderContextForSurface();
1368     extPattern->RestoreHandlingRenderContextForSurface();
1369     extPattern_.Reset();
1370     return XCOMPONENT_CONTROLLER_NO_ERROR;
1371 }
1372 
HandleSetExpectedRateRangeEvent()1373 void XComponentPattern::HandleSetExpectedRateRangeEvent()
1374 {
1375     CHECK_NULL_VOID(nativeXComponent_);
1376     CHECK_NULL_VOID(nativeXComponentImpl_);
1377     CHECK_NULL_VOID(displaySync_);
1378     OH_NativeXComponent_ExpectedRateRange* range = nativeXComponentImpl_->GetRateRange();
1379     CHECK_NULL_VOID(range);
1380     FrameRateRange frameRateRange;
1381     frameRateRange.Set(range->min, range->max, range->expected);
1382     displaySync_->SetExpectedFrameRateRange(frameRateRange);
1383     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "Id: %{public}" PRIu64 " SetExpectedFrameRateRange"
1384         "{%{public}d, %{public}d, %{public}d}", displaySync_->GetId(), range->min, range->max, range->expected);
1385 }
1386 
HandleOnFrameEvent()1387 void XComponentPattern::HandleOnFrameEvent()
1388 {
1389     CHECK_NULL_VOID(nativeXComponent_);
1390     CHECK_NULL_VOID(nativeXComponentImpl_);
1391     CHECK_NULL_VOID(displaySync_);
1392     displaySync_->RegisterOnFrameWithData([weak = AceType::WeakClaim(this)](RefPtr<DisplaySyncData> displaySyncData) {
1393         auto xComponentPattern = weak.Upgrade();
1394         CHECK_NULL_VOID(xComponentPattern);
1395         CHECK_NULL_VOID(xComponentPattern->nativeXComponentImpl_->GetOnFrameCallback());
1396         xComponentPattern->nativeXComponentImpl_->GetOnFrameCallback()(xComponentPattern->nativeXComponent_.get(),
1397             displaySyncData->GetTimestamp(), displaySyncData->GetTargetTimestamp());
1398     });
1399     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "Id: %{public}" PRIu64 " RegisterOnFrame",
1400         displaySync_->GetId());
1401     displaySync_->AddToPipelineOnContainer();
1402 }
1403 
HandleUnregisterOnFrameEvent()1404 void XComponentPattern::HandleUnregisterOnFrameEvent()
1405 {
1406     CHECK_NULL_VOID(nativeXComponent_);
1407     CHECK_NULL_VOID(nativeXComponentImpl_);
1408     CHECK_NULL_VOID(displaySync_);
1409     displaySync_->UnregisterOnFrame();
1410     TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "Id: %{public}" PRIu64 " UnregisterOnFrame",
1411         displaySync_->GetId());
1412     displaySync_->DelFromPipelineOnContainer();
1413 }
1414 
DoTextureExport()1415 bool XComponentPattern::DoTextureExport()
1416 {
1417     CHECK_NULL_RETURN(handlingSurfaceRenderContext_, false);
1418     if (!ExportTextureAvailable()) {
1419         return false;
1420     }
1421     if (!handlingSurfaceRenderContext_->DoTextureExport(exportTextureSurfaceId_)) {
1422         TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "DoTextureExport fail");
1423         return false;
1424     }
1425     auto host = GetHost();
1426     CHECK_NULL_RETURN(host, false);
1427     auto renderContext = host->GetRenderContext();
1428     CHECK_NULL_RETURN(renderContext, false);
1429     renderContext->SetIsNeedRebuildRSTree(false);
1430     return true;
1431 }
1432 
StopTextureExport()1433 bool XComponentPattern::StopTextureExport()
1434 {
1435     CHECK_NULL_RETURN(handlingSurfaceRenderContext_, false);
1436     if (!handlingSurfaceRenderContext_->StopTextureExport()) {
1437         TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "StopTextureExport fail");
1438         return false;
1439     }
1440     auto host = GetHost();
1441     CHECK_NULL_RETURN(host, false);
1442     auto renderContext = host->GetRenderContext();
1443     CHECK_NULL_RETURN(renderContext, false);
1444     renderContext->ClearChildren();
1445     renderContext->AddChild(handlingSurfaceRenderContext_, 0);
1446     renderContext->SetIsNeedRebuildRSTree(true);
1447     return true;
1448 }
1449 
AddAfterLayoutTaskForExportTexture()1450 void XComponentPattern::AddAfterLayoutTaskForExportTexture()
1451 {
1452     auto host = GetHost();
1453     CHECK_NULL_VOID(host);
1454     auto context = host->GetContextRefPtr();
1455     CHECK_NULL_VOID(context);
1456     context->AddAfterLayoutTask([weak = WeakClaim(this)]() {
1457         auto pattern = weak.Upgrade();
1458         CHECK_NULL_VOID(pattern);
1459         pattern->DoTextureExport();
1460     });
1461 }
1462 
ExportTextureAvailable()1463 bool XComponentPattern::ExportTextureAvailable()
1464 {
1465     auto host = GetHost();
1466     auto parnetNodeContainer = host->GetNodeContainer();
1467     CHECK_NULL_RETURN(parnetNodeContainer, false);
1468     auto parent = parnetNodeContainer->GetAncestorNodeOfFrame();
1469     CHECK_NULL_RETURN(parent, false);
1470     auto ancestorNodeContainer = parent->GetNodeContainer();
1471     CHECK_NULL_RETURN(ancestorNodeContainer, true);
1472     auto ancestorViewNode = ancestorNodeContainer->GetChildAtIndex(0);
1473     CHECK_NULL_RETURN(ancestorViewNode, true);
1474     auto parnetExportTextureInfo = ancestorViewNode->GetExportTextureInfo();
1475     CHECK_NULL_RETURN(parnetExportTextureInfo, true);
1476     return parnetExportTextureInfo->GetCurrentRenderType() != NodeRenderType::RENDER_TYPE_TEXTURE;
1477 }
1478 
ChangeRenderType(NodeRenderType renderType)1479 bool XComponentPattern::ChangeRenderType(NodeRenderType renderType)
1480 {
1481     if (type_ != XComponentType::SURFACE) {
1482         return renderType == NodeRenderType::RENDER_TYPE_DISPLAY;
1483     }
1484     auto host = GetHost();
1485     CHECK_NULL_RETURN(host, false);
1486     if (!host->GetNodeContainer()) {
1487         renderType_ = renderType;
1488         return true;
1489     }
1490     auto renderContext = host->GetRenderContext();
1491     CHECK_NULL_RETURN(renderContext, false);
1492     if (renderType == NodeRenderType::RENDER_TYPE_TEXTURE) {
1493         if (DoTextureExport()) {
1494             renderType_ = renderType;
1495             return true;
1496         }
1497     } else {
1498         if (StopTextureExport()) {
1499             renderType_ = renderType;
1500             return true;
1501         }
1502     }
1503     return false;
1504 }
1505 
SetExportTextureSurfaceId(const std::string & surfaceId)1506 void XComponentPattern::SetExportTextureSurfaceId(const std::string& surfaceId)
1507 {
1508     exportTextureSurfaceId_ = StringUtils::StringToLongUint(surfaceId);
1509 }
1510 
SetIdealSurfaceWidth(float surfaceWidth)1511 void XComponentPattern::SetIdealSurfaceWidth(float surfaceWidth)
1512 {
1513     selfIdealSurfaceWidth_ = surfaceWidth;
1514 }
1515 
SetIdealSurfaceHeight(float surfaceHeight)1516 void XComponentPattern::SetIdealSurfaceHeight(float surfaceHeight)
1517 {
1518     selfIdealSurfaceHeight_ = surfaceHeight;
1519 }
1520 
SetIdealSurfaceOffsetX(float offsetX)1521 void XComponentPattern::SetIdealSurfaceOffsetX(float offsetX)
1522 {
1523     selfIdealSurfaceOffsetX_ = offsetX;
1524 }
1525 
SetIdealSurfaceOffsetY(float offsetY)1526 void XComponentPattern::SetIdealSurfaceOffsetY(float offsetY)
1527 {
1528     selfIdealSurfaceOffsetY_ = offsetY;
1529 }
1530 
ClearIdealSurfaceOffset(bool isXAxis)1531 void XComponentPattern::ClearIdealSurfaceOffset(bool isXAxis)
1532 {
1533     if (isXAxis) {
1534         selfIdealSurfaceOffsetX_.reset();
1535     } else {
1536         selfIdealSurfaceOffsetY_.reset();
1537     }
1538 }
1539 
HandleSurfaceChangeEvent(bool needForceRender,bool offsetChanged,bool sizeChanged,bool needFireNativeEvent,bool frameOffsetChange)1540 void XComponentPattern::HandleSurfaceChangeEvent(
1541     bool needForceRender, bool offsetChanged, bool sizeChanged, bool needFireNativeEvent, bool frameOffsetChange)
1542 {
1543     if (!drawSize_.IsPositive()) {
1544         return;
1545     }
1546     if (frameOffsetChange || offsetChanged) {
1547         auto offset = globalPosition_ + paintRect_.GetOffset();
1548         NativeXComponentOffset(offset.GetX(), offset.GetY());
1549     }
1550     if (sizeChanged) {
1551         XComponentSizeChange(paintRect_, needFireNativeEvent);
1552     }
1553     if (handlingSurfaceRenderContext_) {
1554         handlingSurfaceRenderContext_->SetBounds(
1555             paintRect_.GetX(), paintRect_.GetY(), paintRect_.Width(), paintRect_.Height());
1556     }
1557     if (renderSurface_) {
1558         renderSurface_->SetSurfaceDefaultSize(
1559             static_cast<int32_t>(paintRect_.Width()), static_cast<int32_t>(paintRect_.Height()));
1560     }
1561     if (needForceRender) {
1562         auto host = GetHost();
1563         CHECK_NULL_VOID(host);
1564         host->MarkNeedRenderOnly();
1565     }
1566 }
1567 
UpdateSurfaceRect()1568 std::tuple<bool, bool, bool> XComponentPattern::UpdateSurfaceRect()
1569 {
1570     if (!drawSize_.IsPositive()) {
1571         return { false, false, false };
1572     }
1573     auto preSurfaceSize = surfaceSize_;
1574     auto preSurfaceOffset = surfaceOffset_;
1575     if (selfIdealSurfaceWidth_.has_value() && Positive(selfIdealSurfaceWidth_.value()) &&
1576         selfIdealSurfaceHeight_.has_value() && Positive(selfIdealSurfaceHeight_.value())) {
1577         surfaceOffset_.SetX(selfIdealSurfaceOffsetX_.has_value()
1578                                 ? selfIdealSurfaceOffsetX_.value()
1579                                 : (drawSize_.Width() - selfIdealSurfaceWidth_.value()) / 2.0f);
1580 
1581         surfaceOffset_.SetY(selfIdealSurfaceOffsetY_.has_value()
1582                                 ? selfIdealSurfaceOffsetY_.value()
1583                                 : (drawSize_.Height() - selfIdealSurfaceHeight_.value()) / 2.0f);
1584         surfaceSize_ = { selfIdealSurfaceWidth_.value(), selfIdealSurfaceHeight_.value() };
1585     } else {
1586         surfaceSize_ = drawSize_;
1587         surfaceOffset_ = localPosition_;
1588     }
1589     auto offsetChanged = preSurfaceOffset != surfaceOffset_;
1590     auto sizeChanged = preSurfaceSize != surfaceSize_;
1591     if (offsetChanged || sizeChanged) {
1592         paintRect_ = { surfaceOffset_, surfaceSize_ };
1593         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
1594             paintRect_ = AdjustPaintRect(
1595                 surfaceOffset_.GetX(), surfaceOffset_.GetY(), surfaceSize_.Width(), surfaceSize_.Height(), true);
1596         }
1597     }
1598     return { offsetChanged, sizeChanged, preSurfaceSize.IsPositive() };
1599 }
1600 
LoadNative()1601 void XComponentPattern::LoadNative()
1602 {
1603     auto host = GetHost();
1604     CHECK_NULL_VOID(host);
1605     auto eventHub = host->GetEventHub<XComponentEventHub>();
1606     CHECK_NULL_VOID(eventHub);
1607     eventHub->FireSurfaceInitEvent(id_.value_or(""), host->GetId());
1608     OnNativeLoad(reinterpret_cast<FrameNode*>(AceType::RawPtr(host)));
1609 }
1610 
OnNativeLoad(FrameNode * frameNode)1611 void XComponentPattern::OnNativeLoad(FrameNode* frameNode)
1612 {
1613     hasLoadNativeDone_ = true;
1614     CHECK_NULL_VOID(frameNode);
1615     auto eventHub = frameNode->GetEventHub<XComponentEventHub>();
1616     CHECK_NULL_VOID(eventHub);
1617     {
1618         ACE_SCOPED_TRACE("XComponent[%s] FireLoadEvent", GetId().c_str());
1619         eventHub->FireLoadEvent(GetId());
1620     }
1621 }
1622 
OnNativeUnload(FrameNode * frameNode)1623 void XComponentPattern::OnNativeUnload(FrameNode* frameNode)
1624 {
1625     hasLoadNativeDone_ = false;
1626     CHECK_NULL_VOID(frameNode);
1627     auto eventHub = frameNode->GetEventHub<XComponentEventHub>();
1628     CHECK_NULL_VOID(eventHub);
1629     {
1630         ACE_SCOPED_TRACE("XComponent[%s] FireDestroyEvent", GetId().c_str());
1631         eventHub->FireDestroyEvent(GetId());
1632     }
1633 }
1634 
OnSurfaceCreated()1635 void XComponentPattern::OnSurfaceCreated()
1636 {
1637     CHECK_RUN_ON(UI);
1638     auto width = initSize_.Width();
1639     auto height = initSize_.Height();
1640     if (isNativeXComponent_) {
1641         CHECK_NULL_VOID(nativeXComponentImpl_);
1642         CHECK_NULL_VOID(nativeXComponent_);
1643         nativeXComponentImpl_->SetXComponentWidth(static_cast<int32_t>(width));
1644         nativeXComponentImpl_->SetXComponentHeight(static_cast<int32_t>(height));
1645         nativeXComponentImpl_->SetSurface(nativeWindow_);
1646         const auto* callback = nativeXComponentImpl_->GetCallback();
1647         CHECK_NULL_VOID(callback);
1648         CHECK_NULL_VOID(callback->OnSurfaceCreated);
1649         TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "XComponent[%{public}s] native OnSurfaceCreated", GetId().c_str());
1650         ACE_SCOPED_TRACE("XComponent[%s] NativeSurfaceCreated[w:%f,h:%f]", GetId().c_str(), width, height);
1651         callback->OnSurfaceCreated(nativeXComponent_.get(), nativeWindow_);
1652     } else {
1653         auto host = GetHost();
1654         CHECK_NULL_VOID(host);
1655         auto eventHub = host->GetEventHub<XComponentEventHub>();
1656         CHECK_NULL_VOID(eventHub);
1657         {
1658             ACE_SCOPED_TRACE("XComponent[%s] FireControllerCreatedEvent", GetId().c_str());
1659             eventHub->FireControllerCreatedEvent(surfaceId_, GetId());
1660         }
1661     }
1662 }
1663 
OnSurfaceChanged(const RectF & surfaceRect,bool needResizeNativeWindow)1664 void XComponentPattern::OnSurfaceChanged(const RectF& surfaceRect, bool needResizeNativeWindow)
1665 {
1666     CHECK_RUN_ON(UI);
1667     auto host = GetHost();
1668     CHECK_NULL_VOID(host);
1669     auto width = surfaceRect.Width();
1670     auto height = surfaceRect.Height();
1671     if (needResizeNativeWindow) {
1672         CHECK_NULL_VOID(renderSurface_);
1673         auto context = host->GetContextRefPtr();
1674         CHECK_NULL_VOID(context);
1675         auto viewScale = context->GetViewScale();
1676         renderSurface_->AdjustNativeWindowSize(
1677             static_cast<uint32_t>(width * viewScale), static_cast<uint32_t>(height * viewScale));
1678     }
1679     if (isNativeXComponent_) {
1680         CHECK_NULL_VOID(nativeXComponent_);
1681         CHECK_NULL_VOID(nativeXComponentImpl_);
1682         nativeXComponentImpl_->SetXComponentWidth(static_cast<int32_t>(width));
1683         nativeXComponentImpl_->SetXComponentHeight(static_cast<int32_t>(height));
1684         auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
1685         const auto* callback = nativeXComponentImpl_->GetCallback();
1686         CHECK_NULL_VOID(callback);
1687         CHECK_NULL_VOID(callback->OnSurfaceChanged);
1688         {
1689             ACE_SCOPED_TRACE("XComponent[%s] native OnSurfaceChanged[w:%f,h:%f]", GetId().c_str(), width, height);
1690             callback->OnSurfaceChanged(nativeXComponent_.get(), surface);
1691         }
1692     } else {
1693         auto eventHub = host->GetEventHub<XComponentEventHub>();
1694         CHECK_NULL_VOID(eventHub);
1695         {
1696             ACE_SCOPED_TRACE("XComponent[%s] FireControllerChangedEvent[w:%f,h:%f]", GetId().c_str(), width, height);
1697             eventHub->FireControllerChangedEvent(surfaceId_, surfaceRect);
1698         }
1699     }
1700 }
1701 
OnSurfaceDestroyed()1702 void XComponentPattern::OnSurfaceDestroyed()
1703 {
1704     if (isNativeXComponent_) {
1705         CHECK_RUN_ON(UI);
1706         CHECK_NULL_VOID(nativeXComponent_);
1707         CHECK_NULL_VOID(nativeXComponentImpl_);
1708         auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
1709         const auto* callback = nativeXComponentImpl_->GetCallback();
1710         CHECK_NULL_VOID(callback);
1711         CHECK_NULL_VOID(callback->OnSurfaceDestroyed);
1712         TAG_LOGI(AceLogTag::ACE_XCOMPONENT, "XComponent[%{public}s] native OnSurfaceDestroyed", GetId().c_str());
1713         ACE_SCOPED_TRACE("XComponent[%s] native OnSurfaceDestroyed", GetId().c_str());
1714         callback->OnSurfaceDestroyed(nativeXComponent_.get(), surface);
1715         nativeXComponentImpl_->SetSurface(nullptr);
1716     } else {
1717         auto host = GetHost();
1718         CHECK_NULL_VOID(host);
1719         auto eventHub = host->GetEventHub<XComponentEventHub>();
1720         CHECK_NULL_VOID(eventHub);
1721         {
1722             ACE_SCOPED_TRACE("XComponent[%s] FireControllerDestroyedEvent", GetId().c_str());
1723             eventHub->FireControllerDestroyedEvent(surfaceId_, GetId());
1724         }
1725     }
1726 }
1727 
RegisterSurfaceCallbackModeEvent()1728 void XComponentPattern::RegisterSurfaceCallbackModeEvent()
1729 {
1730     if (isTypedNode_ && !surfaceCallbackModeChangeEvent_) {
1731         surfaceCallbackModeChangeEvent_ = [weak = WeakClaim(this)](SurfaceCallbackMode mode) {
1732             auto xcPattern = weak.Upgrade();
1733             CHECK_NULL_VOID(xcPattern);
1734             xcPattern->OnSurfaceCallbackModeChange(mode);
1735         };
1736     }
1737 }
1738 
OnSurfaceCallbackModeChange(SurfaceCallbackMode mode)1739 void XComponentPattern::OnSurfaceCallbackModeChange(SurfaceCallbackMode mode)
1740 {
1741     CHECK_EQUAL_VOID(surfaceCallbackMode_, mode);
1742     surfaceCallbackMode_ = mode;
1743     auto host = GetHost();
1744     CHECK_NULL_VOID(host);
1745     if (!host->IsOnMainTree()) {
1746         if (surfaceCallbackMode_ == SurfaceCallbackMode::PIP) {
1747             HandleSurfaceCreated();
1748         } else if (surfaceCallbackMode_ == SurfaceCallbackMode::DEFAULT) {
1749             HandleSurfaceDestroyed();
1750         }
1751     }
1752 }
1753 
HandleSurfaceCreated()1754 void XComponentPattern::HandleSurfaceCreated()
1755 {
1756     CHECK_NULL_VOID(renderSurface_);
1757     renderSurface_->RegisterSurface();
1758     surfaceId_ = renderSurface_->GetUniqueId();
1759     CHECK_NULL_VOID(xcomponentController_);
1760     xcomponentController_->SetSurfaceId(surfaceId_);
1761     OnSurfaceCreated();
1762 }
1763 
HandleSurfaceDestroyed()1764 void XComponentPattern::HandleSurfaceDestroyed()
1765 {
1766     CHECK_NULL_VOID(renderSurface_);
1767     renderSurface_->ReleaseSurfaceBuffers();
1768     renderSurface_->UnregisterSurface();
1769     CHECK_NULL_VOID(xcomponentController_);
1770     OnSurfaceDestroyed();
1771     xcomponentController_->SetSurfaceId("");
1772 }
1773 
NativeSurfaceShow()1774 void XComponentPattern::NativeSurfaceShow()
1775 {
1776     CHECK_RUN_ON(UI);
1777     CHECK_NULL_VOID(nativeXComponentImpl_);
1778     CHECK_NULL_VOID(nativeXComponent_);
1779     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
1780     const auto surfaceShowCallback = nativeXComponentImpl_->GetSurfaceShowCallback();
1781     CHECK_NULL_VOID(surfaceShowCallback);
1782     surfaceShowCallback(nativeXComponent_.get(), surface);
1783 }
1784 
NativeSurfaceHide()1785 void XComponentPattern::NativeSurfaceHide()
1786 {
1787     CHECK_RUN_ON(UI);
1788     CHECK_NULL_VOID(nativeXComponent_);
1789     CHECK_NULL_VOID(nativeXComponentImpl_);
1790     auto* surface = const_cast<void*>(nativeXComponentImpl_->GetSurface());
1791     const auto surfaceHideCallback = nativeXComponentImpl_->GetSurfaceHideCallback();
1792     CHECK_NULL_VOID(surfaceHideCallback);
1793     surfaceHideCallback(nativeXComponent_.get(), surface);
1794     CHECK_NULL_VOID(renderSurface_);
1795     renderSurface_->ReleaseSurfaceBuffers();
1796 }
1797 
OnWindowHide()1798 void XComponentPattern::OnWindowHide()
1799 {
1800     if (!hasXComponentInit_ || hasReleasedSurface_ ||
1801         (type_ != XComponentType::SURFACE && type_ != XComponentType::TEXTURE)) {
1802         return;
1803     }
1804     if (renderSurface_) {
1805         renderSurface_->OnWindowStateChange(false);
1806     }
1807     NativeSurfaceHide();
1808     hasReleasedSurface_ = true;
1809 }
1810 
OnWindowShow()1811 void XComponentPattern::OnWindowShow()
1812 {
1813     if (!hasXComponentInit_ || !hasReleasedSurface_ ||
1814         (type_ != XComponentType::SURFACE && type_ != XComponentType::TEXTURE)) {
1815         return;
1816     }
1817     if (renderSurface_) {
1818         renderSurface_->OnWindowStateChange(true);
1819     }
1820     NativeSurfaceShow();
1821     hasReleasedSurface_ = false;
1822 }
1823 
AdjustPaintRect(float positionX,float positionY,float width,float height,bool isRound)1824 RectF XComponentPattern::AdjustPaintRect(float positionX, float positionY, float width, float height, bool isRound)
1825 {
1826     RectF rect;
1827     float relativeLeft = positionX;
1828     float relativeTop = positionY;
1829     float nodeWidth = width;
1830     float nodeHeight = height;
1831     float absoluteRight = relativeLeft + nodeWidth;
1832     float absoluteBottom = relativeTop + nodeHeight;
1833     float roundToPixelErrorX = 0;
1834     float roundToPixelErrorY = 0;
1835 
1836     float nodeLeftI = RoundValueToPixelGrid(relativeLeft, isRound, false, false);
1837     float nodeTopI = RoundValueToPixelGrid(relativeTop, isRound, false, false);
1838     roundToPixelErrorX += nodeLeftI - relativeLeft;
1839     roundToPixelErrorY += nodeTopI - relativeTop;
1840     rect.SetLeft(nodeLeftI);
1841     rect.SetTop(nodeTopI);
1842 
1843     float nodeWidthI = RoundValueToPixelGrid(absoluteRight, isRound, false, false) - nodeLeftI;
1844     float nodeWidthTemp = RoundValueToPixelGrid(nodeWidth, isRound, false, false);
1845     roundToPixelErrorX += nodeWidthI - nodeWidth;
1846     if (roundToPixelErrorX > 0.5f) {
1847         nodeWidthI -= 1.0f;
1848         roundToPixelErrorX -= 1.0f;
1849     }
1850     if (roundToPixelErrorX < -0.5f) {
1851         nodeWidthI += 1.0f;
1852         roundToPixelErrorX += 1.0f;
1853     }
1854     if (nodeWidthI < nodeWidthTemp) {
1855         roundToPixelErrorX += nodeWidthTemp - nodeWidthI;
1856         nodeWidthI = nodeWidthTemp;
1857     }
1858 
1859     float nodeHeightI = RoundValueToPixelGrid(absoluteBottom, isRound, false, false) - nodeTopI;
1860     float nodeHeightTemp = RoundValueToPixelGrid(nodeHeight, isRound, false, false);
1861     roundToPixelErrorY += nodeHeightI - nodeHeight;
1862     if (roundToPixelErrorY > 0.5f) {
1863         nodeHeightI -= 1.0f;
1864         roundToPixelErrorY -= 1.0f;
1865     }
1866     if (roundToPixelErrorY < -0.5f) {
1867         nodeHeightI += 1.0f;
1868         roundToPixelErrorY += 1.0f;
1869     }
1870     if (nodeHeightI < nodeHeightTemp) {
1871         roundToPixelErrorY += nodeHeightTemp - nodeHeightI;
1872         nodeHeightI = nodeHeightTemp;
1873     }
1874 
1875     rect.SetWidth(nodeWidthI);
1876     rect.SetHeight(nodeHeightI);
1877     return rect;
1878 }
1879 
RoundValueToPixelGrid(float value,bool isRound,bool forceCeil,bool forceFloor)1880 float XComponentPattern::RoundValueToPixelGrid(float value, bool isRound, bool forceCeil, bool forceFloor)
1881 {
1882     float fractials = fmod(value, 1.0f);
1883     if (fractials < 0.0f) {
1884         ++fractials;
1885     }
1886     if (forceCeil) {
1887         return (value - fractials + 1.0f);
1888     } else if (forceFloor) {
1889         return (value - fractials);
1890     } else if (isRound) {
1891         if (NearEqual(fractials, 1.0f) || GreatOrEqual(fractials, 0.50f)) {
1892             return (value - fractials + 1.0f);
1893         } else {
1894             return (value - fractials);
1895         }
1896     }
1897     return value;
1898 }
1899 
EnableAnalyzer(bool enable)1900 void XComponentPattern::EnableAnalyzer(bool enable)
1901 {
1902     isEnableAnalyzer_ = enable;
1903     if (!isEnableAnalyzer_) {
1904         DestroyAnalyzerOverlay();
1905         return;
1906     }
1907 
1908     CHECK_NULL_VOID(!imageAnalyzerManager_);
1909     auto host = GetHost();
1910     CHECK_NULL_VOID(host);
1911     imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(host, ImageAnalyzerHolder::XCOMPONENT);
1912 }
1913 
SetImageAIOptions(void * options)1914 void XComponentPattern::SetImageAIOptions(void* options)
1915 {
1916     if (!imageAnalyzerManager_) {
1917         imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(GetHost(), ImageAnalyzerHolder::XCOMPONENT);
1918     }
1919     CHECK_NULL_VOID(imageAnalyzerManager_);
1920     imageAnalyzerManager_->SetImageAIOptions(options);
1921 }
1922 
StartImageAnalyzer(void * config,OnAnalyzedCallback & onAnalyzed)1923 void XComponentPattern::StartImageAnalyzer(void* config, OnAnalyzedCallback& onAnalyzed)
1924 {
1925     if (!IsSupportImageAnalyzerFeature()) {
1926         CHECK_NULL_VOID(onAnalyzed);
1927         (onAnalyzed.value())(ImageAnalyzerState::UNSUPPORTED);
1928         return;
1929     }
1930 
1931     CHECK_NULL_VOID(imageAnalyzerManager_);
1932     imageAnalyzerManager_->SetImageAnalyzerConfig(config);
1933     imageAnalyzerManager_->SetImageAnalyzerCallback(onAnalyzed);
1934 
1935     auto host = GetHost();
1936     CHECK_NULL_VOID(host);
1937     auto context = host->GetContext();
1938     CHECK_NULL_VOID(context);
1939     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1940     uiTaskExecutor.PostTask(
1941         [weak = WeakClaim(this)] {
1942             auto pattern = weak.Upgrade();
1943             CHECK_NULL_VOID(pattern);
1944             pattern->CreateAnalyzerOverlay();
1945         },
1946         "ArkUIXComponentCreateAnalyzerOverlay");
1947 }
1948 
StopImageAnalyzer()1949 void XComponentPattern::StopImageAnalyzer()
1950 {
1951     DestroyAnalyzerOverlay();
1952 }
1953 
IsSupportImageAnalyzerFeature()1954 bool XComponentPattern::IsSupportImageAnalyzerFeature()
1955 {
1956     return isEnableAnalyzer_ && imageAnalyzerManager_ && imageAnalyzerManager_->IsSupportImageAnalyzerFeature();
1957 }
1958 
CreateAnalyzerOverlay()1959 void XComponentPattern::CreateAnalyzerOverlay()
1960 {
1961     auto host = GetHost();
1962     CHECK_NULL_VOID(host);
1963     host->SetOverlayNode(nullptr);
1964 
1965     auto layoutProperty = GetLayoutProperty<XComponentLayoutProperty>();
1966     CHECK_NULL_VOID(layoutProperty);
1967     auto padding  = layoutProperty->CreatePaddingAndBorder();
1968     Rect contentRect = { padding.left.value_or(0), padding.top.value_or(0), drawSize_.Width(), drawSize_.Height() };
1969     auto context = host->GetRenderContext();
1970     CHECK_NULL_VOID(context);
1971     auto nailPixelMap = context->GetThumbnailPixelMap();
1972     CHECK_NULL_VOID(nailPixelMap);
1973     auto pixelMap = nailPixelMap->GetCropPixelMap(contentRect);
1974     CHECK_NULL_VOID(pixelMap);
1975 
1976     CHECK_NULL_VOID(imageAnalyzerManager_);
1977     imageAnalyzerManager_->CreateAnalyzerOverlay(pixelMap);
1978 }
1979 
UpdateAnalyzerOverlay()1980 void XComponentPattern::UpdateAnalyzerOverlay()
1981 {
1982     auto context = GetHost()->GetRenderContext();
1983     CHECK_NULL_VOID(context);
1984     auto pixelMap = context->GetThumbnailPixelMap();
1985     CHECK_NULL_VOID(pixelMap);
1986     CHECK_NULL_VOID(imageAnalyzerManager_);
1987     imageAnalyzerManager_->UpdateAnalyzerOverlay(pixelMap);
1988 }
1989 
UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode> & geometryNode)1990 void XComponentPattern::UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode)
1991 {
1992     if (IsSupportImageAnalyzerFeature()) {
1993         CHECK_NULL_VOID(imageAnalyzerManager_);
1994         imageAnalyzerManager_->UpdateAnalyzerUIConfig(geometryNode);
1995     }
1996 }
1997 
DestroyAnalyzerOverlay()1998 void XComponentPattern::DestroyAnalyzerOverlay()
1999 {
2000     CHECK_NULL_VOID(imageAnalyzerManager_);
2001     imageAnalyzerManager_->DestroyAnalyzerOverlay();
2002 }
2003 
ReleaseImageAnalyzer()2004 void XComponentPattern::ReleaseImageAnalyzer()
2005 {
2006     CHECK_NULL_VOID(imageAnalyzerManager_);
2007     imageAnalyzerManager_->ReleaseImageAnalyzer();
2008 }
2009 
SetSurfaceRotation(bool isLock)2010 void XComponentPattern::SetSurfaceRotation(bool isLock)
2011 {
2012     if (type_ != XComponentType::SURFACE) {
2013         return;
2014     }
2015     isSurfaceLock_ = isLock;
2016 
2017     CHECK_NULL_VOID(handlingSurfaceRenderContext_);
2018     handlingSurfaceRenderContext_->SetSurfaceRotation(isLock);
2019 }
2020 
SetRenderFit(RenderFit renderFit)2021 void XComponentPattern::SetRenderFit(RenderFit renderFit)
2022 {
2023     CHECK_NULL_VOID(handlingSurfaceRenderContext_);
2024     handlingSurfaceRenderContext_->SetRenderFit(renderFit);
2025 }
2026 
EnableSecure(bool isSecure)2027 void XComponentPattern::EnableSecure(bool isSecure)
2028 {
2029     if (type_ != XComponentType::SURFACE) {
2030         return;
2031     }
2032     CHECK_NULL_VOID(renderContextForSurface_);
2033     renderContextForSurface_->SetSecurityLayer(isSecure);
2034     isEnableSecure_ = isSecure;
2035 }
2036 } // namespace OHOS::Ace::NG
2037