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