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