1 /*
2  * Copyright (c) 2023-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/ui_extension/ui_extension_pattern.h"
17 
18 #include <optional>
19 
20 #include "core/event/key_event.h"
21 #include "core/event/pointer_event.h"
22 #include "session/host/include/extension_session.h"
23 #include "session/host/include/session.h"
24 #include "ui/rs_surface_node.h"
25 
26 #include "adapter/ohos/entrance/ace_container.h"
27 #include "adapter/ohos/entrance/ace_extra_input_data.h"
28 #include "adapter/ohos/entrance/mmi_event_convertor.h"
29 #include "adapter/ohos/osal/want_wrap_ohos.h"
30 #include "base/error/error_code.h"
31 #include "base/log/dump_log.h"
32 #include "base/geometry/offset.h"
33 #include "base/error/error_code.h"
34 #include "base/utils/utils.h"
35 #include "core/common/container.h"
36 #include "core/components_ng/event/event_hub.h"
37 #include "core/components_ng/pattern/pattern.h"
38 #include "core/components_ng/pattern/text_field/text_field_manager.h"
39 #include "core/components_ng/pattern/ui_extension/modal_ui_extension_proxy_impl.h"
40 #include "core/components_ng/pattern/ui_extension/session_wrapper.h"
41 #include "core/components_ng/pattern/ui_extension/session_wrapper_factory.h"
42 #include "core/components_ng/pattern/ui_extension/session_wrapper_impl.h"
43 #include "core/components_ng/pattern/ui_extension/ui_extension_layout_algorithm.h"
44 #include "core/components_ng/pattern/ui_extension/ui_extension_surface_pattern.h"
45 #include "core/components_ng/pattern/ui_extension/ui_extension_proxy.h"
46 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
47 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
48 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
49 #include "core/components_ng/render/adapter/rosen_render_context.h"
50 #include "core/components_ng/render/adapter/rosen_window.h"
51 #include "core/event/ace_events.h"
52 #include "core/event/mouse_event.h"
53 #include "core/event/touch_event.h"
54 #include "core/pipeline/pipeline_context.h"
55 #include "core/pipeline_ng/pipeline_context.h"
56 
57 namespace OHOS::Ace::NG {
58 namespace {
59 constexpr char ABILITY_KEY_ASYNC[] = "ability.want.params.KeyAsync";
60 constexpr char ABILITY_KEY_IS_MODAL[] = "ability.want.params.IsModal";
61 constexpr char ATOMIC_SERVICE_PREFIX[] = "com.atomicservice.";
62 constexpr char PROHIBIT_NESTING_FAIL_NAME[] = "Prohibit_Nesting_SecurityUIExtensionComponent";
63 constexpr char PROHIBIT_NESTING_FAIL_MESSAGE[] =
64     "Prohibit nesting securityUIExtensionComponent in UIExtensionAbility";
65 constexpr double SHOW_START = 0.0;
66 constexpr double SHOW_FULL = 1.0;
67 constexpr char PID_FLAG[] = "pidflag";
68 constexpr char NO_EXTRA_UIE_DUMP[] = "-nouie";
69 constexpr uint32_t REMOVE_PLACEHOLDER_DELAY_TIME = 32;
70 
StartWith(const std::string & source,const std::string & prefix)71 bool StartWith(const std::string &source, const std::string &prefix)
72 {
73     if (source.empty() || prefix.empty()) {
74         return false;
75     }
76 
77     return source.find(prefix) == 0;
78 }
79 
SetInputEventExtraProperty(std::shared_ptr<MMI::PointerEvent> & newInputEvent,const std::shared_ptr<MMI::PointerEvent> & oldInputEvent)80 void SetInputEventExtraProperty(std::shared_ptr<MMI::PointerEvent>& newInputEvent,
81     const std::shared_ptr<MMI::PointerEvent>& oldInputEvent)
82 {
83     if (!newInputEvent || !oldInputEvent) {
84         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
85             "The newInputEvent or oldInputEvent is null.");
86         return;
87     }
88 
89     std::shared_ptr<const uint8_t[]> raw;
90     uint32_t length = 0;
91     oldInputEvent->GetExtraData(raw, length);
92     if (length == 0 || !raw) {
93         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
94             "The oldInputEvent no extra data.");
95     } else {
96         newInputEvent->SetExtraData(raw, length);
97     }
98 
99     newInputEvent->SetSensorInputTime(oldInputEvent->GetSensorInputTime());
100 }
101 
SetPointerEventExtraProperty(std::shared_ptr<MMI::PointerEvent> & newPointerEvent,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)102 void SetPointerEventExtraProperty(std::shared_ptr<MMI::PointerEvent>& newPointerEvent,
103     const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
104 {
105     if (!newPointerEvent) {
106         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "The New PointerEvent is null.");
107         return;
108     }
109     CHECK_NULL_VOID(pointerEvent);
110 #ifdef OHOS_BUILD_ENABLE_SECURITY_COMPONENT
111     newPointerEvent->SetEnhanceData(pointerEvent->GetEnhanceData());
112 #endif // OHOS_BUILD_ENABLE_SECURITY_COMPONENT
113 #ifdef OHOS_BUILD_ENABLE_ANCO
114     newPointerEvent->SetAncoDeal(pointerEvent->GetAncoDeal());
115 #endif // OHOS_BUILD_ENABLE_ANCO
116     newPointerEvent->SetHandlerEventType(pointerEvent->GetHandlerEventType());
117     SetInputEventExtraProperty(newPointerEvent, pointerEvent);
118 }
119 
120 class UIExtensionAccessibilityChildTreeCallback : public AccessibilityChildTreeCallback {
121 public:
UIExtensionAccessibilityChildTreeCallback(const WeakPtr<UIExtensionPattern> & weakPattern,int64_t accessibilityId)122     UIExtensionAccessibilityChildTreeCallback(const WeakPtr<UIExtensionPattern> &weakPattern, int64_t accessibilityId)
123         : AccessibilityChildTreeCallback(accessibilityId), weakPattern_(weakPattern)
124     {}
125 
126     ~UIExtensionAccessibilityChildTreeCallback() override = default;
127 
OnRegister(uint32_t windowId,int32_t treeId)128     bool OnRegister(uint32_t windowId, int32_t treeId) override
129     {
130         auto pattern = weakPattern_.Upgrade();
131         if (pattern == nullptr) {
132             return false;
133         }
134         if (isReg_) {
135             return true;
136         }
137         pattern->OnAccessibilityChildTreeRegister(windowId, treeId, GetAccessibilityId());
138         isReg_ = true;
139         return true;
140     }
141 
OnDeregister()142     bool OnDeregister() override
143     {
144         auto pattern = weakPattern_.Upgrade();
145         if (pattern == nullptr) {
146             return false;
147         }
148         if (!isReg_) {
149             return true;
150         }
151         pattern->OnAccessibilityChildTreeDeregister();
152         isReg_ = false;
153         return true;
154     }
155 
OnSetChildTree(int32_t childWindowId,int32_t childTreeId)156     bool OnSetChildTree(int32_t childWindowId, int32_t childTreeId) override
157     {
158         auto pattern = weakPattern_.Upgrade();
159         if (pattern == nullptr) {
160             return false;
161         }
162         pattern->OnSetAccessibilityChildTree(childWindowId, childTreeId);
163         return true;
164     }
165 
OnDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)166     bool OnDumpChildInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override
167     {
168         auto pattern = weakPattern_.Upgrade();
169         if (pattern == nullptr) {
170             return false;
171         }
172         pattern->OnAccessibilityDumpChildInfo(params, info);
173         return true;
174     }
175 
OnClearRegisterFlag()176     void OnClearRegisterFlag() override
177     {
178         auto pattern = weakPattern_.Upgrade();
179         if (pattern == nullptr) {
180             return;
181         }
182         isReg_ = false;
183     }
184 
185 private:
186     bool isReg_ = false;
187     WeakPtr<UIExtensionPattern> weakPattern_;
188 };
189 }
UIExtensionPattern(bool isTransferringCaller,bool isModal,bool isAsyncModalBinding,SessionType sessionType)190 UIExtensionPattern::UIExtensionPattern(
191     bool isTransferringCaller, bool isModal, bool isAsyncModalBinding, SessionType sessionType)
192     : isTransferringCaller_(isTransferringCaller), isModal_(isModal),
193     isAsyncModalBinding_(isAsyncModalBinding), sessionType_(sessionType)
194 {
195     uiExtensionId_ = UIExtensionIdUtility::GetInstance().ApplyExtensionId();
196     sessionWrapper_ = SessionWrapperFactory::CreateSessionWrapper(
197         sessionType, AceType::WeakClaim(this), instanceId_, isTransferringCaller_);
198     accessibilitySessionAdapter_ =
199         AceType::MakeRefPtr<AccessibilitySessionAdapterUIExtension>(sessionWrapper_);
200     UIEXT_LOGI("The %{public}smodal UIExtension is created.", isModal_ ? "" : "non");
201 }
202 
~UIExtensionPattern()203 UIExtensionPattern::~UIExtensionPattern()
204 {
205     UIEXT_LOGI("The %{public}smodal UIExtension is destroyed.", isModal_ ? "" : "non");
206     if (isModal_) {
207         LogoutModalUIExtension();
208     }
209     NotifyDestroy();
210     FireModalOnDestroy();
211     UIExtensionIdUtility::GetInstance().RecycleExtensionId(uiExtensionId_);
212     auto pipeline = PipelineContext::GetCurrentContext();
213     CHECK_NULL_VOID(pipeline);
214     auto uiExtensionManager = pipeline->GetUIExtensionManager();
215     CHECK_NULL_VOID(uiExtensionManager);
216     uiExtensionManager->RemoveDestroyedUIExtension(GetNodeId());
217 
218     if (accessibilityChildTreeCallback_ == nullptr) {
219         return;
220     }
221 
222     auto instanceId = GetInstanceIdFromHost();
223     ContainerScope scope(instanceId);
224     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
225     CHECK_NULL_VOID(ngPipeline);
226     auto frontend = ngPipeline->GetFrontend();
227     CHECK_NULL_VOID(frontend);
228     auto accessibilityManager = frontend->GetAccessibilityManager();
229     CHECK_NULL_VOID(accessibilityManager);
230     accessibilityManager->DeregisterAccessibilityChildTreeCallback(
231         accessibilityChildTreeCallback_->GetAccessibilityId());
232     accessibilityChildTreeCallback_ = nullptr;
233 }
234 
LogoutModalUIExtension()235 void UIExtensionPattern::LogoutModalUIExtension()
236 {
237     auto sessionId = GetSessionId();
238     UIEXT_LOGI("LogoutModalUIExtension sessionId %{public}d.", sessionId);
239     auto pipeline = PipelineContext::GetCurrentContext();
240     CHECK_NULL_VOID(pipeline);
241     auto overlay = pipeline->GetOverlayManager();
242     CHECK_NULL_VOID(overlay);
243     overlay->ResetRootNode(-(sessionId));
244 }
245 
CreateLayoutAlgorithm()246 RefPtr<LayoutAlgorithm> UIExtensionPattern::CreateLayoutAlgorithm()
247 {
248     return MakeRefPtr<UIExtensionLayoutAlgorithm>();
249 }
250 
GetFocusPattern() const251 FocusPattern UIExtensionPattern::GetFocusPattern() const
252 {
253     return { FocusType::NODE, true, FocusStyleType::FORCE_NONE };
254 }
255 
GetAccessibilitySessionAdapter()256 RefPtr<AccessibilitySessionAdapter> UIExtensionPattern::GetAccessibilitySessionAdapter()
257 {
258     return accessibilitySessionAdapter_;
259 }
260 
UpdateWant(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)261 void UIExtensionPattern::UpdateWant(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
262 {
263     if (!wantWrap) {
264         UIEXT_LOGW("wantWrap is nullptr");
265         return;
266     }
267     auto wantWrapOhos = AceType::DynamicCast<WantWrapOhos>(wantWrap);
268     if (!wantWrapOhos) {
269         UIEXT_LOGW("DynamicCast failed, wantWrapOhos is nullptr");
270         return;
271     }
272     auto want = wantWrapOhos->GetWant();
273     want_ = want.GetElement().GetBundleName().append(want.GetElement().GetAbilityName().c_str());
274     UpdateWant(want);
275 }
276 
MountPlaceholderNode(PlaceholderType type)277 void UIExtensionPattern::MountPlaceholderNode(PlaceholderType type)
278 {
279     if (!IsCanMountPlaceholder(type)) {
280         return;
281     }
282     RefPtr<NG::FrameNode> placeholderNode = nullptr;
283     auto it = placeholderMap_.find(type);
284     if (it != placeholderMap_.end()) {
285         placeholderNode = it->second;
286     }
287     CHECK_NULL_VOID(placeholderNode);
288     auto host = GetHost();
289     CHECK_NULL_VOID(host);
290     host->RemoveChildAtIndex(0);
291     host->AddChild(placeholderNode, 0);
292     ACE_SCOPED_TRACE("MountPlaceholderNode type[%d]", static_cast<int32_t>(type));
293     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
294     SetCurPlaceholderType(type);
295 }
296 
RemovePlaceholderNode()297 void UIExtensionPattern::RemovePlaceholderNode()
298 {
299     if (!IsShowPlaceholder()) {
300         return;
301     }
302     auto host = GetHost();
303     CHECK_NULL_VOID(host);
304     host->RemoveChildAtIndex(0);
305     ACE_SCOPED_TRACE("RemovePlaceholderNode type[%d]", static_cast<int32_t>(curPlaceholderType_));
306     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
307     SetCurPlaceholderType(PlaceholderType::NONE);
308 }
309 
CheckConstraint()310 bool UIExtensionPattern::CheckConstraint()
311 {
312     auto container = Platform::AceContainer::GetContainer(instanceId_);
313     CHECK_NULL_RETURN(container, false);
314     if (container->GetUIContentType() == UIContentType::SECURITY_UI_EXTENSION) {
315         UIEXT_LOGE("Not allowed nesting in SECURITY_UI_EXTENSION.");
316         FireOnErrorCallback(ERROR_CODE_UIEXTENSION_FORBID_CASCADE,
317             PROHIBIT_NESTING_FAIL_NAME, PROHIBIT_NESTING_FAIL_MESSAGE);
318         return false;
319     }
320 
321     return true;
322 }
323 
UpdateWant(const AAFwk::Want & want)324 void UIExtensionPattern::UpdateWant(const AAFwk::Want& want)
325 {
326     if (!CheckConstraint()) {
327         UIEXT_LOGE("Check constraint failed.");
328         return;
329     }
330 
331     CHECK_NULL_VOID(sessionWrapper_);
332     UIEXT_LOGI("The current state is '%{public}s' when UpdateWant, needCheck: '%{public}d'.",
333         ToString(state_), needCheckWindowSceneId_);
334     bool isBackground = state_ == AbilityState::BACKGROUND;
335     // Prohibit rebuilding the session unless the Want is updated.
336     if (sessionWrapper_->IsSessionValid()) {
337         auto sessionWant = sessionWrapper_->GetWant();
338         if (sessionWant == nullptr) {
339             UIEXT_LOGW("The sessionWrapper want is nullptr.");
340             return;
341         }
342         if (sessionWant->IsEquals(want)) {
343             return;
344         }
345         UIEXT_LOGI("The old want bundle = %{public}s, ability = %{public}s",
346             sessionWant->GetElement().GetBundleName().c_str(), sessionWant->GetElement().GetAbilityName().c_str());
347         auto host = GetHost();
348         CHECK_NULL_VOID(host);
349         host->RemoveChildAtIndex(0);
350         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
351         SetCurPlaceholderType(PlaceholderType::NONE);
352         NotifyDestroy();
353         // reset callback, in order to register childtree call back again when onConnect to new ability
354         ResetAccessibilityChildTreeCallback();
355     }
356 
357     isKeyAsync_ = want.GetBoolParam(ABILITY_KEY_ASYNC, false);
358     UIExtensionUsage uIExtensionUsage = GetUIExtensionUsage(want);
359     usage_ = uIExtensionUsage;
360     UIEXT_LOGI("The ability KeyAsync %{public}d, uIExtensionUsage: %{public}u.",
361         isKeyAsync_, uIExtensionUsage);
362     MountPlaceholderNode(PlaceholderType::INITIAL);
363     SessionConfig config;
364     config.isAsyncModalBinding = isAsyncModalBinding_;
365     config.uiExtensionUsage = uIExtensionUsage;
366     sessionWrapper_->CreateSession(want, config);
367     if (isBackground) {
368         UIEXT_LOGW("Unable to StartUiextensionAbility while in the background.");
369         return;
370     }
371     auto container = Platform::AceContainer::GetContainer(instanceId_);
372     CHECK_NULL_VOID(container);
373     if (needCheckWindowSceneId_ && container->IsScenceBoardWindow() &&
374         uIExtensionUsage != UIExtensionUsage::MODAL && !hasMountToParent_) {
375         needReNotifyForeground_ = true;
376         UIEXT_LOGI("Should NotifyForeground after MountToParent.");
377         return;
378     }
379     NotifyForeground();
380 }
381 
IsModalUec()382 bool UIExtensionPattern::IsModalUec()
383 {
384     return usage_ == UIExtensionUsage::MODAL;
385 }
386 
IsForeground()387 bool UIExtensionPattern::IsForeground()
388 {
389     return state_ == AbilityState::FOREGROUND;
390 }
391 
GetUIExtensionUsage(const AAFwk::Want & want)392 UIExtensionUsage UIExtensionPattern::GetUIExtensionUsage(const AAFwk::Want& want)
393 {
394     if (sessionType_ == SessionType::EMBEDDED_UI_EXTENSION) {
395         return UIExtensionUsage::EMBEDDED;
396     }
397 
398     if (isModal_) {
399         return UIExtensionUsage::MODAL;
400     }
401 
402     bool wantParamModal = want.GetBoolParam(ABILITY_KEY_IS_MODAL, false);
403     auto bundleName = want.GetElement().GetBundleName();
404     bool startWithAtomicService = StartWith(bundleName, ATOMIC_SERVICE_PREFIX);
405     if (wantParamModal && startWithAtomicService) {
406         return UIExtensionUsage::MODAL;
407     }
408 
409     return UIExtensionUsage::EMBEDDED;
410 }
411 
OnConnect()412 void UIExtensionPattern::OnConnect()
413 {
414     CHECK_RUN_ON(UI);
415     CHECK_NULL_VOID(sessionWrapper_);
416     UIEXT_LOGI("The session is connected and the current state is '%{public}s'.", ToString(state_));
417     ContainerScope scope(instanceId_);
418     contentNode_ = FrameNode::CreateFrameNode(V2::UI_EXTENSION_SURFACE_TAG,
419         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<UIExtensionSurfacePattern>());
420     contentNode_->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
421     contentNode_->SetHitTestMode(HitTestMode::HTMNONE);
422     auto host = GetHost();
423     CHECK_NULL_VOID(host);
424     auto&& opts = host->GetLayoutProperty()->GetSafeAreaExpandOpts();
425     if (opts && opts->Expansive()) {
426         contentNode_->GetLayoutProperty()->UpdateSafeAreaExpandOpts(*opts);
427         contentNode_->MarkModifyDone();
428     }
429     auto context = AceType::DynamicCast<NG::RosenRenderContext>(contentNode_->GetRenderContext());
430     CHECK_NULL_VOID(context);
431     auto surfaceNode = sessionWrapper_->GetSurfaceNode();
432     if (!surfaceNode) {
433         UIEXT_LOGE("Get surfaceNode from session is null.");
434         return;
435     }
436     context->SetRSNode(surfaceNode);
437     RemovePlaceholderNode();
438     host->AddChild(contentNode_, 0);
439     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
440     surfaceNode->CreateNodeInRenderThread();
441     surfaceNode->SetForeground(usage_ == UIExtensionUsage::MODAL);
442     FireOnRemoteReadyCallback();
443     auto focusHub = host->GetFocusHub();
444     if ((usage_ == UIExtensionUsage::MODAL) && focusHub) {
445         focusHub->RequestFocusImmediately();
446     }
447     bool isFocused = focusHub && focusHub->IsCurrentFocus();
448     RegisterVisibleAreaChange();
449     DispatchFocusState(isFocused);
450     DispatchFollowHostDensity(GetDensityDpi());
451     auto pipeline = host->GetContextRefPtr();
452     CHECK_NULL_VOID(pipeline);
453     auto uiExtensionManager = pipeline->GetUIExtensionManager();
454     uiExtensionManager->AddAliveUIExtension(host->GetId(), WeakClaim(this));
455     if (isFocused || (usage_ == UIExtensionUsage::MODAL)) {
456         uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
457     }
458     InitializeAccessibility();
459     ReDispatchDisplayArea();
460 }
461 
ReplacePlaceholderByContent()462 void UIExtensionPattern::ReplacePlaceholderByContent()
463 {
464     CHECK_RUN_ON(UI);
465     if (!IsShowPlaceholder()) {
466         return;
467     }
468     RemovePlaceholderNode();
469     auto host = GetHost();
470     CHECK_NULL_VOID(host);
471     host->AddChild(contentNode_, 0);
472     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
473 }
474 
OnAreaUpdated()475 void UIExtensionPattern::OnAreaUpdated()
476 {
477     PostDelayRemovePlaceholder(REMOVE_PLACEHOLDER_DELAY_TIME);
478 }
479 
RegisterWindowSceneVisibleChangeCallback(const RefPtr<Pattern> & windowScenePattern)480 void UIExtensionPattern::RegisterWindowSceneVisibleChangeCallback(
481     const RefPtr<Pattern>& windowScenePattern)
482 {
483     auto systemWindowScene = AceType::DynamicCast<SystemWindowScene>(windowScenePattern);
484     CHECK_NULL_VOID(systemWindowScene);
485     auto host = GetHost();
486     CHECK_NULL_VOID(host);
487     auto callback = [weak = WeakClaim(this)](bool visible) {
488         auto pattern = weak.Upgrade();
489         if (pattern) {
490             pattern->OnWindowSceneVisibleChange(visible);
491         }
492     };
493     systemWindowScene->RegisterVisibleChangeCallback(host->GetId(), callback);
494     weakSystemWindowScene_ = systemWindowScene;
495     UIEXT_LOGI("RegisterWindowSceneVisibleChangeCallback %{public}d.", host->GetId());
496 }
497 
UnRegisterWindowSceneVisibleChangeCallback(int32_t nodeId)498 void UIExtensionPattern::UnRegisterWindowSceneVisibleChangeCallback(int32_t nodeId)
499 {
500     auto pattern = weakSystemWindowScene_.Upgrade();
501     CHECK_NULL_VOID(pattern);
502     auto systemWindowScene = AceType::DynamicCast<SystemWindowScene>(pattern);
503     CHECK_NULL_VOID(systemWindowScene);
504     systemWindowScene->UnRegisterVisibleChangeCallback(nodeId);
505     UIEXT_LOGI("UnRegisterWindowSceneVisibleChangeCallback %{public}d.", nodeId);
506 }
507 
OnWindowSceneVisibleChange(bool visible)508 void UIExtensionPattern::OnWindowSceneVisibleChange(bool visible)
509 {
510     UIEXT_LOGI("OnWindowSceneVisibleChange %{public}d.", visible);
511     if (!visible) {
512         OnWindowHide();
513     }
514 }
515 
PostDelayRemovePlaceholder(uint32_t delay)516 void UIExtensionPattern::PostDelayRemovePlaceholder(uint32_t delay)
517 {
518     ContainerScope scope(instanceId_);
519     auto taskExecutor = Container::CurrentTaskExecutor();
520     CHECK_NULL_VOID(taskExecutor);
521     taskExecutor->PostDelayedTask(
522         [weak = WeakClaim(this)]() {
523             auto pattern = weak.Upgrade();
524             CHECK_NULL_VOID(pattern);
525             pattern->ReplacePlaceholderByContent();
526         },
527         TaskExecutor::TaskType::UI, delay, "ArkUIUIExtensionRemovePlaceholder");
528 }
529 
OnExtensionEvent(UIExtCallbackEventId eventId)530 void UIExtensionPattern::OnExtensionEvent(UIExtCallbackEventId eventId)
531 {
532     CHECK_RUN_ON(UI);
533     ContainerScope scope(instanceId_);
534     switch (eventId) {
535         case UIExtCallbackEventId::ON_AREA_CHANGED:
536             OnAreaUpdated();
537             break;
538         case UIExtCallbackEventId::ON_UEA_ACCESSIBILITY_READY:
539             OnUeaAccessibilityEventAsync();
540             break;
541     }
542 }
543 
OnUeaAccessibilityEventAsync()544 void UIExtensionPattern::OnUeaAccessibilityEventAsync()
545 {
546     auto frameNode = frameNode_.Upgrade();
547     CHECK_NULL_VOID(frameNode);
548     auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
549     CHECK_NULL_VOID(accessibilityProperty);
550     if ((accessibilityChildTreeCallback_ != nullptr) && (accessibilityProperty->GetChildTreeId() != -1)) {
551         UIEXT_LOGI("uec need notify register accessibility again %{public}d, %{public}d.",
552             accessibilityProperty->GetChildWindowId(), accessibilityProperty->GetChildTreeId());
553         ResetAccessibilityChildTreeCallback();
554         InitializeAccessibility();
555     }
556 }
557 
GetSizeChangeReason()558 PlaceholderType UIExtensionPattern::GetSizeChangeReason()
559 {
560     CHECK_NULL_RETURN(sessionWrapper_, PlaceholderType::NONE);
561     if (IsFoldStatusChanged()) {
562         SetFoldStatusChanged(false);
563         return PlaceholderType::FOLD_TO_EXPAND;
564     }
565     if (IsRotateStatusChanged()) {
566         SetRotateStatusChanged(false);
567         return PlaceholderType::ROTATION;
568     }
569     return PlaceholderType::UNDEFINED;
570 }
571 
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)572 void UIExtensionPattern::OnAccessibilityEvent(
573     const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset)
574 {
575     UIEXT_LOGI("The accessibility event is reported and the current state is '%{public}s'.", ToString(state_));
576     ContainerScope scope(instanceId_);
577     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
578     CHECK_NULL_VOID(ngPipeline);
579     uiExtensionOffset = uiExtensionId_ * NG::UI_EXTENSION_OFFSET_MAX + uiExtensionOffset;
580     auto frontend = ngPipeline->GetFrontend();
581     CHECK_NULL_VOID(frontend);
582     auto accessibilityManager = frontend->GetAccessibilityManager();
583     CHECK_NULL_VOID(accessibilityManager);
584     accessibilityManager->SendExtensionAccessibilityEvent(info, uiExtensionOffset);
585 }
586 
OnDisconnect(bool isAbnormal)587 void UIExtensionPattern::OnDisconnect(bool isAbnormal)
588 {
589     CHECK_RUN_ON(UI);
590     UIEXT_LOGI("The session is disconnected and the current state is '%{public}s'.", ToString(state_));
591     auto host = GetHost();
592     CHECK_NULL_VOID(host);
593     host->RemoveChildAtIndex(0);
594     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
595     SetCurPlaceholderType(PlaceholderType::NONE);
596 }
597 
OnSyncGeometryNode(const DirtySwapConfig & config)598 void UIExtensionPattern::OnSyncGeometryNode(const DirtySwapConfig& config)
599 {
600     if (needReNotifyForeground_) {
601         needReNotifyForeground_ = false;
602         UIEXT_LOGI("NotifyForeground onSyncGeometryNode first.");
603         NotifyForeground();
604         needReDispatchDisplayArea_ = true;
605     }
606     DispatchDisplayArea(true);
607 }
608 
ReDispatchDisplayArea()609 void UIExtensionPattern::ReDispatchDisplayArea()
610 {
611     if (needReDispatchDisplayArea_) {
612         UIEXT_LOGI("ReDispatchDisplayArea.");
613         DispatchDisplayArea(true);
614         needReDispatchDisplayArea_ = false;
615     }
616 }
617 
OnWindowShow()618 void UIExtensionPattern::OnWindowShow()
619 {
620     UIEXT_LOGI("The window is being shown and the component is %{public}s.", isVisible_ ? "visible" : "invisible");
621     if (isVisible_) {
622         NotifyForeground();
623     }
624 }
625 
OnWindowHide()626 void UIExtensionPattern::OnWindowHide()
627 {
628     UIEXT_LOGI("The window is being hidden and the component is %{public}s, state is '%{public}s.",
629         isVisible_ ? "visible" : "invisible", ToString(state_));
630     if (isVisible_) {
631         NotifyBackground();
632     } else if (state_ == AbilityState::FOREGROUND) {
633         NotifyBackground(false);
634     }
635 }
636 
OnWindowSizeChanged(int32_t,int32_t,WindowSizeChangeReason type)637 void UIExtensionPattern::OnWindowSizeChanged(int32_t  /*width*/, int32_t  /*height*/, WindowSizeChangeReason type)
638 {
639     if (WindowSizeChangeReason::ROTATION == type) {
640         SetRotateStatusChanged(true);
641     }
642 }
643 
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)644 void UIExtensionPattern::NotifySizeChangeReason(
645     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
646 {
647     CHECK_NULL_VOID(sessionWrapper_);
648     sessionWrapper_->NotifySizeChangeReason(type, rsTransaction);
649 }
650 
OnExtensionDetachToDisplay()651 void UIExtensionPattern::OnExtensionDetachToDisplay()
652 {
653     if (contentNode_ == nullptr) {
654         UIEXT_LOGW("ContentNode is null when OnExtensionDetachToDisplay.");
655         return;
656     }
657 
658     UIEXT_LOGI("OnExtensionDetachToDisplay");
659     auto host = GetHost();
660     CHECK_NULL_VOID(host);
661     host->RemoveChild(contentNode_);
662     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
663 }
664 
NotifyForeground()665 void UIExtensionPattern::NotifyForeground()
666 {
667     if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::FOREGROUND) {
668         UIEXT_LOGI("The state is changing from '%{public}s' to 'FOREGROUND'.", ToString(state_));
669         state_ = AbilityState::FOREGROUND;
670         sessionWrapper_->NotifyForeground();
671     }
672 }
673 
NotifyBackground(bool isHandleError)674 void UIExtensionPattern::NotifyBackground(bool isHandleError)
675 {
676     if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ == AbilityState::FOREGROUND) {
677         UIEXT_LOGI("The state is changing from '%{public}s' to 'BACKGROUND'.", ToString(state_));
678         state_ = AbilityState::BACKGROUND;
679         sessionWrapper_->NotifyBackground(isHandleError);
680     }
681 }
682 
NotifyDestroy()683 void UIExtensionPattern::NotifyDestroy()
684 {
685     if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::DESTRUCTION &&
686         state_ != AbilityState::NONE) {
687         UIEXT_LOGI("The state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
688         state_ = AbilityState::DESTRUCTION;
689         sessionWrapper_->NotifyDestroy();
690         sessionWrapper_->DestroySession();
691     }
692 }
693 
OnAttachToFrameNode()694 void UIExtensionPattern::OnAttachToFrameNode()
695 {
696     ContainerScope scope(instanceId_);
697     auto pipeline = PipelineContext::GetCurrentContext();
698     CHECK_NULL_VOID(pipeline);
699     auto host = GetHost();
700     CHECK_NULL_VOID(host);
701     auto eventHub = host->GetEventHub<EventHub>();
702     CHECK_NULL_VOID(eventHub);
703     OnAreaChangedFunc onAreaChangedFunc = [weak = WeakClaim(this)](
704         const RectF& oldRect,
705         const OffsetF& oldOrigin,
706         const RectF& rect,
707         const OffsetF& origin) {
708             auto pattern = weak.Upgrade();
709             CHECK_NULL_VOID(pattern);
710             pattern->DispatchDisplayArea();
711     };
712     eventHub->AddInnerOnAreaChangedCallback(host->GetId(), std::move(onAreaChangedFunc));
713     pipeline->AddOnAreaChangeNode(host->GetId());
714     pipeline->AddWindowSizeChangeCallback(host->GetId());
715     surfacePositionCallBackId_ =
716         pipeline->RegisterSurfacePositionChangedCallback([weak = WeakClaim(this)](int32_t, int32_t) {
717         auto pattern = weak.Upgrade();
718         CHECK_NULL_VOID(pattern);
719         pattern->DispatchDisplayArea(true);
720     });
721     foldDisplayCallBackId_ =
722         pipeline->RegisterFoldDisplayModeChangedCallback([weak = WeakClaim(this)](FoldDisplayMode foldDisplayMode) {
723         auto pattern = weak.Upgrade();
724         CHECK_NULL_VOID(pattern);
725         pattern->SetFoldStatusChanged(true);
726     });
727     UIEXT_LOGI("OnAttachToFrameNode");
728 }
729 
OnDetachFromFrameNode(FrameNode * frameNode)730 void UIExtensionPattern::OnDetachFromFrameNode(FrameNode* frameNode)
731 {
732     auto id = frameNode->GetId();
733     UnRegisterWindowSceneVisibleChangeCallback(id);
734     ContainerScope scope(instanceId_);
735     auto pipeline = PipelineContext::GetCurrentContext();
736     CHECK_NULL_VOID(pipeline);
737     pipeline->RemoveOnAreaChangeNode(id);
738     pipeline->RemoveWindowSizeChangeCallback(id);
739     pipeline->RemoveWindowStateChangedCallback(id);
740     pipeline->UnregisterSurfacePositionChangedCallback(surfacePositionCallBackId_);
741     pipeline->UnRegisterFoldDisplayModeChangedCallback(foldDisplayCallBackId_);
742 }
743 
OnModifyDone()744 void UIExtensionPattern::OnModifyDone()
745 {
746     Pattern::OnModifyDone();
747     auto host = GetHost();
748     CHECK_NULL_VOID(host);
749     auto hub = host->GetEventHub<EventHub>();
750     CHECK_NULL_VOID(hub);
751     auto gestureHub = hub->GetOrCreateGestureEventHub();
752     CHECK_NULL_VOID(gestureHub);
753     InitTouchEvent(gestureHub);
754     auto inputHub = hub->GetOrCreateInputEventHub();
755     CHECK_NULL_VOID(inputHub);
756     InitMouseEvent(inputHub);
757     InitHoverEvent(inputHub);
758     auto focusHub = host->GetFocusHub();
759     CHECK_NULL_VOID(focusHub);
760     InitKeyEvent(focusHub);
761 }
762 
InitKeyEvent(const RefPtr<FocusHub> & focusHub)763 void UIExtensionPattern::InitKeyEvent(const RefPtr<FocusHub>& focusHub)
764 {
765     focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
766         auto pattern = weak.Upgrade();
767         if (pattern) {
768             pattern->HandleFocusEvent();
769         }
770     });
771 
772     focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
773         auto pattern = weak.Upgrade();
774         if (pattern) {
775             pattern->HandleBlurEvent();
776         }
777     });
778 
779     focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
780         auto pattern = weak.Upgrade();
781         if (pattern) {
782             pattern->DispatchFocusActiveEvent(false);
783         }
784     });
785     focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
786         auto pattern = weak.Upgrade();
787         if (pattern) {
788             pattern->DispatchFocusActiveEvent(true);
789             return true;
790         }
791         return false;
792     });
793 
794     focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
795         auto pattern = wp.Upgrade();
796         if (pattern) {
797             return pattern->HandleKeyEvent(event);
798         }
799         return false;
800     });
801 }
802 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)803 void UIExtensionPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
804 {
805     if (touchEvent_) {
806         return;
807     }
808     auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
809         auto pattern = weak.Upgrade();
810         if (pattern) {
811             pattern->HandleTouchEvent(info);
812         }
813     };
814     if (touchEvent_) {
815         gestureHub->RemoveTouchEvent(touchEvent_);
816     }
817     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
818     gestureHub->AddTouchEvent(touchEvent_);
819 }
820 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)821 void UIExtensionPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
822 {
823     if (mouseEvent_) {
824         return;
825     }
826     auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
827         auto pattern = weak.Upgrade();
828         if (pattern) {
829             pattern->HandleMouseEvent(info);
830         }
831     };
832     if (mouseEvent_) {
833         inputHub->RemoveOnMouseEvent(mouseEvent_);
834     }
835     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
836     inputHub->AddOnMouseEvent(mouseEvent_);
837 }
838 
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)839 void UIExtensionPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
840 {
841     if (hoverEvent_) {
842         return;
843     }
844     auto callback = [weak = WeakClaim(this)](bool isHover) {
845         auto pattern = weak.Upgrade();
846         if (pattern) {
847             pattern->HandleHoverEvent(isHover);
848         }
849     };
850     if (hoverEvent_) {
851         inputHub->RemoveOnHoverEvent(hoverEvent_);
852     }
853     hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
854     inputHub->AddOnHoverEvent(hoverEvent_);
855 }
856 
HandleKeyEvent(const KeyEvent & event)857 bool UIExtensionPattern::HandleKeyEvent(const KeyEvent& event)
858 {
859     return DispatchKeyEventSync(event);
860 }
861 
HandleFocusEvent()862 void UIExtensionPattern::HandleFocusEvent()
863 {
864     auto pipeline = PipelineContext::GetCurrentContext();
865     CHECK_NULL_VOID(pipeline);
866     if (canFocusSendToUIExtension_) {
867         if (pipeline->GetIsFocusActive()) {
868             DispatchFocusActiveEvent(true);
869         }
870 
871         DispatchFocusState(true);
872         needReSendFocusToUIExtension_ = false;
873     } else {
874         needReSendFocusToUIExtension_ = true;
875     }
876 
877     canFocusSendToUIExtension_ = true;
878     auto uiExtensionManager = pipeline->GetUIExtensionManager();
879     uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
880 }
881 
HandleBlurEvent()882 void UIExtensionPattern::HandleBlurEvent()
883 {
884     DispatchFocusActiveEvent(false);
885     DispatchFocusState(false);
886     auto pipeline = PipelineContext::GetCurrentContext();
887     CHECK_NULL_VOID(pipeline);
888     auto uiExtensionManager = pipeline->GetUIExtensionManager();
889     uiExtensionManager->RegisterUIExtensionInFocus(nullptr, nullptr);
890 }
891 
HandleTouchEvent(const TouchEventInfo & info)892 void UIExtensionPattern::HandleTouchEvent(const TouchEventInfo& info)
893 {
894     if (info.GetSourceDevice() != SourceType::TOUCH) {
895         UIEXT_LOGE("The source type is not TOUCH.");
896         return;
897     }
898     const auto pointerEvent = info.GetPointerEvent();
899     if (!pointerEvent) {
900         UIEXT_LOGE("The pointerEvent is empty.");
901         return;
902     }
903     auto host = GetHost();
904     CHECK_NULL_VOID(host);
905     auto pipeline = PipelineBase::GetCurrentContext();
906     CHECK_NULL_VOID(pipeline);
907     AceExtraInputData::InsertInterpolatePoints(info);
908     std::shared_ptr<MMI::PointerEvent> newPointerEvent = std::make_shared<MMI::PointerEvent>(*pointerEvent);
909     SetPointerEventExtraProperty(newPointerEvent, pointerEvent);
910     Platform::CalculatePointerEvent(newPointerEvent, host);
911     auto focusHub = host->GetFocusHub();
912     CHECK_NULL_VOID(focusHub);
913     bool ret = true;
914     if (pipeline->IsWindowFocused() && !focusHub->IsCurrentFocus()) {
915         canFocusSendToUIExtension_ = false;
916         ret = focusHub->RequestFocusImmediately();
917         if (!ret) {
918             canFocusSendToUIExtension_ = true;
919             UIEXT_LOGW("RequestFocusImmediately failed when HandleTouchEvent.");
920         }
921     }
922     focusState_ = pipeline->IsWindowFocused();
923     DispatchPointerEvent(newPointerEvent);
924     if (pipeline->IsWindowFocused() && needReSendFocusToUIExtension_ &&
925         newPointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) {
926         HandleFocusEvent();
927         needReSendFocusToUIExtension_ = false;
928     }
929 }
930 
HandleMouseEvent(const MouseInfo & info)931 void UIExtensionPattern::HandleMouseEvent(const MouseInfo& info)
932 {
933     if (info.GetSourceDevice() != SourceType::MOUSE) {
934         return;
935     }
936     if (info.GetPullAction() == MouseAction::PULL_MOVE || info.GetPullAction() == MouseAction::PULL_UP) {
937         return;
938     }
939     const auto pointerEvent = info.GetPointerEvent();
940     CHECK_NULL_VOID(pointerEvent);
941     lastPointerEvent_ = pointerEvent;
942     auto host = GetHost();
943     CHECK_NULL_VOID(host);
944     Platform::CalculatePointerEvent(pointerEvent, host);
945     if (info.GetAction() == MouseAction::PRESS) {
946         auto hub = host->GetFocusHub();
947         CHECK_NULL_VOID(hub);
948         hub->RequestFocusImmediately();
949     }
950     DispatchPointerEvent(pointerEvent);
951 }
952 
HandleHoverEvent(bool isHover)953 void UIExtensionPattern::HandleHoverEvent(bool isHover)
954 {
955     if (isHover) {
956         return;
957     }
958     CHECK_NULL_VOID(lastPointerEvent_);
959     lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
960     DispatchPointerEvent(lastPointerEvent_);
961 }
962 
DispatchKeyEvent(const KeyEvent & event)963 void UIExtensionPattern::DispatchKeyEvent(const KeyEvent& event)
964 {
965     CHECK_NULL_VOID(event.rawKeyEvent);
966     CHECK_NULL_VOID(sessionWrapper_);
967     sessionWrapper_->NotifyKeyEventAsync(event.rawKeyEvent);
968 }
969 
DispatchKeyEventSync(const KeyEvent & event)970 bool UIExtensionPattern::DispatchKeyEventSync(const KeyEvent& event)
971 {
972     CHECK_NULL_RETURN(sessionWrapper_, false);
973     if (isKeyAsync_) {
974         sessionWrapper_->NotifyKeyEventAsync(event.rawKeyEvent, false);
975         return true;
976     }
977 
978     return sessionWrapper_->NotifyKeyEventSync(event.rawKeyEvent, event.isPreIme);
979 }
980 
DispatchFocusActiveEvent(bool isFocusActive)981 void UIExtensionPattern::DispatchFocusActiveEvent(bool isFocusActive)
982 {
983     CHECK_NULL_VOID(sessionWrapper_);
984     sessionWrapper_->NotifyFocusEventAsync(isFocusActive);
985 }
986 
DispatchFocusState(bool focusState)987 void UIExtensionPattern::DispatchFocusState(bool focusState)
988 {
989     CHECK_NULL_VOID(sessionWrapper_);
990     sessionWrapper_->NotifyFocusStateAsync(focusState);
991 }
992 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)993 void UIExtensionPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
994 {
995     if (!pointerEvent) {
996         UIEXT_LOGE("DispatchPointerEvent pointerEvent is null.");
997         return;
998     }
999     if (!sessionWrapper_) {
1000         UIEXT_LOGE("DispatchPointerEvent sessionWrapper is null.");
1001         return;
1002     }
1003     sessionWrapper_->NotifyPointerEventAsync(pointerEvent);
1004 }
1005 
DispatchDisplayArea(bool isForce)1006 void UIExtensionPattern::DispatchDisplayArea(bool isForce)
1007 {
1008     CHECK_NULL_VOID(sessionWrapper_);
1009     auto host = GetHost();
1010     CHECK_NULL_VOID(host);
1011     auto [displayOffset, err] = host->GetPaintRectGlobalOffsetWithTranslate();
1012     auto geometryNode = host->GetGeometryNode();
1013     CHECK_NULL_VOID(geometryNode);
1014     auto renderContext = host->GetRenderContext();
1015     CHECK_NULL_VOID(renderContext);
1016     auto displaySize = renderContext->GetPaintRectWithoutTransform().GetSize();
1017     auto displayArea = RectF(displayOffset, displaySize);
1018     bool sizeChange = displayArea_ != displayArea;
1019     if (sizeChange || isForce) {
1020         displayArea_ = displayArea;
1021         if (sizeChange) {
1022             MountPlaceholderNode(GetSizeChangeReason());
1023         }
1024         sessionWrapper_->NotifyDisplayArea(displayArea_);
1025     }
1026 }
1027 
HandleDragEvent(const PointerEvent & info)1028 void UIExtensionPattern::HandleDragEvent(const PointerEvent& info)
1029 {
1030     auto pointerEvent = info.rawPointerEvent;
1031     CHECK_NULL_VOID(pointerEvent);
1032     auto host = GetHost();
1033     CHECK_NULL_VOID(host);
1034     auto pipeline = PipelineBase::GetCurrentContext();
1035     CHECK_NULL_VOID(pipeline);
1036     Platform::CalculatePointerEvent(pointerEvent, host, true);
1037     Platform::UpdatePointerAction(pointerEvent, info.action);
1038     DispatchPointerEvent(pointerEvent);
1039 }
1040 
SetOnRemoteReadyCallback(const std::function<void (const RefPtr<UIExtensionProxy> &)> && callback)1041 void UIExtensionPattern::SetOnRemoteReadyCallback(const std::function<void(const RefPtr<UIExtensionProxy>&)>&& callback)
1042 {
1043     onRemoteReadyCallback_ = std::move(callback);
1044 }
1045 
SetModalOnRemoteReadyCallback(const std::function<void (const std::shared_ptr<ModalUIExtensionProxy> &)> && callback)1046 void UIExtensionPattern::SetModalOnRemoteReadyCallback(
1047     const std::function<void(const std::shared_ptr<ModalUIExtensionProxy>&)>&& callback)
1048 {
1049     onModalRemoteReadyCallback_ = std::move(callback);
1050 }
1051 
FireOnRemoteReadyCallback()1052 void UIExtensionPattern::FireOnRemoteReadyCallback()
1053 {
1054     UIEXT_LOGI("OnRemoteReady the current state is '%{public}s'.", ToString(state_));
1055     ContainerScope scope(instanceId_);
1056     // These two callbacks will be unified in the future.
1057     if (onRemoteReadyCallback_) {
1058         onRemoteReadyCallback_(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1059     }
1060     if (onModalRemoteReadyCallback_) {
1061         onModalRemoteReadyCallback_(std::make_shared<ModalUIExtensionProxyImpl>(sessionWrapper_));
1062     }
1063 }
1064 
SetModalOnDestroy(const std::function<void ()> && callback)1065 void UIExtensionPattern::SetModalOnDestroy(const std::function<void()>&& callback)
1066 {
1067     onModalDestroy_ = std::move(callback);
1068 }
1069 
FireModalOnDestroy()1070 void UIExtensionPattern::FireModalOnDestroy()
1071 {
1072     UIEXT_LOGI("ModalOnDestroy the current state is '%{public}s'.", ToString(state_));
1073     // Native modal page destroy callback
1074     if (onModalDestroy_) {
1075         ContainerScope scope(instanceId_);
1076         onModalDestroy_();
1077     }
1078 }
1079 
SetOnReleaseCallback(const std::function<void (int32_t)> && callback)1080 void UIExtensionPattern::SetOnReleaseCallback(const std::function<void(int32_t)>&& callback)
1081 {
1082     onReleaseCallback_ = std::move(callback);
1083 }
1084 
FireOnReleaseCallback(int32_t releaseCode)1085 void UIExtensionPattern::FireOnReleaseCallback(int32_t releaseCode)
1086 {
1087     UIEXT_LOGI("OnRelease the state is changing from '%{public}s' to 'DESTRUCTION' and releaseCode = %{public}d.",
1088         ToString(state_), releaseCode);
1089     state_ = AbilityState::DESTRUCTION;
1090     if (onReleaseCallback_) {
1091         onReleaseCallback_(releaseCode);
1092     }
1093     // Release the session.
1094     if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
1095         sessionWrapper_->OnReleaseDone();
1096     }
1097 }
1098 
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)1099 void UIExtensionPattern::SetOnErrorCallback(
1100     const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
1101 {
1102     onErrorCallback_ = std::move(callback);
1103     if (lastError_.code != 0) {
1104         ErrorMsg error;
1105         std::swap(lastError_, error);
1106         FireOnErrorCallback(error.code, error.name, error.message);
1107     }
1108 }
1109 
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)1110 void UIExtensionPattern::FireOnErrorCallback(int32_t code, const std::string& name, const std::string& message)
1111 {
1112     // 1. As long as the error occurs, the host believes that UIExtensionAbility has been killed.
1113     UIEXT_LOGI("OnError the state is changing from '%{public}s' to 'NONE'.", ToString(state_));
1114     state_ = AbilityState::NONE;
1115     // Release the session.
1116     if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
1117         if (!IsShowPlaceholder()) {
1118             auto host = GetHost();
1119             CHECK_NULL_VOID(host);
1120             host->RemoveChildAtIndex(0);
1121             host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1122         }
1123         sessionWrapper_->NotifyDestroy(false);
1124         sessionWrapper_->DestroySession();
1125     }
1126     if (onErrorCallback_) {
1127         ContainerScope scope(instanceId_);
1128         onErrorCallback_(code, name, message);
1129         return;
1130     }
1131     lastError_ = { code, name, message };
1132 }
1133 
SetOnResultCallback(const std::function<void (int32_t,const AAFwk::Want &)> && callback)1134 void UIExtensionPattern::SetOnResultCallback(const std::function<void(int32_t, const AAFwk::Want&)>&& callback)
1135 {
1136     onResultCallback_ = std::move(callback);
1137 }
1138 
FireOnResultCallback(int32_t code,const AAFwk::Want & want)1139 void UIExtensionPattern::FireOnResultCallback(int32_t code, const AAFwk::Want& want)
1140 {
1141     UIEXT_LOGI("OnResult the state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
1142     if (onResultCallback_ && (state_ != AbilityState::DESTRUCTION)) {
1143         ContainerScope scope(instanceId_);
1144         onResultCallback_(code, want);
1145     }
1146     state_ = AbilityState::DESTRUCTION;
1147 }
1148 
IsCompatibleOldVersion()1149 bool UIExtensionPattern::IsCompatibleOldVersion()
1150 {
1151     ContainerScope scope(instanceId_);
1152     return (sessionType_ == SessionType::UI_EXTENSION_ABILITY) && (onTerminatedCallback_ == nullptr);
1153 }
1154 
SetOnTerminatedCallback(const std::function<void (int32_t,const RefPtr<WantWrap> & wantWrap)> && callback)1155 void UIExtensionPattern::SetOnTerminatedCallback(
1156     const std::function<void(int32_t, const RefPtr<WantWrap>& wantWrap)>&& callback)
1157 {
1158     onTerminatedCallback_ = std::move(callback);
1159 }
1160 
FireOnTerminatedCallback(int32_t code,const RefPtr<WantWrap> & wantWrap)1161 void UIExtensionPattern::FireOnTerminatedCallback(int32_t code, const RefPtr<WantWrap>& wantWrap)
1162 {
1163     UIEXT_LOGI("OnTerminated the state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
1164     if (onTerminatedCallback_ && (state_ != AbilityState::DESTRUCTION)) {
1165         ContainerScope scope(instanceId_);
1166         onTerminatedCallback_(code, wantWrap);
1167     }
1168     state_ = AbilityState::DESTRUCTION;
1169 }
1170 
SetOnReceiveCallback(const std::function<void (const AAFwk::WantParams &)> && callback)1171 void UIExtensionPattern::SetOnReceiveCallback(const std::function<void(const AAFwk::WantParams&)>&& callback)
1172 {
1173     onReceiveCallback_ = std::move(callback);
1174 }
1175 
FireOnReceiveCallback(const AAFwk::WantParams & params)1176 void UIExtensionPattern::FireOnReceiveCallback(const AAFwk::WantParams& params)
1177 {
1178     UIEXT_LOGI("OnReceive the current state is '%{public}s'.", ToString(state_));
1179     if (onReceiveCallback_) {
1180         ContainerScope scope(instanceId_);
1181         onReceiveCallback_(params);
1182     }
1183 }
1184 
SetSyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)1185 void UIExtensionPattern::SetSyncCallbacks(
1186     const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
1187 {
1188     onSyncOnCallbackList_ = std::move(callbackList);
1189 }
1190 
FireSyncCallbacks()1191 void UIExtensionPattern::FireSyncCallbacks()
1192 {
1193     UIEXT_LOGD("The size of sync callbacks = %{public}zu.", onSyncOnCallbackList_.size());
1194     ContainerScope scope(instanceId_);
1195     for (const auto& callback : onSyncOnCallbackList_) {
1196         if (callback) {
1197             callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1198         }
1199     }
1200 }
1201 
SetAsyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)1202 void UIExtensionPattern::SetAsyncCallbacks(
1203     const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
1204 {
1205     onAsyncOnCallbackList_ = std::move(callbackList);
1206 }
1207 
FireAsyncCallbacks()1208 void UIExtensionPattern::FireAsyncCallbacks()
1209 {
1210     UIEXT_LOGD("The size of async callbacks = %{public}zu.", onSyncOnCallbackList_.size());
1211     ContainerScope scope(instanceId_);
1212     for (const auto& callback : onAsyncOnCallbackList_) {
1213         if (callback) {
1214             callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1215         }
1216     }
1217 }
1218 
SetBindModalCallback(const std::function<void ()> && callback)1219 void UIExtensionPattern::SetBindModalCallback(const std::function<void()>&& callback)
1220 {
1221     bindModalCallback_ = std::move(callback);
1222 }
1223 
FireBindModalCallback()1224 void UIExtensionPattern::FireBindModalCallback()
1225 {
1226     if (bindModalCallback_) {
1227         bindModalCallback_();
1228     }
1229 }
1230 
SetDensityDpi(bool densityDpi)1231 void UIExtensionPattern::SetDensityDpi(bool densityDpi)
1232 {
1233     densityDpi_ = densityDpi;
1234 }
1235 
DispatchFollowHostDensity(bool densityDpi)1236 void UIExtensionPattern::DispatchFollowHostDensity(bool densityDpi)
1237 {
1238     densityDpi_ = densityDpi;
1239     CHECK_NULL_VOID(sessionWrapper_);
1240     sessionWrapper_->SetDensityDpiImpl(densityDpi_);
1241 }
1242 
OnDpiConfigurationUpdate()1243 void UIExtensionPattern::OnDpiConfigurationUpdate()
1244 {
1245     if (GetDensityDpi()) {
1246         DispatchFollowHostDensity(true);
1247     }
1248 }
1249 
GetDensityDpi()1250 bool UIExtensionPattern::GetDensityDpi()
1251 {
1252     return densityDpi_;
1253 }
1254 
OnVisibleChange(bool visible)1255 void UIExtensionPattern::OnVisibleChange(bool visible)
1256 {
1257     UIEXT_LOGI("The component is changing from '%{public}s' to '%{public}s'.", isVisible_ ? "visible" : "invisible",
1258         visible ? "visible" : "invisible");
1259     isVisible_ = visible;
1260     if (visible) {
1261         NotifyForeground();
1262     } else {
1263         NotifyBackground();
1264     }
1265 }
1266 
InitializeAccessibility()1267 void UIExtensionPattern::InitializeAccessibility()
1268 {
1269     if (accessibilityChildTreeCallback_ != nullptr) {
1270         return;
1271     }
1272     auto instanceId = GetInstanceIdFromHost();
1273     ContainerScope scope(instanceId);
1274     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
1275     CHECK_NULL_VOID(ngPipeline);
1276     auto frontend = ngPipeline->GetFrontend();
1277     CHECK_NULL_VOID(frontend);
1278     auto accessibilityManager = frontend->GetAccessibilityManager();
1279     CHECK_NULL_VOID(accessibilityManager);
1280     auto frameNode = frameNode_.Upgrade();
1281     CHECK_NULL_VOID(frameNode);
1282     int64_t accessibilityId = frameNode->GetAccessibilityId();
1283     accessibilityChildTreeCallback_ = std::make_shared<UIExtensionAccessibilityChildTreeCallback>(
1284         WeakClaim(this), accessibilityId);
1285     CHECK_NULL_VOID(accessibilityChildTreeCallback_);
1286     auto realHostWindowId = ngPipeline->GetRealHostWindowId();
1287     realHostWindowId_ = realHostWindowId;
1288     focusWindowId_ = ngPipeline->GetFocusWindowId();
1289     if (accessibilityManager->IsRegister()) {
1290         accessibilityChildTreeCallback_->OnRegister(
1291             realHostWindowId, accessibilityManager->GetTreeId());
1292     }
1293     UIEXT_LOGI("UIExtension: %{public}" PRId64 " register child tree, realHostWindowId: %{public}u",
1294         accessibilityId, realHostWindowId);
1295     accessibilityManager->RegisterAccessibilityChildTreeCallback(accessibilityId, accessibilityChildTreeCallback_);
1296 }
1297 
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)1298 void UIExtensionPattern::OnAccessibilityChildTreeRegister(uint32_t windowId, int32_t treeId, int64_t accessibilityId)
1299 {
1300     UIEXT_LOGI("treeId: %{public}d, id: %{public}" PRId64, treeId, accessibilityId);
1301     if (sessionWrapper_ == nullptr) {
1302         UIEXT_LOGI("sessionWrapper_ is null");
1303         return;
1304     }
1305     sessionWrapper_->TransferAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
1306 }
1307 
OnAccessibilityChildTreeDeregister()1308 void UIExtensionPattern::OnAccessibilityChildTreeDeregister()
1309 {
1310     UIEXT_LOGI("deregister accessibility child tree");
1311     if (sessionWrapper_ == nullptr) {
1312         UIEXT_LOGI("sessionWrapper_ is null");
1313         return;
1314     }
1315     sessionWrapper_->TransferAccessibilityChildTreeDeregister();
1316 }
1317 
OnSetAccessibilityChildTree(int32_t childWindowId,int32_t childTreeId)1318 void UIExtensionPattern::OnSetAccessibilityChildTree(int32_t childWindowId, int32_t childTreeId)
1319 {
1320     auto frameNode = frameNode_.Upgrade();
1321     CHECK_NULL_VOID(frameNode);
1322     auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
1323     if (accessibilityProperty != nullptr) {
1324         accessibilityProperty->SetChildWindowId(childWindowId);
1325         accessibilityProperty->SetChildTreeId(childTreeId);
1326     }
1327 }
1328 
OnAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)1329 void UIExtensionPattern::OnAccessibilityDumpChildInfo(
1330     const std::vector<std::string>& params, std::vector<std::string>& info)
1331 {
1332     UIEXT_LOGI("dump accessibility child info");
1333     if (sessionWrapper_ == nullptr) {
1334         UIEXT_LOGI("sessionWrapper_ is null");
1335         return;
1336     }
1337     sessionWrapper_->TransferAccessibilityDumpChildInfo(params, info);
1338 }
1339 
ResetAccessibilityChildTreeCallback()1340 void UIExtensionPattern::ResetAccessibilityChildTreeCallback()
1341 {
1342     CHECK_NULL_VOID(accessibilityChildTreeCallback_);
1343     auto instanceId = GetInstanceIdFromHost();
1344     ContainerScope scope(instanceId);
1345     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
1346     CHECK_NULL_VOID(ngPipeline);
1347     auto frontend = ngPipeline->GetFrontend();
1348     CHECK_NULL_VOID(frontend);
1349     auto accessibilityManager = frontend->GetAccessibilityManager();
1350     CHECK_NULL_VOID(accessibilityManager);
1351     accessibilityManager->DeregisterAccessibilityChildTreeCallback(
1352         accessibilityChildTreeCallback_->GetAccessibilityId());
1353     accessibilityChildTreeCallback_.reset();
1354     accessibilityChildTreeCallback_ = nullptr;
1355 }
1356 
OnMountToParentDone()1357 void UIExtensionPattern::OnMountToParentDone()
1358 {
1359     UIEXT_LOGI("OnMountToParentDone.");
1360     hasMountToParent_ = true;
1361     if (needReNotifyForeground_) {
1362         auto hostWindowNode = WindowSceneHelper::FindWindowScene(GetHost());
1363         if (hostWindowNode) {
1364             needReNotifyForeground_ = false;
1365             UIEXT_LOGI("NotifyForeground OnMountToParentDone.");
1366             NotifyForeground();
1367         } else {
1368             UIEXT_LOGI("No WindowScene when OnMountToParentDone, wait.");
1369         }
1370     }
1371     auto frameNode = frameNode_.Upgrade();
1372     CHECK_NULL_VOID(frameNode);
1373     if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
1374         UIEXT_LOGD("Frame node status is normal.");
1375         return;
1376     }
1377     auto wantWrap = GetWantWrap();
1378     CHECK_NULL_VOID(wantWrap);
1379     UpdateWant(wantWrap);
1380     SetWantWrap(nullptr);
1381 }
1382 
AfterMountToParent()1383 void UIExtensionPattern::AfterMountToParent()
1384 {
1385     UIEXT_LOGI("AfterMountToParent.");
1386     hasMountToParent_ = true;
1387     if (needReNotifyForeground_) {
1388         auto hostWindowNode = WindowSceneHelper::FindWindowScene(GetHost());
1389         if (hostWindowNode) {
1390             needReNotifyForeground_ = false;
1391             UIEXT_LOGI("NotifyForeground AfterMountToParent.");
1392             NotifyForeground();
1393         } else {
1394             UIEXT_LOGI("No WindowScene when AfterMountToParent, wait.");
1395         }
1396     }
1397 }
1398 
RegisterVisibleAreaChange()1399 void UIExtensionPattern::RegisterVisibleAreaChange()
1400 {
1401     auto pipeline = PipelineContext::GetCurrentContext();
1402     CHECK_NULL_VOID(pipeline);
1403     auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
1404         auto uiExtension = weak.Upgrade();
1405         CHECK_NULL_VOID(uiExtension);
1406         uiExtension->HandleVisibleAreaChange(visible, ratio);
1407     };
1408     auto host = GetHost();
1409     CHECK_NULL_VOID(host);
1410     std::vector<double> ratioList = { SHOW_START, SHOW_FULL };
1411     pipeline->AddVisibleAreaChangeNode(host, ratioList, callback, false);
1412 }
1413 
HandleVisibleAreaChange(bool visible,double ratio)1414 void UIExtensionPattern::HandleVisibleAreaChange(bool visible, double ratio)
1415 {
1416     UIEXT_LOGI("HandleVisibleAreaChange visible: %{public}d, curVisible: %{public}d, "
1417         "ratio: %{public}f, displayArea: %{public}s.", visible, curVisible_,
1418         ratio, displayArea_.ToString().c_str());
1419     bool needCheckDisplayArea = NearEqual(ratio, SHOW_FULL) && curVisible_ && visible;
1420     bool curVisible = !NearEqual(ratio, SHOW_START);
1421     if (curVisible_ != curVisible) {
1422         curVisible_ = curVisible;
1423         OnVisibleChange(curVisible_);
1424     }
1425 
1426     if (needCheckDisplayArea) {
1427         DispatchDisplayArea(false);
1428     }
1429 }
1430 
OnLanguageConfigurationUpdate()1431 void UIExtensionPattern::OnLanguageConfigurationUpdate()
1432 {
1433     CHECK_NULL_VOID(sessionWrapper_);
1434     sessionWrapper_->NotifyConfigurationUpdate();
1435 }
1436 
OnColorConfigurationUpdate()1437 void UIExtensionPattern::OnColorConfigurationUpdate()
1438 {
1439     CHECK_NULL_VOID(sessionWrapper_);
1440     sessionWrapper_->NotifyConfigurationUpdate();
1441 }
1442 
GetSessionId()1443 int32_t UIExtensionPattern::GetSessionId()
1444 {
1445     return sessionWrapper_ ? sessionWrapper_->GetSessionId() : 0;
1446 }
1447 
GetUiExtensionId()1448 int32_t UIExtensionPattern::GetUiExtensionId()
1449 {
1450     return uiExtensionId_;
1451 }
1452 
GetNodeId()1453 int32_t UIExtensionPattern::GetNodeId()
1454 {
1455     auto host = GetHost();
1456     return host ? host->GetId() : -1;
1457 }
1458 
GetInstanceId()1459 int32_t UIExtensionPattern::GetInstanceId()
1460 {
1461     return instanceId_;
1462 }
1463 
GetInstanceIdFromHost()1464 int32_t UIExtensionPattern::GetInstanceIdFromHost()
1465 {
1466     auto instanceId = GetHostInstanceId();
1467     if (instanceId != instanceId_) {
1468         UIEXT_LOGW("UIExtension pattern instanceId %{public}d not equal frame node instanceId %{public}d",
1469             instanceId_, instanceId);
1470     }
1471     return instanceId;
1472 }
1473 
DispatchOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)1474 void UIExtensionPattern::DispatchOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
1475 {
1476     CHECK_NULL_VOID(sessionWrapper_);
1477     sessionWrapper_->NotifyOriginAvoidArea(avoidArea, type);
1478 }
1479 
SetWantWrap(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)1480 void UIExtensionPattern::SetWantWrap(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
1481 {
1482     curWant_ = wantWrap;
1483 }
1484 
GetWantWrap()1485 RefPtr<OHOS::Ace::WantWrap> UIExtensionPattern::GetWantWrap()
1486 {
1487     return curWant_;
1488 }
1489 
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)1490 int64_t UIExtensionPattern::WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
1491 {
1492     return uiExtensionId_ * extensionOffset + abilityId;
1493 }
1494 
ToString(AbilityState state)1495 const char* UIExtensionPattern::ToString(AbilityState state)
1496 {
1497     switch (state) {
1498         case AbilityState::FOREGROUND:
1499             return "FOREGROUND";
1500         case AbilityState::BACKGROUND:
1501             return "BACKGROUND";
1502         case AbilityState::DESTRUCTION:
1503             return "DESTRUCTION";
1504         case AbilityState::NONE:
1505         default:
1506             return "NONE";
1507     }
1508 }
1509 
DumpInfo()1510 void UIExtensionPattern::DumpInfo()
1511 {
1512     CHECK_NULL_VOID(sessionWrapper_);
1513     UIEXT_LOGI("Dump UIE Info In String Format");
1514     DumpLog::GetInstance().AddDesc(std::string("focusWindowId: ").append(std::to_string(focusWindowId_)));
1515     DumpLog::GetInstance().AddDesc(std::string("realHostWindowId: ").append(std::to_string(realHostWindowId_)));
1516     DumpLog::GetInstance().AddDesc(std::string("want: ").append(want_));
1517     DumpLog::GetInstance().AddDesc(std::string("displayArea: ").append(displayArea_.ToString()));
1518     DumpLog::GetInstance().AddDesc(std::string("reason: ").append(std::to_string(sessionWrapper_->GetReasonDump())));
1519     DumpLog::GetInstance().AddDesc(std::string("focusStatus: ").append(std::to_string(focusState_)));
1520     DumpLog::GetInstance().AddDesc(std::string("abilityState: ").append(ToString(state_)));
1521 
1522     auto container = Platform::AceContainer::GetContainer(instanceId_);
1523     CHECK_NULL_VOID(container);
1524     std::vector<std::string> params = container->GetUieParams();
1525     // Use -nouie to choose not dump extra uie info
1526     if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1527         UIEXT_LOGI("Not Support Dump Extra UIE Info");
1528     } else {
1529         if (!container->IsUIExtensionWindow()) {
1530             params.push_back(PID_FLAG);
1531         }
1532         params.push_back(std::to_string(getpid()));
1533         std::vector<std::string> dumpInfo;
1534         sessionWrapper_->NotifyUieDump(params, dumpInfo);
1535         for (std::string info : dumpInfo) {
1536             DumpLog::GetInstance().AddDesc(std::string("UI Extension info: ").append(info));
1537         }
1538     }
1539 }
1540 
DumpInfo(std::unique_ptr<JsonValue> & json)1541 void UIExtensionPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
1542 {
1543     CHECK_NULL_VOID(sessionWrapper_);
1544     UIEXT_LOGI("Dump UIE Info In Json Format");
1545     json->Put("focusWindowId: ", std::to_string(focusWindowId_).c_str());
1546     json->Put("realHostWindowId: ", std::to_string(realHostWindowId_).c_str());
1547     json->Put("want: ", want_.c_str());
1548     json->Put("displayArea: ", displayArea_.ToString().c_str());
1549     json->Put("reason: ", std::to_string(sessionWrapper_->GetReasonDump()).c_str());
1550     json->Put("focusStatus: ", std::to_string(focusState_).c_str());
1551     json->Put("abilityState: ", ToString(state_));
1552 
1553     auto container = Platform::AceContainer::GetContainer(instanceId_);
1554     CHECK_NULL_VOID(container);
1555     std::vector<std::string> params = container->GetUieParams();
1556     // Use -nouie to choose not dump extra uie info
1557     if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1558         UIEXT_LOGI("Not Support Dump Extra UIE Info");
1559     } else {
1560         if (!container->IsUIExtensionWindow()) {
1561             params.push_back(PID_FLAG);
1562         }
1563         params.push_back(std::to_string(getpid()));
1564         std::vector<std::string> dumpInfo;
1565         sessionWrapper_->NotifyUieDump(params, dumpInfo);
1566         for (std::string info : dumpInfo) {
1567             json->Put("UI Extension info: ", info.c_str());
1568         }
1569     }
1570 }
1571 
DumpOthers()1572 void UIExtensionPattern::DumpOthers()
1573 {
1574     CHECK_NULL_VOID(sessionWrapper_);
1575     auto container = Platform::AceContainer::GetContainer(instanceId_);
1576     CHECK_NULL_VOID(container);
1577     std::vector<std::string> params = container->GetUieParams();
1578     if (params.empty()) {
1579         return;
1580     }
1581     // Use -nouie to choose not dump extra uie info
1582     if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1583         UIEXT_LOGI("Not Support Dump Extra UIE Info");
1584     } else {
1585         if (params.back() == "-json") {
1586             params.insert(params.end() - 1, std::to_string(getpid()));
1587             if (!container->IsUIExtensionWindow()) {
1588                 params.insert(params.end() - 1, PID_FLAG);
1589             }
1590         } else {
1591             if (!container->IsUIExtensionWindow()) {
1592                 params.push_back(PID_FLAG);
1593             }
1594             params.push_back(std::to_string(getpid()));
1595         }
1596         std::vector<std::string> dumpInfo;
1597         sessionWrapper_->NotifyUieDump(params, dumpInfo);
1598         for (std::string info : dumpInfo) {
1599             std::stringstream ss(info);
1600             std::string line;
1601             DumpLog::GetInstance().Print("\n------ UIExtension Dump ------");
1602             while (getline(ss, line, ';')) {
1603                 DumpLog::GetInstance().Print(line);
1604             }
1605         }
1606     }
1607 }
1608 } // namespace OHOS::Ace::NG
1609