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