1 /*
2 * Copyright (c) 2023 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/ui_extension/session_wrapper_impl.h"
17
18 #include <cmath>
19 #include <memory>
20
21 #include "accessibility_event_info.h"
22 #include "refbase.h"
23 #include "session_manager/include/extension_session_manager.h"
24 #include "transaction/rs_sync_transaction_controller.h"
25 #include "transaction/rs_transaction.h"
26 #include "ui/rs_surface_node.h"
27 #include "want_params.h"
28 #include "wm/wm_common.h"
29
30 #include "adapter/ohos/entrance/ace_container.h"
31 #include "adapter/ohos/osal/want_wrap_ohos.h"
32 #include "base/error/error_code.h"
33 #include "base/utils/utils.h"
34 #include "core/common/container.h"
35 #include "core/common/container_scope.h"
36 #include "core/components_ng/pattern/ui_extension/session_wrapper.h"
37 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
38 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
39 #include "core/pipeline_ng/pipeline_context.h"
40
41 namespace OHOS::Ace::NG {
42 namespace {
43 // Defines all error names and messages.
44 constexpr char START_FAIL_NAME[] = "start_ability_fail";
45 constexpr char START_FAIL_MESSAGE[] = "Start ui extension ability failed, please check the want of UIextensionAbility.";
46 constexpr char BACKGROUND_FAIL_NAME[] = "background_fail";
47 constexpr char BACKGROUND_FAIL_MESSAGE[] = "background ui extension ability failed, please check AMS log.";
48 constexpr char TERMINATE_FAIL_NAME[] = "terminate_fail";
49 constexpr char TERMINATE_FAIL_MESSAGE[] = "terminate ui extension ability failed, please check AMS log.";
50 constexpr char PULL_FAIL_NAME[] = "extension_pulling_up_fail";
51 constexpr char PULL_FAIL_MESSAGE[] = "pulling another embedded component failed, not allowed to cascade.";
52 constexpr char EXIT_ABNORMALLY_NAME[] = "extension_exit_abnormally";
53 constexpr char EXIT_ABNORMALLY_MESSAGE[] = "the extension ability exited abnormally, please check AMS log.";
54 constexpr char LIFECYCLE_TIMEOUT_NAME[] = "extension_lifecycle_timeout";
55 constexpr char LIFECYCLE_TIMEOUT_MESSAGE[] = "the lifecycle of extension ability is timeout, please check AMS log.";
56 constexpr char EVENT_TIMEOUT_NAME[] = "handle_event_timeout";
57 constexpr char EVENT_TIMEOUT_MESSAGE[] = "the extension ability has timed out processing the key event.";
58 // Defines the want parameter to control the soft-keyboard area change of the provider.
59 constexpr char OCCUPIED_AREA_CHANGE_KEY[] = "ability.want.params.IsNotifyOccupiedAreaChange";
60 // Set the UIExtension type of the EmbeddedComponent.
61 constexpr char UI_EXTENSION_TYPE_KEY[] = "ability.want.params.uiExtensionType";
62 const std::string EMBEDDED_UI("embeddedUI");
63 constexpr int32_t AVOID_DELAY_TIME = 30;
64 constexpr int32_t INVALID_WINDOW_ID = -1;
65 } // namespace
66
67 class UIExtensionLifecycleListener : public Rosen::ILifecycleListener {
68 public:
UIExtensionLifecycleListener(const WeakPtr<SessionWrapper> & sessionWrapper)69 explicit UIExtensionLifecycleListener(const WeakPtr<SessionWrapper>& sessionWrapper)
70 : sessionWrapper_(sessionWrapper)
71 {}
72 virtual ~UIExtensionLifecycleListener() = default;
73
OnActivation()74 void OnActivation() override {}
OnForeground()75 void OnForeground() override {}
OnBackground()76 void OnBackground() override {}
77
OnConnect()78 void OnConnect() override
79 {
80 auto sessionWrapper = sessionWrapper_.Upgrade();
81 CHECK_NULL_VOID(sessionWrapper);
82 sessionWrapper->OnConnect();
83 }
84
OnDisconnect()85 void OnDisconnect() override
86 {
87 auto sessionWrapper = sessionWrapper_.Upgrade();
88 CHECK_NULL_VOID(sessionWrapper);
89 sessionWrapper->OnDisconnect(false);
90 }
91
OnExtensionDied()92 void OnExtensionDied() override
93 {
94 auto sessionWrapper = sessionWrapper_.Upgrade();
95 CHECK_NULL_VOID(sessionWrapper);
96 sessionWrapper->OnDisconnect(true);
97 }
98
OnExtensionTimeout(int32_t errorCode)99 void OnExtensionTimeout(int32_t errorCode) override
100 {
101 auto sessionWrapper = sessionWrapper_.Upgrade();
102 CHECK_NULL_VOID(sessionWrapper);
103 sessionWrapper->OnExtensionTimeout(errorCode);
104 }
105
OnExtensionDetachToDisplay()106 void OnExtensionDetachToDisplay() override
107 {
108 auto sessionWrapper = sessionWrapper_.Upgrade();
109 CHECK_NULL_VOID(sessionWrapper);
110 sessionWrapper->OnExtensionDetachToDisplay();
111 }
112
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)113 void OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset) override
114 {
115 auto sessionWrapper = sessionWrapper_.Upgrade();
116 CHECK_NULL_VOID(sessionWrapper);
117 sessionWrapper->OnAccessibilityEvent(info, uiExtensionOffset);
118 }
119
120 private:
121 WeakPtr<SessionWrapper> sessionWrapper_;
122 };
123
124 /************************************************ Begin: Initialization ***********************************************/
SessionWrapperImpl(const WeakPtr<UIExtensionPattern> & hostPattern,int32_t instanceId,bool isTransferringCaller,SessionType sessionType)125 SessionWrapperImpl::SessionWrapperImpl(const WeakPtr<UIExtensionPattern>& hostPattern, int32_t instanceId,
126 bool isTransferringCaller, SessionType sessionType)
127 : hostPattern_(hostPattern), instanceId_(instanceId), isTransferringCaller_(isTransferringCaller),
128 sessionType_(sessionType)
129 {
130 auto pattern = hostPattern.Upgrade();
131 uiExtensionId_ = pattern ? pattern->GetUiExtensionId() : 0;
132 taskExecutor_ = Container::CurrentTaskExecutor();
133 }
134
~SessionWrapperImpl()135 SessionWrapperImpl::~SessionWrapperImpl() {}
136
InitAllCallback()137 void SessionWrapperImpl::InitAllCallback()
138 {
139 CHECK_NULL_VOID(session_);
140 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
141 int32_t callSessionId = GetSessionId();
142 foregroundCallback_ = [weak = hostPattern_, taskExecutor = taskExecutor_](OHOS::Rosen::WSError errcode) {
143 if (errcode != OHOS::Rosen::WSError::WS_OK) {
144 taskExecutor->PostTask(
145 [weak, errcode] {
146 auto pattern = weak.Upgrade();
147 CHECK_NULL_VOID(pattern);
148 int32_t code = pattern->IsCompatibleOldVersion()
149 ? static_cast<int32_t>(errcode) : ERROR_CODE_UIEXTENSION_FOREGROUND_FAILED;
150 pattern->FireOnErrorCallback(code, START_FAIL_NAME, START_FAIL_MESSAGE);
151 },
152 TaskExecutor::TaskType::UI, "ArkUIUIExtensionForegroundError");
153 }
154 };
155 backgroundCallback_ = [weak = hostPattern_, taskExecutor = taskExecutor_](OHOS::Rosen::WSError errcode) {
156 if (errcode != OHOS::Rosen::WSError::WS_OK) {
157 taskExecutor->PostTask(
158 [weak, errcode] {
159 auto pattern = weak.Upgrade();
160 CHECK_NULL_VOID(pattern);
161 int32_t code = pattern->IsCompatibleOldVersion()
162 ? static_cast<int32_t>(errcode) : ERROR_CODE_UIEXTENSION_BACKGROUND_FAILED;
163 pattern->FireOnErrorCallback(
164 code, BACKGROUND_FAIL_NAME, BACKGROUND_FAIL_MESSAGE);
165 },
166 TaskExecutor::TaskType::UI, "ArkUIUIExtensionBackgroundError");
167 }
168 };
169 destructionCallback_ = [weak = hostPattern_, taskExecutor = taskExecutor_](OHOS::Rosen::WSError errcode) {
170 if (errcode != OHOS::Rosen::WSError::WS_OK) {
171 taskExecutor->PostTask(
172 [weak, errcode] {
173 auto pattern = weak.Upgrade();
174 CHECK_NULL_VOID(pattern);
175 int32_t code = pattern->IsCompatibleOldVersion()
176 ? static_cast<int32_t>(errcode) : ERROR_CODE_UIEXTENSION_DESTRUCTION_FAILED;
177 pattern->FireOnErrorCallback(
178 code, TERMINATE_FAIL_NAME, TERMINATE_FAIL_MESSAGE);
179 },
180 TaskExecutor::TaskType::UI, "ArkUIUIExtensionDestructionError");
181 }
182 };
183 sessionCallbacks->transferAbilityResultFunc_ = [weak = hostPattern_, taskExecutor = taskExecutor_,
184 sessionType = sessionType_](
185 int32_t code, const AAFwk::Want& want) {
186 taskExecutor->PostTask(
187 [weak, code, want, sessionType]() {
188 auto pattern = weak.Upgrade();
189 CHECK_NULL_VOID(pattern);
190 if (sessionType == SessionType::UI_EXTENSION_ABILITY && pattern->IsCompatibleOldVersion()) {
191 pattern->FireOnResultCallback(code, want);
192 } else {
193 pattern->FireOnTerminatedCallback(code, MakeRefPtr<WantWrapOhos>(want));
194 }
195 },
196 TaskExecutor::TaskType::UI, "ArkUIUIExtensionTransferAbilityResult");
197 };
198 sessionCallbacks->transferExtensionDataFunc_ = [weak = hostPattern_, taskExecutor = taskExecutor_](
199 const AAFwk::WantParams& params) {
200 taskExecutor->PostTask(
201 [weak, params]() {
202 auto pattern = weak.Upgrade();
203 CHECK_NULL_VOID(pattern);
204 pattern->FireOnReceiveCallback(params);
205 },
206 TaskExecutor::TaskType::UI, "ArkUIUIExtensionReceiveCallback");
207 };
208 sessionCallbacks->notifyRemoteReadyFunc_ = [weak = hostPattern_, taskExecutor = taskExecutor_]() {
209 taskExecutor->PostTask(
210 [weak]() {
211 auto pattern = weak.Upgrade();
212 CHECK_NULL_VOID(pattern);
213 pattern->FireOnRemoteReadyCallback();
214 },
215 TaskExecutor::TaskType::UI, "ArkUIUIExtensionRemoteReadyCallback");
216 };
217 sessionCallbacks->notifySyncOnFunc_ = [weak = hostPattern_, taskExecutor = taskExecutor_]() {
218 taskExecutor->PostTask(
219 [weak]() {
220 auto pattern = weak.Upgrade();
221 CHECK_NULL_VOID(pattern);
222 pattern->FireSyncCallbacks();
223 },
224 TaskExecutor::TaskType::UI, "ArkUIUIExtensionSyncCallbacks");
225 };
226 sessionCallbacks->notifyAsyncOnFunc_ = [weak = hostPattern_, taskExecutor = taskExecutor_]() {
227 taskExecutor->PostTask(
228 [weak]() {
229 auto pattern = weak.Upgrade();
230 CHECK_NULL_VOID(pattern);
231 pattern->FireAsyncCallbacks();
232 },
233 TaskExecutor::TaskType::UI, "ArkUIUIExtensionAsyncCallbacks");
234 };
235 sessionCallbacks->notifyBindModalFunc_ = [weak = hostPattern_, taskExecutor = taskExecutor_]() {
236 taskExecutor->PostSyncTask(
237 [weak]() {
238 auto pattern = weak.Upgrade();
239 CHECK_NULL_VOID(pattern);
240 pattern->FireBindModalCallback();
241 },
242 TaskExecutor::TaskType::UI, "ArkUIUIExtensionBindModalCallback");
243 };
244 sessionCallbacks->notifyGetAvoidAreaByTypeFunc_ = [instanceId = instanceId_](
245 Rosen::AvoidAreaType type) -> Rosen::AvoidArea {
246 Rosen::AvoidArea avoidArea;
247 auto container = Platform::AceContainer::GetContainer(instanceId);
248 CHECK_NULL_RETURN(container, avoidArea);
249 avoidArea = container->GetAvoidAreaByType(type);
250 return avoidArea;
251 };
252 sessionCallbacks->notifyExtensionEventFunc_ =
253 [weak = hostPattern_, taskExecutor = taskExecutor_, callSessionId](uint32_t eventId) {
254 taskExecutor->PostTask(
255 [weak, callSessionId, eventId]() {
256 auto pattern = weak.Upgrade();
257 CHECK_NULL_VOID(pattern);
258 if (callSessionId != pattern->GetSessionId()) {
259 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
260 "notifyBindModalFunc_: The callSessionId(%{public}d)"
261 " is inconsistent with the curSession(%{public}d)",
262 callSessionId, pattern->GetSessionId());
263 return;
264 }
265 pattern->OnExtensionEvent(static_cast<UIExtCallbackEventId>(eventId));
266 },
267 TaskExecutor::TaskType::UI, "ArkUIUIExtensionEventCallback");
268 };
269 }
270 /************************************************ End: Initialization *************************************************/
271
272 /************************************************ Begin: About session ************************************************/
CreateSession(const AAFwk::Want & want,const SessionConfig & config)273 void SessionWrapperImpl::CreateSession(const AAFwk::Want& want, const SessionConfig& config)
274 {
275 UIEXT_LOGI("The session is created with bundle = %{public}s, ability = %{public}s",
276 want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str());
277 auto container = Platform::AceContainer::GetContainer(instanceId_);
278 CHECK_NULL_VOID(container);
279 auto pipeline = container->GetPipelineContext();
280 CHECK_NULL_VOID(pipeline);
281 auto realHostWindowId = pipeline->GetRealHostWindowId();
282 auto wantPtr = std::make_shared<Want>(want);
283 if (sessionType_ == SessionType::UI_EXTENSION_ABILITY) {
284 if (wantPtr->GetStringParam(UI_EXTENSION_TYPE_KEY) == EMBEDDED_UI) {
285 UIEXT_LOGE("The UIExtensionComponent is not allowed to start the EmbeddedUIExtensionAbility.");
286 return;
287 }
288 if ((container->IsUIExtensionAbilityHost() && container->IsUIExtensionSubWindow())) {
289 UIEXT_LOGE("The UIExtensionComponent does not allow nested pulling of another.");
290 auto pattern = hostPattern_.Upgrade();
291 CHECK_NULL_VOID(pattern);
292 pattern->FireOnErrorCallback(ERROR_CODE_UIEXTENSION_FORBID_CASCADE, PULL_FAIL_NAME, PULL_FAIL_MESSAGE);
293 return;
294 }
295 }
296 if (sessionType_ == SessionType::EMBEDDED_UI_EXTENSION) {
297 if ((container->IsUIExtensionWindow()) ||
298 (container->IsUIExtensionAbilityProcess() && container->IsUIExtensionSubWindow())) {
299 UIEXT_LOGE("The EmbeddedComponent does not allow nested pulling of another.");
300 auto pattern = hostPattern_.Upgrade();
301 CHECK_NULL_VOID(pattern);
302 pattern->FireOnErrorCallback(ERROR_CODE_UIEXTENSION_FORBID_CASCADE, PULL_FAIL_NAME, PULL_FAIL_MESSAGE);
303 return;
304 }
305 WantParams wantParams;
306 wantPtr->SetParam(UI_EXTENSION_TYPE_KEY, EMBEDDED_UI);
307 }
308 isNotifyOccupiedAreaChange_ = want.GetBoolParam(OCCUPIED_AREA_CHANGE_KEY, true);
309 uint32_t parentWindowType = 0;
310 if (container->IsUIExtensionWindow()) {
311 parentWindowType = container->GetParentWindowType();
312 } else {
313 parentWindowType = container->GetWindowType();
314 }
315 UIEXT_LOGI("Want param isNotifyOccupiedAreaChange is %{public}d, realHostWindowId: %{public}u,"
316 " parentWindowType: %{public}u",
317 isNotifyOccupiedAreaChange_, realHostWindowId, parentWindowType);
318 auto callerToken = container->GetToken();
319 auto parentToken = container->GetParentToken();
320 Rosen::SessionInfo extensionSessionInfo = {
321 .bundleName_ = want.GetElement().GetBundleName(),
322 .abilityName_ = want.GetElement().GetAbilityName(),
323 .callerToken_ = callerToken,
324 .rootToken_ = (isTransferringCaller_ && parentToken) ? parentToken : callerToken,
325 .want = wantPtr,
326 .realParentId_ = static_cast<int32_t>(realHostWindowId),
327 .uiExtensionUsage_ = static_cast<uint32_t>(config.uiExtensionUsage),
328 .isAsyncModalBinding_ = config.isAsyncModalBinding,
329 .parentWindowType_ = parentWindowType,
330 };
331 session_ = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSession(extensionSessionInfo);
332 CHECK_NULL_VOID(session_);
333 UpdateSessionConfig();
334 lifecycleListener_ = std::make_shared<UIExtensionLifecycleListener>(AceType::WeakClaim(this));
335 session_->RegisterLifecycleListener(lifecycleListener_);
336 InitAllCallback();
337 }
338
UpdateSessionConfig()339 void SessionWrapperImpl::UpdateSessionConfig()
340 {
341 auto extConfig = session_->GetSystemConfig();
342 auto pipeline = PipelineBase::GetCurrentContext();
343 CHECK_NULL_VOID(pipeline);
344 auto hostConfig = pipeline->GetKeyboardAnimationConfig();
345 extConfig.animationIn_ = {
346 hostConfig.curveIn_.curveType_, hostConfig.curveIn_.curveParams_, hostConfig.curveIn_.duration_};
347 extConfig.animationOut_ = {
348 hostConfig.curveOut_.curveType_, hostConfig.curveOut_.curveParams_, hostConfig.curveOut_.duration_};
349 session_->SetSystemConfig(extConfig);
350 }
351
DestroySession()352 void SessionWrapperImpl::DestroySession()
353 {
354 CHECK_NULL_VOID(session_);
355 UIEXT_LOGI("DestroySession, persistentid = %{public}d.", session_->GetPersistentId());
356 session_->UnregisterLifecycleListener(lifecycleListener_);
357 session_ = nullptr;
358 }
359
IsSessionValid()360 bool SessionWrapperImpl::IsSessionValid()
361 {
362 return session_ != nullptr;
363 }
364
GetSessionId() const365 int32_t SessionWrapperImpl::GetSessionId() const
366 {
367 return session_ ? session_->GetPersistentId() : 0;
368 }
369
GetWant()370 const std::shared_ptr<AAFwk::Want> SessionWrapperImpl::GetWant()
371 {
372 return session_ ? session_->GetSessionInfo().want : nullptr;
373 }
374 /************************************************ End: About session **************************************************/
375
376 /************************************************ Begin: Synchronous interface for event notify ***********************/
NotifyFocusEventSync(bool isFocus)377 bool SessionWrapperImpl::NotifyFocusEventSync(bool isFocus)
378 {
379 return false;
380 }
NotifyFocusStateSync(bool focusState)381 bool SessionWrapperImpl::NotifyFocusStateSync(bool focusState)
382 {
383 return false;
384 }
385
NotifyBackPressedSync()386 bool SessionWrapperImpl::NotifyBackPressedSync()
387 {
388 CHECK_NULL_RETURN(session_, false);
389 bool isConsumed = false;
390 session_->TransferBackPressedEventForConsumed(isConsumed);
391 UIEXT_LOGI("Back event notified to uiextension, persistentid = %{public}d and %{public}s consumed.",
392 GetSessionId(), isConsumed ? "is" : "is not");
393 return isConsumed;
394 }
395
NotifyPointerEventSync(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)396 bool SessionWrapperImpl::NotifyPointerEventSync(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
397 {
398 return false;
399 }
400
NotifyKeyEventSync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)401 bool SessionWrapperImpl::NotifyKeyEventSync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
402 {
403 CHECK_NULL_RETURN(session_, false);
404 bool isConsumed = false;
405 bool isTimeout = false;
406 session_->TransferKeyEventForConsumed(keyEvent, isConsumed, isTimeout, isPreIme);
407 auto pattern = hostPattern_.Upgrade();
408 if (isTimeout && pattern) {
409 pattern->FireOnErrorCallback(ERROR_CODE_UIEXTENSION_EVENT_TIMEOUT, EVENT_TIMEOUT_NAME, EVENT_TIMEOUT_MESSAGE);
410 return false;
411 }
412 UIEXT_LOGI("Key event notified to uiextension, persistentid = %{public}d and %{public}s consumed.",
413 GetSessionId(), isConsumed ? "is" : "is not");
414 return isConsumed;
415 }
416
NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)417 bool SessionWrapperImpl::NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
418 {
419 CHECK_NULL_RETURN(session_, false);
420 session_->TransferKeyEventAsync(keyEvent, isPreIme);
421 return true;
422 }
423
NotifyAxisEventSync(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)424 bool SessionWrapperImpl::NotifyAxisEventSync(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
425 {
426 return false;
427 }
428 /************************************************ End: Synchronous interface for event notify *************************/
429
430 /************************************************ Begin: Asynchronous interface for event notify **********************/
NotifyFocusEventAsync(bool isFocus)431 bool SessionWrapperImpl::NotifyFocusEventAsync(bool isFocus)
432 {
433 CHECK_NULL_RETURN(session_, false);
434 UIEXT_LOGI("Notify uiextension, persistentid = %{public}d to %{public}s the focus state.",
435 GetSessionId(), isFocus ? "paint" : "clear");
436 session_->TransferFocusActiveEvent(isFocus);
437 return true;
438 }
439
NotifyFocusStateAsync(bool focusState)440 bool SessionWrapperImpl::NotifyFocusStateAsync(bool focusState)
441 {
442 CHECK_NULL_RETURN(session_, false);
443 UIEXT_LOGI("%{public}s state notified to uiextension, persistentid = %{public}d.",
444 focusState ? "focused" : "unfocused", GetSessionId());
445 session_->TransferFocusStateEvent(focusState);
446 return true;
447 }
448
NotifyBackPressedAsync()449 bool SessionWrapperImpl::NotifyBackPressedAsync()
450 {
451 return false;
452 }
NotifyPointerEventAsync(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)453 bool SessionWrapperImpl::NotifyPointerEventAsync(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
454 {
455 if (session_ && pointerEvent) {
456 UIEXT_LOGI("Transfer pointer event with 'id = %{public}d' to uiextension, persistentid = %{public}d.",
457 pointerEvent->GetId(), GetSessionId());
458 session_->TransferPointerEvent(pointerEvent);
459 }
460 return false;
461 }
NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent)462 bool SessionWrapperImpl::NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent)
463 {
464 if (session_ && keyEvent) {
465 UIEXT_LOGI("Transfer key event with 'id = %{public}d' to uiextension, persistentid = %{public}d.",
466 keyEvent->GetId(), GetSessionId());
467 session_->TransferKeyEvent(keyEvent);
468 }
469 return false;
470 }
NotifyAxisEventAsync(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)471 bool SessionWrapperImpl::NotifyAxisEventAsync(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
472 {
473 return false;
474 }
475 /************************************************ End: Asynchronous interface for event notify ************************/
476
477 /************************************************ Begin: The lifecycle interface **************************************/
NotifyCreate()478 void SessionWrapperImpl::NotifyCreate() {}
479
GetWindowSceneId()480 int32_t SessionWrapperImpl::GetWindowSceneId()
481 {
482 auto pattern = hostPattern_.Upgrade();
483 CHECK_NULL_RETURN(pattern, INVALID_WINDOW_ID);
484 auto hostWindowNode = WindowSceneHelper::FindWindowScene(pattern->GetHost());
485 CHECK_NULL_RETURN(hostWindowNode, INVALID_WINDOW_ID);
486 auto hostNode = AceType::DynamicCast<FrameNode>(hostWindowNode);
487 CHECK_NULL_RETURN(hostNode, INVALID_WINDOW_ID);
488 auto hostPattern = hostNode->GetPattern<SystemWindowScene>();
489 CHECK_NULL_RETURN(hostPattern, INVALID_WINDOW_ID);
490 auto hostSession = hostPattern->GetSession();
491 CHECK_NULL_RETURN(hostSession, INVALID_WINDOW_ID);
492 int32_t windowSceneId = hostSession->GetPersistentId();
493 if (windowSceneId != INVALID_WINDOW_ID) {
494 pattern->RegisterWindowSceneVisibleChangeCallback(hostPattern);
495 }
496 return windowSceneId;
497 }
498
NotifyForeground()499 void SessionWrapperImpl::NotifyForeground()
500 {
501 CHECK_NULL_VOID(session_);
502 auto container = Platform::AceContainer::GetContainer(instanceId_);
503 CHECK_NULL_VOID(container);
504 auto pipeline = PipelineBase::GetCurrentContext();
505 CHECK_NULL_VOID(pipeline);
506 auto hostWindowId = pipeline->GetFocusWindowId();
507 int32_t windowSceneId = GetWindowSceneId();
508 UIEXT_LOGI("NotifyForeground, persistentid = %{public}d, hostWindowId = %{public}u,"
509 " windowSceneId = %{public}d, IsScenceBoardWindow: %{public}d.",
510 session_->GetPersistentId(), hostWindowId, windowSceneId, container->IsScenceBoardWindow());
511 if (container->IsScenceBoardWindow() && windowSceneId != INVALID_WINDOW_ID) {
512 hostWindowId = static_cast<uint32_t>(windowSceneId);
513 }
514 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionActivation(
515 session_, hostWindowId, std::move(foregroundCallback_));
516 }
517
NotifyBackground(bool isHandleError)518 void SessionWrapperImpl::NotifyBackground(bool isHandleError)
519 {
520 CHECK_NULL_VOID(session_);
521 UIEXT_LOGI("NotifyBackground, persistentid = %{public}d, isHandleError = %{public}d.",
522 session_->GetPersistentId(), isHandleError);
523 if (isHandleError) {
524 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionBackground(
525 session_, std::move(backgroundCallback_));
526 } else {
527 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionBackground(
528 session_, nullptr);
529 }
530 }
531
OnReleaseDone()532 void SessionWrapperImpl::OnReleaseDone()
533 {
534 CHECK_NULL_VOID(session_);
535 UIEXT_LOGI("OnReleaseDone, persistentid = %{public}d.", session_->GetPersistentId());
536 session_->UnregisterLifecycleListener(lifecycleListener_);
537 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestructionDone(session_);
538 session_ = nullptr;
539 }
540
NotifyDestroy(bool isHandleError)541 void SessionWrapperImpl::NotifyDestroy(bool isHandleError)
542 {
543 CHECK_NULL_VOID(session_);
544 UIEXT_LOGI("NotifyDestroy, isHandleError = %{public}d, persistentid = %{public}d.",
545 isHandleError, session_->GetPersistentId());
546 if (isHandleError) {
547 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestruction(
548 session_, std::move(destructionCallback_));
549 } else {
550 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestruction(
551 session_, nullptr);
552 }
553 }
554
NotifyConfigurationUpdate()555 void SessionWrapperImpl::NotifyConfigurationUpdate() {}
556 /************************************************ End: The lifecycle interface ****************************************/
557
558 /************************************************ Begin: The interface for responsing provider ************************/
OnConnect()559 void SessionWrapperImpl::OnConnect()
560 {
561 int32_t callSessionId = GetSessionId();
562 taskExecutor_->PostTask(
563 [weak = hostPattern_, wrapperWeak = WeakClaim(this), callSessionId]() {
564 auto pattern = weak.Upgrade();
565 CHECK_NULL_VOID(pattern);
566 if (callSessionId != pattern->GetSessionId()) {
567 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnConnect: The callSessionId(%{public}d)"
568 " is inconsistent with the curSession(%{public}d)",
569 callSessionId, pattern->GetSessionId());
570 }
571 pattern->OnConnect();
572 auto wrapper = wrapperWeak.Upgrade();
573 CHECK_NULL_VOID(wrapper && wrapper->session_);
574 ContainerScope scope(wrapper->instanceId_);
575 if (auto hostWindowNode = WindowSceneHelper::FindWindowScene(pattern->GetHost())) {
576 auto hostNode = AceType::DynamicCast<FrameNode>(hostWindowNode);
577 CHECK_NULL_VOID(hostNode);
578 auto hostPattern = hostNode->GetPattern<SystemWindowScene>();
579 CHECK_NULL_VOID(hostPattern);
580 wrapper->session_->SetParentSession(hostPattern->GetSession());
581 }
582 },
583 TaskExecutor::TaskType::UI, "ArkUIUIExtensionSessionConnect");
584 }
585
OnDisconnect(bool isAbnormal)586 void SessionWrapperImpl::OnDisconnect(bool isAbnormal)
587 {
588 int32_t callSessionId = GetSessionId();
589 taskExecutor_->PostTask(
590 [weak = hostPattern_, sessionType = sessionType_, isAbnormal, callSessionId]() {
591 auto pattern = weak.Upgrade();
592 CHECK_NULL_VOID(pattern);
593 if (callSessionId != pattern->GetSessionId()) {
594 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnDisconnect: The callSessionId(%{public}d)"
595 " is inconsistent with the curSession(%{public}d)",
596 callSessionId, pattern->GetSessionId());
597 return;
598 }
599 pattern->OnDisconnect(isAbnormal);
600 if (sessionType == SessionType::UI_EXTENSION_ABILITY && pattern->IsCompatibleOldVersion()) {
601 pattern->FireOnReleaseCallback(static_cast<int32_t>(isAbnormal));
602 return;
603 }
604 if (isAbnormal) {
605 pattern->FireOnErrorCallback(
606 ERROR_CODE_UIEXTENSION_EXITED_ABNORMALLY, EXIT_ABNORMALLY_NAME, EXIT_ABNORMALLY_MESSAGE);
607 } else {
608 pattern->FireOnTerminatedCallback(0, nullptr);
609 }
610 },
611 TaskExecutor::TaskType::UI, "ArkUIUIExtensionSessionDisconnect");
612 }
613
OnExtensionTimeout(int32_t)614 void SessionWrapperImpl::OnExtensionTimeout(int32_t /* errorCode */)
615 {
616 int32_t callSessionId = GetSessionId();
617 taskExecutor_->PostTask(
618 [weak = hostPattern_, callSessionId]() {
619 auto pattern = weak.Upgrade();
620 CHECK_NULL_VOID(pattern);
621 if (callSessionId != pattern->GetSessionId()) {
622 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnExtensionTimeout: The callSessionId(%{public}d)"
623 " is inconsistent with the curSession(%{public}d)",
624 callSessionId, pattern->GetSessionId());
625 }
626 pattern->FireOnErrorCallback(
627 ERROR_CODE_UIEXTENSION_LIFECYCLE_TIMEOUT, LIFECYCLE_TIMEOUT_NAME, LIFECYCLE_TIMEOUT_MESSAGE);
628 },
629 TaskExecutor::TaskType::UI, "ArkUIUIExtensionTimeout");
630 }
631
OnExtensionDetachToDisplay()632 void SessionWrapperImpl::OnExtensionDetachToDisplay()
633 {
634 UIEXT_LOGI("OnExtensionDetachToDisplay");
635 int32_t callSessionId = GetSessionId();
636 taskExecutor_->PostTask(
637 [weak = hostPattern_, callSessionId]() {
638 auto pattern = weak.Upgrade();
639 CHECK_NULL_VOID(pattern);
640 if (callSessionId != pattern->GetSessionId()) {
641 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
642 "OnExtensionDetachToDisplay: The callSessionId(%{public}d)"
643 " is inconsistent with the curSession(%{public}d)",
644 callSessionId, pattern->GetSessionId());
645 return;
646 }
647
648 pattern->OnExtensionDetachToDisplay();
649 },
650 TaskExecutor::TaskType::UI, "ArkUIUIExtensionOnExtensionDetachToDisplay");
651 }
652
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t offset)653 void SessionWrapperImpl::OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info, int64_t offset)
654 {
655 int32_t callSessionId = GetSessionId();
656 taskExecutor_->PostTask(
657 [weak = hostPattern_, info, offset, callSessionId]() {
658 auto pattern = weak.Upgrade();
659 CHECK_NULL_VOID(pattern);
660 if (callSessionId != pattern->GetSessionId()) {
661 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnAccessibilityEvent: The callSessionId(%{public}d)"
662 " is inconsistent with the curSession(%{public}d)",
663 callSessionId, pattern->GetSessionId());
664 }
665 pattern->OnAccessibilityEvent(info, offset);
666 },
667 TaskExecutor::TaskType::UI, "ArkUIUIExtensionAccessibilityEvent");
668 }
669 /************************************************** End: The interface for responsing provider ************************/
670
671 /************************************************ Begin: The interface about the accessibility ************************/
TransferAccessibilityHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)672 void SessionWrapperImpl::TransferAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
673 int32_t eventType, int64_t timeMs)
674 {
675 CHECK_NULL_VOID(session_);
676 session_->TransferAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
677 }
678
TransferAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)679 void SessionWrapperImpl::TransferAccessibilityChildTreeRegister(
680 uint32_t windowId, int32_t treeId, int64_t accessibilityId)
681 {
682 CHECK_NULL_VOID(session_);
683 session_->TransferAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
684 }
685
TransferAccessibilityChildTreeDeregister()686 void SessionWrapperImpl::TransferAccessibilityChildTreeDeregister()
687 {
688 CHECK_NULL_VOID(session_);
689 session_->TransferAccessibilityChildTreeUnregister();
690 }
691
TransferAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)692 void SessionWrapperImpl::TransferAccessibilityDumpChildInfo(
693 const std::vector<std::string>& params, std::vector<std::string>& info)
694 {
695 CHECK_NULL_VOID(session_);
696 session_->TransferAccessibilityDumpChildInfo(params, info);
697 }
698 /************************************************ End: The interface about the accessibility **************************/
699
700 /***************************** Begin: The interface to control the display area and the avoid area ********************/
GetSurfaceNode() const701 std::shared_ptr<Rosen::RSSurfaceNode> SessionWrapperImpl::GetSurfaceNode() const
702 {
703 return session_ ? session_->GetSurfaceNode() : nullptr;
704 }
705
NotifyDisplayArea(const RectF & displayArea)706 void SessionWrapperImpl::NotifyDisplayArea(const RectF& displayArea)
707 {
708 CHECK_NULL_VOID(session_);
709 ContainerScope scope(instanceId_);
710 auto pipeline = PipelineBase::GetCurrentContext();
711 CHECK_NULL_VOID(pipeline);
712 displayAreaWindow_ = pipeline->GetCurrentWindowRect();
713 displayArea_ = displayArea + OffsetF(displayAreaWindow_.Left(), displayAreaWindow_.Top());
714 std::shared_ptr<Rosen::RSTransaction> transaction;
715 auto parentSession = session_->GetParentSession();
716 auto reason = parentSession ? parentSession->GetSizeChangeReason() : session_->GetSizeChangeReason();
717 reason_ = (uint32_t)reason;
718 auto persistentId = parentSession ? parentSession->GetPersistentId() : session_->GetPersistentId();
719 int32_t duration = 0;
720 if (reason == Rosen::SizeChangeReason::ROTATION) {
721 if (transaction_.lock()) {
722 transaction = transaction_.lock();
723 transaction_.reset();
724 } else if (auto transactionController = Rosen::RSSyncTransactionController::GetInstance()) {
725 transaction = transactionController->GetRSTransaction();
726 }
727 if (transaction && parentSession) {
728 duration = pipeline->GetSyncAnimationOption().GetDuration();
729 transaction->SetDuration(duration);
730 }
731 }
732 ACE_SCOPED_TRACE("NotifyDisplayArea displayArea[%s], curWindow[%s], reason[%d], duration[%d]",
733 displayArea_.ToString().c_str(), displayAreaWindow_.ToString().c_str(), reason, duration);
734 UIEXT_LOGI("NotifyDisplayArea displayArea = %{public}s, curWindow = %{public}s, "
735 "reason = %{public}d, duration = %{public}d, persistentId = %{public}d.",
736 displayArea_.ToString().c_str(), displayAreaWindow_.ToString().c_str(), reason, duration, persistentId);
737 session_->UpdateRect({ std::round(displayArea_.Left()), std::round(displayArea_.Top()),
738 std::round(displayArea_.Width()), std::round(displayArea_.Height()) }, reason, "NotifyDisplayArea",
739 transaction);
740 }
741
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)742 void SessionWrapperImpl::NotifySizeChangeReason(
743 WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
744 {
745 CHECK_NULL_VOID(session_);
746 auto reason = static_cast<Rosen::SizeChangeReason>(type);
747 session_->UpdateSizeChangeReason(reason);
748 if (rsTransaction && (type == WindowSizeChangeReason::ROTATION)) {
749 transaction_ = rsTransaction;
750 }
751 }
752
NotifyOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type) const753 void SessionWrapperImpl::NotifyOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type) const
754 {
755 CHECK_NULL_VOID(session_);
756 UIEXT_LOGI("NotifyAvoidArea, type: %{public}d, topRect = (%{public}d, %{public}d) - [%{public}d, %{public}d], "
757 "bottomRect = (%{public}d, %{public}d) - [%{public}d, %{public}d], persistentId = %{public}d.",
758 type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
759 (int32_t)avoidArea.topRect_.height_, avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
760 (int32_t)avoidArea.bottomRect_.width_, (int32_t)avoidArea.bottomRect_.height_, GetSessionId());
761 ACE_SCOPED_TRACE("NotifyAvoidArea, type: %d, topRect: (%d, %d) - [%d, %d], bottomRect: (%d, %d) - [%d, %d]",
762 type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
763 (int32_t)avoidArea.topRect_.height_, avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
764 (int32_t)avoidArea.bottomRect_.width_, (int32_t)avoidArea.bottomRect_.height_);
765 session_->UpdateAvoidArea(sptr<Rosen::AvoidArea>::MakeSptr(avoidArea), static_cast<Rosen::AvoidAreaType>(type));
766 }
767
NotifyOccupiedAreaChangeInfo(sptr<Rosen::OccupiedAreaChangeInfo> info,bool needWaitLayout)768 bool SessionWrapperImpl::NotifyOccupiedAreaChangeInfo(
769 sptr<Rosen::OccupiedAreaChangeInfo> info, bool needWaitLayout)
770 {
771 CHECK_NULL_RETURN(session_, false);
772 CHECK_NULL_RETURN(info, false);
773 CHECK_NULL_RETURN(isNotifyOccupiedAreaChange_, false);
774 CHECK_NULL_RETURN(taskExecutor_, false);
775 ContainerScope scope(instanceId_);
776 auto pipeline = PipelineBase::GetCurrentContext();
777 CHECK_NULL_RETURN(pipeline, false);
778 auto curWindow = pipeline->GetCurrentWindowRect();
779 int64_t curTime = GetCurrentTimestamp();
780 if (displayAreaWindow_ != curWindow && needWaitLayout) {
781 LOGI("OccupiedArea wait layout, displayAreaWindow: %{public}s, curWindow: %{public}s.",
782 displayAreaWindow_.ToString().c_str(), curWindow.ToString().c_str());
783 taskExecutor_->PostDelayedTask(
784 [info, weak = AceType::WeakClaim(this), curTime] {
785 auto session = weak.Upgrade();
786 if (session) {
787 session->InnerNotifyOccupiedAreaChangeInfo(info, true, curTime);
788 }
789 },
790 TaskExecutor::TaskType::UI, AVOID_DELAY_TIME, "ArkUIVirtualKeyboardAreaChangeDelay");
791 return true;
792 }
793
794 taskExecutor_->PostTask(
795 [info, weak = AceType::WeakClaim(this), curTime] {
796 auto session = weak.Upgrade();
797 if (session) {
798 session->InnerNotifyOccupiedAreaChangeInfo(info, false, curTime);
799 }
800 },
801 TaskExecutor::TaskType::UI, "ArkUIUecAreaChange");
802 return true;
803 }
804
InnerNotifyOccupiedAreaChangeInfo(sptr<Rosen::OccupiedAreaChangeInfo> info,bool isWaitTask,int64_t occupiedAreaTime)805 bool SessionWrapperImpl::InnerNotifyOccupiedAreaChangeInfo(
806 sptr<Rosen::OccupiedAreaChangeInfo> info, bool isWaitTask, int64_t occupiedAreaTime)
807 {
808 if (isWaitTask && occupiedAreaTime < lastOccupiedAreaTime_) {
809 UIEXT_LOGW("OccupiedArea has been executed last time, persistentid = %{public}d.",
810 GetSessionId());
811 return false;
812 }
813
814 lastOccupiedAreaTime_ = occupiedAreaTime;
815 CHECK_NULL_RETURN(session_, false);
816 CHECK_NULL_RETURN(info, false);
817 CHECK_NULL_RETURN(isNotifyOccupiedAreaChange_, false);
818 int32_t keyboardHeight = static_cast<int32_t>(info->rect_.height_);
819 ContainerScope scope(instanceId_);
820 auto pipeline = PipelineBase::GetCurrentContext();
821 CHECK_NULL_RETURN(pipeline, false);
822 auto curWindow = pipeline->GetCurrentWindowRect();
823 if (keyboardHeight > 0) {
824 if (curWindow.Bottom() >= displayArea_.Bottom()) {
825 int32_t spaceWindow = std::max(curWindow.Bottom() - displayArea_.Bottom(), 0.0);
826 keyboardHeight = static_cast<int32_t>(std::max(keyboardHeight - spaceWindow, 0));
827 } else {
828 keyboardHeight = keyboardHeight + (displayArea_.Bottom() - curWindow.Bottom());
829 }
830 }
831 sptr<Rosen::OccupiedAreaChangeInfo> newInfo = new Rosen::OccupiedAreaChangeInfo(
832 info->type_, info->rect_, info->safeHeight_, info->textFieldPositionY_, info->textFieldHeight_);
833 newInfo->rect_.height_ = static_cast<uint32_t>(keyboardHeight);
834 UIEXT_LOGI("OccupiedArea keyboardHeight = %{public}d, displayArea = %{public}s, "
835 "curWindow = %{public}s, persistentid = %{public}d.",
836 keyboardHeight, displayArea_.ToString().c_str(), curWindow.ToString().c_str(), GetSessionId());
837 session_->NotifyOccupiedAreaChangeInfo(newInfo);
838 return true;
839 }
840
SetDensityDpiImpl(bool isDensityDpi)841 void SessionWrapperImpl::SetDensityDpiImpl(bool isDensityDpi)
842 {
843 CHECK_NULL_VOID(session_);
844 if (isDensityDpi) {
845 float density = PipelineBase::GetCurrentDensity();
846 session_->NotifyDensityFollowHost(isDensityDpi, density);
847 }
848 }
849 /***************************** End: The interface to control the display area and the avoid area **********************/
850
851 /************************************************ Begin: The interface to send the data for ArkTS *********************/
SendDataAsync(const AAFwk::WantParams & params) const852 void SessionWrapperImpl::SendDataAsync(const AAFwk::WantParams& params) const
853 {
854 UIEXT_LOGI("The data is asynchronously send and the session is %{public}s", session_ ? "valid" : "invalid");
855 CHECK_NULL_VOID(session_);
856 session_->TransferComponentData(params);
857 }
858
SendDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams) const859 int32_t SessionWrapperImpl::SendDataSync(const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams) const
860 {
861 Rosen::WSErrorCode transferCode = Rosen::WSErrorCode::WS_ERROR_TRANSFER_DATA_FAILED;
862 UIEXT_LOGI("The data is synchronously send and the session is %{public}s", session_ ? "valid" : "invalid");
863 if (session_) {
864 transferCode = session_->TransferComponentDataSync(wantParams, reWantParams);
865 }
866 return static_cast<int32_t>(transferCode);
867 }
868 /************************************************ End: The interface to send the data for ArkTS ***********************/
869
870 /************************************************ Begin: The interface for UEC dump **********************************/
GetReasonDump() const871 uint32_t SessionWrapperImpl::GetReasonDump() const
872 {
873 return reason_;
874 }
875
NotifyUieDump(const std::vector<std::string> & params,std::vector<std::string> & info)876 void SessionWrapperImpl::NotifyUieDump(const std::vector<std::string>& params, std::vector<std::string>& info)
877 {
878 CHECK_NULL_VOID(session_);
879 session_->NotifyDumpInfo(params, info);
880 }
881 /************************************************ End: The interface for UEC dump **********************************/
882 } // namespace OHOS::Ace::NG
883