1 /*
2 * Copyright (c) 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 #include "core/components_ng/pattern/xcomponent/xcomponent_pattern_v2.h"
18
19 #include "interfaces/native/event/ui_input_event_impl.h"
20 #include "interfaces/native/ui_input_event.h"
21
22 #include "base/log/dump_log.h"
23 #include "base/log/frame_report.h"
24 #include "base/log/log_wrapper.h"
25 #include "base/memory/ace_type.h"
26 #include "base/ressched/ressched_report.h"
27 #include "base/utils/system_properties.h"
28 #include "base/utils/utils.h"
29 #include "core/common/ace_engine.h"
30 #include "core/common/ace_view.h"
31 #include "core/common/ai/image_analyzer_manager.h"
32 #include "core/components/common/layout/constants.h"
33 #include "core/components_ng/event/gesture_event_hub.h"
34 #include "core/components_ng/pattern/xcomponent/xcomponent_controller_ng.h"
35 #include "core/event/axis_event.h"
36 #ifdef NG_BUILD
37 #include "bridge/declarative_frontend/ng/declarative_frontend_ng.h"
38 #else
39 #include "bridge/declarative_frontend/declarative_frontend.h"
40 #endif
41 #ifdef ENABLE_ROSEN_BACKEND
42 #include "feature/anco_manager/rs_ext_node_operation.h"
43 #include "core/components_ng/render/adapter/rosen_render_context.h"
44 #endif
45
46 #include "core/components_ng/event/input_event.h"
47 #include "core/components_ng/pattern/xcomponent/xcomponent_event_hub.h"
48 #include "core/components_ng/pattern/xcomponent/xcomponent_ext_surface_callback_client.h"
49 #include "core/event/event_info_convertor.h"
50 #include "core/event/key_event.h"
51 #include "core/event/mouse_event.h"
52 #include "core/event/touch_event.h"
53 #include "core/pipeline_ng/pipeline_context.h"
54
55
56 namespace OHOS::Ace::NG {
57 namespace {
58 const std::string BUFFER_USAGE_XCOMPONENT = "xcomponent";
59 }
60
InitSurfaceMultiThread(const RefPtr<FrameNode> & host)61 void XComponentPattern::InitSurfaceMultiThread(const RefPtr<FrameNode>& host)
62 {
63 CHECK_NULL_VOID(host);
64 auto renderContext = host->GetRenderContext();
65 CHECK_NULL_VOID(renderContext);
66
67 // only xcomponent created by capi will set successfully, others will be set in FireExternalEvent
68 SetExpectedRateRangeInit();
69 OnFrameEventInit();
70 UnregisterOnFrameEventInit();
71
72 renderContext->SetClipToFrame(true);
73 renderContext->SetClipToBounds(true);
74 #ifdef RENDER_EXTRACT_SUPPORTED
75 renderSurface_ = RenderSurface::Create(CovertToRenderSurfaceType(type_));
76 #else
77 renderSurface_ = RenderSurface::Create();
78 #endif
79 renderSurface_->SetInstanceId(GetHostInstanceId());
80 std::string xComponentType = GetType() == XComponentType::SURFACE ? "s" : "t";
81 renderSurface_->SetBufferUsage(BUFFER_USAGE_XCOMPONENT + "-" + xComponentType + "-" + GetId());
82 if (type_ == XComponentType::SURFACE) {
83 InitializeRenderContext();
84 if (!SystemProperties::GetExtSurfaceEnabled()) {
85 renderSurface_->SetRenderContext(renderContextForSurface_);
86 } else {
87 extSurfaceClient_ = MakeRefPtr<XComponentExtSurfaceCallbackClient>(WeakClaim(this));
88 renderSurface_->SetExtSurfaceCallback(extSurfaceClient_);
89 #ifdef RENDER_EXTRACT_SUPPORTED
90 RegisterRenderContextCallBack();
91 #endif
92 }
93 handlingSurfaceRenderContext_ = renderContextForSurface_;
94 } else if (type_ == XComponentType::TEXTURE) {
95 renderSurface_->SetRenderContext(renderContext);
96 renderSurface_->SetIsTexture(true);
97 renderContext->OnNodeNameUpdate(GetId());
98 }
99 renderSurface_->InitSurface();
100 renderSurface_->UpdateSurfaceConfig();
101 if (type_ == XComponentType::TEXTURE) {
102 renderSurface_->RegisterBufferCallback();
103 }
104 if (isTypedNode_ || isCNode_) {
105 InitNativeWindow(initSize_.Width(), initSize_.Height());
106 }
107 surfaceId_ = renderSurface_->GetUniqueId();
108 }
109
InitControllerMultiThread()110 void XComponentPattern::InitControllerMultiThread()
111 {
112 CHECK_NULL_VOID(xcomponentController_);
113 if (!isTypedNode_) {
114 xcomponentController_->SetSurfaceId(surfaceId_);
115 }
116 auto* controllerNG = static_cast<XComponentControllerNG*>(xcomponentController_.get());
117 CHECK_NULL_VOID(controllerNG);
118 controllerNG->SetPattern(AceType::Claim(this));
119 }
120
RegisterContextEventMultiThread(const RefPtr<FrameNode> & host)121 void XComponentPattern::RegisterContextEventMultiThread(const RefPtr<FrameNode>& host)
122 {
123 CHECK_NULL_VOID(host);
124 auto pipelineContext = host->GetContextRefPtr();
125 CHECK_NULL_VOID(pipelineContext);
126 pipelineContext->AddOnAreaChangeNode(host->GetId());
127 if (!HasTransformHintChangedCallbackId()) {
128 RegisterTransformHintCallback(AceType::RawPtr(pipelineContext));
129 }
130 CHECK_NULL_VOID(xcomponentController_);
131 auto uiTaskExecutor = SingleTaskExecutor::Make(pipelineContext->GetTaskExecutor(), TaskExecutor::TaskType::UI);
132 xcomponentController_->SetConfigSurfaceImpl(
133 [weak = WeakClaim(this), uiTaskExecutor](uint32_t surfaceWidth, uint32_t surfaceHeight) {
134 uiTaskExecutor.PostSyncTask(
135 [weak, surfaceWidth, surfaceHeight]() {
136 auto pattern = weak.Upgrade();
137 CHECK_NULL_VOID(pattern);
138 pattern->ConfigSurface(surfaceWidth, surfaceHeight);
139 },
140 "ArkUIXComponentSurfaceConfigChange");
141 });
142 }
143
OnAttachToMainTreeMultiThread(const RefPtr<FrameNode> & host)144 void XComponentPattern::OnAttachToMainTreeMultiThread(const RefPtr<FrameNode>& host)
145 {
146 isOnTree_ = true;
147 RegisterContextEventMultiThread(host);
148 if (isTypedNode_ && surfaceCallbackMode_ == SurfaceCallbackMode::DEFAULT) {
149 HandleSurfaceCreated();
150 }
151 CHECK_NULL_VOID(host);
152 if (host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
153 if (needRecoverDisplaySync_ && displaySync_ && !displaySync_->IsOnPipeline()) {
154 TAG_LOGD(AceLogTag::ACE_XCOMPONENT, "OnAttachToMainTree:recover displaySync: "
155 "%{public}s(%{public}" PRIu64 ")", GetId().c_str(), displaySync_->GetId());
156 displaySync_->AddToPipelineOnContainer();
157 needRecoverDisplaySync_ = false;
158 }
159 }
160 }
161
OnDetachFromMainTreeMultiThread(const RefPtr<FrameNode> & host)162 void XComponentPattern::OnDetachFromMainTreeMultiThread(const RefPtr<FrameNode>& host)
163 {
164 isOnTree_ = false;
165 if (isTypedNode_ && surfaceCallbackMode_ == SurfaceCallbackMode::DEFAULT) {
166 HandleSurfaceDestroyed();
167 }
168 CHECK_NULL_VOID(host);
169 if (host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
170 if (displaySync_ && displaySync_->IsOnPipeline()) {
171 TAG_LOGD(AceLogTag::ACE_XCOMPONENT, "OnDetachFromMainTree:remove displaySync: "
172 "%{public}s(%{public}" PRIu64 ")", GetId().c_str(), displaySync_->GetId());
173 displaySync_->DelFromPipelineOnContainer();
174 needRecoverDisplaySync_ = true;
175 }
176 }
177 auto context = host->GetContextRefPtr();
178 CHECK_NULL_VOID(context);
179 if (HasTransformHintChangedCallbackId()) {
180 context->UnregisterTransformHintChangedCallback(transformHintChangedCallbackId_.value_or(-1));
181 transformHintChangedCallbackId_ = std::nullopt;
182 }
183 }
184
OnDetachFromFrameNodeMultiThread(FrameNode * frameNode)185 void XComponentPattern::OnDetachFromFrameNodeMultiThread(FrameNode* frameNode)
186 {
187 CHECK_NULL_VOID(frameNode);
188 UninitializeAccessibility(frameNode);
189 if (isTypedNode_) {
190 if (surfaceCallbackMode_ == SurfaceCallbackMode::PIP) {
191 HandleSurfaceDestroyed(frameNode);
192 }
193 if (isNativeXComponent_) {
194 OnNativeUnload(frameNode);
195 }
196 } else {
197 if (!hasXComponentInit_) {
198 return;
199 }
200 if (type_ == XComponentType::SURFACE || type_ == XComponentType::TEXTURE) {
201 OnSurfaceDestroyed();
202 auto eventHub = frameNode->GetEventHub<XComponentEventHub>();
203 CHECK_NULL_VOID(eventHub);
204 {
205 eventHub->FireDestroyEvent(GetId());
206 }
207 if (id_.has_value()) {
208 eventHub->FireDetachEvent(id_.value());
209 }
210 {
211 eventHub->FireControllerDestroyedEvent(surfaceId_, GetId());
212 }
213 #ifdef RENDER_EXTRACT_SUPPORTED
214 if (renderContextForSurface_) {
215 renderContextForSurface_->RemoveSurfaceChangedCallBack();
216 }
217 #endif
218 }
219 }
220 if (FrameReport::GetInstance().GetEnable()) {
221 FrameReport::GetInstance().DisableSelfRender();
222 }
223 }
224
InitSurfaceMultiThread(const RefPtr<FrameNode> & host)225 void XComponentPatternV2::InitSurfaceMultiThread(const RefPtr<FrameNode>& host)
226 {
227 CHECK_NULL_VOID(host);
228 auto renderContext = host->GetRenderContext();
229 CHECK_NULL_VOID(renderContext);
230
231 renderContext->SetClipToFrame(true);
232 renderContext->SetClipToBounds(true);
233 renderSurface_ = RenderSurface::Create();
234 renderSurface_->SetInstanceId(GetHostInstanceId());
235 if (type_ == XComponentType::SURFACE) {
236 InitializeRenderContext();
237 renderSurface_->SetRenderContext(renderContextForSurface_);
238 } else if (type_ == XComponentType::TEXTURE) {
239 renderSurface_->SetRenderContext(renderContext);
240 renderSurface_->SetIsTexture(true);
241 renderContext->OnNodeNameUpdate(GetId());
242 }
243 renderSurface_->InitSurface();
244 renderSurface_->UpdateSurfaceConfig();
245 if (type_ == XComponentType::TEXTURE) {
246 renderSurface_->RegisterBufferCallback();
247 }
248 surfaceId_ = renderSurface_->GetUniqueId();
249 }
250
OnAttachToMainTreeMultiThread(const RefPtr<FrameNode> & host)251 void XComponentPatternV2::OnAttachToMainTreeMultiThread(const RefPtr<FrameNode>& host)
252 {
253 RegisterContextEventMultiThread(host);
254 isOnTree_ = true;
255 if (autoInitialize_) {
256 HandleSurfaceCreated();
257 }
258 }
259
RegisterContextEventMultiThread(const RefPtr<FrameNode> & host)260 void XComponentPatternV2::RegisterContextEventMultiThread(const RefPtr<FrameNode>& host)
261 {
262 CHECK_NULL_VOID(host);
263 auto pipelineContext = host->GetContextRefPtr();
264 CHECK_NULL_VOID(pipelineContext);
265 if (!HasTransformHintChangedCallbackId()) {
266 RegisterTransformHintCallback(AceType::RawPtr(pipelineContext));
267 }
268 }
269
OnDetachFromMainTreeMultiThread(const RefPtr<FrameNode> & host)270 void XComponentPatternV2::OnDetachFromMainTreeMultiThread(const RefPtr<FrameNode>& host)
271 {
272 isOnTree_ = false;
273 if (autoInitialize_) {
274 HandleSurfaceDestroyed();
275 }
276 CHECK_NULL_VOID(host);
277 auto id = host->GetId();
278 auto pipeline = host->GetContextRefPtr();
279 CHECK_NULL_VOID(pipeline);
280 pipeline->RemoveWindowStateChangedCallback(id);
281 if (HasTransformHintChangedCallbackId()) {
282 pipeline->UnregisterTransformHintChangedCallback(transformHintChangedCallbackId_.value_or(-1));
283 transformHintChangedCallbackId_ = std::nullopt;
284 }
285 }
286
OnDetachFromFrameNodeMultiThread()287 void XComponentPatternV2::OnDetachFromFrameNodeMultiThread()
288 {
289 if (FrameReport::GetInstance().GetEnable()) {
290 FrameReport::GetInstance().DisableSelfRender();
291 }
292 HandleSurfaceDestroyed();
293
294 CHECK_NULL_VOID(surfaceHolder_);
295 surfaceHolder_->nativeWindow_ = nullptr;
296 surfaceHolder_->node_ = nullptr;
297 }
298
299 }
300