• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/ui_extension/ui_extension_component/ui_extension_pattern.h"
17 
18 #include <optional>
19 
20 #include "adapter/ohos/entrance/ace_container.h"
21 #include "adapter/ohos/entrance/ace_extra_input_data.h"
22 #include "adapter/ohos/entrance/mmi_event_convertor.h"
23 #include "adapter/ohos/osal/want_wrap_ohos.h"
24 #include "base/error/error_code.h"
25 #include "base/geometry/offset.h"
26 #include "base/log/dump_log.h"
27 #include "base/utils/utils.h"
28 #include "core/common/container.h"
29 #include "core/components_ng/event/event_hub.h"
30 #include "core/components_ng/pattern/pattern.h"
31 #include "core/components_ng/pattern/text_field/text_field_manager.h"
32 #include "core/components_ng/pattern/ui_extension/session_wrapper.h"
33 #include "core/components_ng/pattern/ui_extension/session_wrapper_factory.h"
34 #include "core/components_ng/pattern/ui_extension/ui_extension_component/modal_ui_extension_proxy_impl.h"
35 #include "core/components_ng/pattern/ui_extension/ui_extension_component/session_wrapper_impl.h"
36 #include "core/components_ng/pattern/ui_extension/ui_extension_component/ui_extension_proxy.h"
37 #include "core/components_ng/pattern/ui_extension/ui_extension_layout_algorithm.h"
38 #include "core/components_ng/pattern/ui_extension/ui_extension_surface_pattern.h"
39 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
40 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
41 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
42 #include "core/components_ng/render/adapter/rosen_render_context.h"
43 #include "core/components_ng/render/adapter/rosen_window.h"
44 #include "core/event/ace_events.h"
45 #ifdef SUPPORT_DIGITAL_CROWN
46 #include "core/event/crown_event.h"
47 #endif
48 #include "core/event/key_event.h"
49 #include "core/event/mouse_event.h"
50 #include "core/event/pointer_event.h"
51 #include "core/event/touch_event.h"
52 #include "core/pipeline/pipeline_context.h"
53 #include "core/pipeline_ng/pipeline_context.h"
54 #include "session/host/include/extension_session.h"
55 #include "session/host/include/session.h"
56 #include "ui/rs_surface_node.h"
57 
58 namespace OHOS::Ace::NG {
59 namespace {
60 constexpr char ABILITY_KEY_ASYNC[] = "ability.want.params.KeyAsync";
61 constexpr char ABILITY_KEY_IS_MODAL[] = "ability.want.params.IsModal";
62 constexpr char ATOMIC_SERVICE_PREFIX[] = "com.atomicservice.";
63 constexpr char PROHIBIT_NESTING_FAIL_NAME[] = "Prohibit_Nesting_SecurityUIExtensionComponent";
64 constexpr char PROHIBIT_NESTING_FAIL_MESSAGE[] =
65     "Prohibit nesting uIExtensionExtensionComponent in securityUIAbility";
66 constexpr char PID_FLAG[] = "pidflag";
67 constexpr char NO_EXTRA_UIE_DUMP[] = "-nouie";
68 constexpr double SHOW_START = 0.0;
69 constexpr double SHOW_FULL = 1.0;
70 constexpr uint32_t REMOVE_PLACEHOLDER_DELAY_TIME = 32;
71 constexpr uint32_t PLACEHOLDER_TIMEOUT = 6000;
72 
StartWith(const std::string & source,const std::string & prefix)73 bool StartWith(const std::string &source, const std::string &prefix)
74 {
75     if (source.empty() || prefix.empty()) {
76         return false;
77     }
78 
79     return source.find(prefix) == 0;
80 }
81 
82 class UIExtensionAccessibilityChildTreeCallback : public AccessibilityChildTreeCallback {
83 public:
UIExtensionAccessibilityChildTreeCallback(const WeakPtr<UIExtensionPattern> & weakPattern,int64_t accessibilityId)84     UIExtensionAccessibilityChildTreeCallback(const WeakPtr<UIExtensionPattern>& weakPattern, int64_t accessibilityId)
85         : AccessibilityChildTreeCallback(accessibilityId), weakPattern_(weakPattern)
86     {}
87 
88     ~UIExtensionAccessibilityChildTreeCallback() override = default;
89 
OnRegister(uint32_t windowId,int32_t treeId)90     bool OnRegister(uint32_t windowId, int32_t treeId) override
91     {
92         auto pattern = weakPattern_.Upgrade();
93         if (pattern == nullptr) {
94             return false;
95         }
96         if (isReg_) {
97             return true;
98         }
99         pattern->OnAccessibilityChildTreeRegister(windowId, treeId, GetAccessibilityId());
100         isReg_ = true;
101         return true;
102     }
103 
OnDeregister()104     bool OnDeregister() override
105     {
106         auto pattern = weakPattern_.Upgrade();
107         if (pattern == nullptr) {
108             return false;
109         }
110         if (!isReg_) {
111             return true;
112         }
113         pattern->OnAccessibilityChildTreeDeregister();
114         isReg_ = false;
115         return true;
116     }
117 
OnSetChildTree(int32_t childWindowId,int32_t childTreeId)118     bool OnSetChildTree(int32_t childWindowId, int32_t childTreeId) override
119     {
120         auto pattern = weakPattern_.Upgrade();
121         if (pattern == nullptr) {
122             return false;
123         }
124         pattern->OnSetAccessibilityChildTree(childWindowId, childTreeId);
125         return true;
126     }
127 
OnDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)128     bool OnDumpChildInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override
129     {
130         auto pattern = weakPattern_.Upgrade();
131         if (pattern == nullptr) {
132             return false;
133         }
134         pattern->OnAccessibilityDumpChildInfo(params, info);
135         return true;
136     }
137 
OnClearRegisterFlag()138     void OnClearRegisterFlag() override
139     {
140         auto pattern = weakPattern_.Upgrade();
141         if (pattern == nullptr) {
142             return;
143         }
144         isReg_ = false;
145     }
146 
147 private:
148     bool isReg_ = false;
149     WeakPtr<UIExtensionPattern> weakPattern_;
150 };
151 }
UIExtensionPattern(bool isTransferringCaller,bool isModal,bool isAsyncModalBinding,SessionType sessionType)152 UIExtensionPattern::UIExtensionPattern(
153     bool isTransferringCaller, bool isModal, bool isAsyncModalBinding, SessionType sessionType)
154     : isTransferringCaller_(isTransferringCaller), isModal_(isModal),
155     isAsyncModalBinding_(isAsyncModalBinding), sessionType_(sessionType)
156 {
157     uiExtensionId_ = UIExtensionIdUtility::GetInstance().ApplyExtensionId();
158     UIEXT_LOGI("The %{public}smodal UIExtension is created.", isModal_ ? "" : "non");
159 }
160 
~UIExtensionPattern()161 UIExtensionPattern::~UIExtensionPattern()
162 {
163     UIEXT_LOGI("The %{public}smodal UIExtension is destroyed.", isModal_ ? "" : "non");
164     if (isModal_) {
165         LogoutModalUIExtension();
166     }
167     NotifyDestroy();
168     FireModalOnDestroy();
169     UIExtensionIdUtility::GetInstance().RecycleExtensionId(uiExtensionId_);
170     auto pipeline = PipelineContext::GetCurrentContext();
171     CHECK_NULL_VOID(pipeline);
172     auto uiExtensionManager = pipeline->GetUIExtensionManager();
173     CHECK_NULL_VOID(uiExtensionManager);
174     uiExtensionManager->RemoveDestroyedUIExtension(GetNodeId());
175 
176     if (accessibilityChildTreeCallback_ == nullptr) {
177         return;
178     }
179 
180     auto instanceId = GetInstanceIdFromHost();
181     ContainerScope scope(instanceId);
182     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
183     CHECK_NULL_VOID(ngPipeline);
184     auto frontend = ngPipeline->GetFrontend();
185     CHECK_NULL_VOID(frontend);
186     auto accessibilityManager = frontend->GetAccessibilityManager();
187     CHECK_NULL_VOID(accessibilityManager);
188     accessibilityManager->DeregisterAccessibilityChildTreeCallback(
189         accessibilityChildTreeCallback_->GetAccessibilityId());
190     accessibilityChildTreeCallback_ = nullptr;
191 }
192 
LogoutModalUIExtension()193 void UIExtensionPattern::LogoutModalUIExtension()
194 {
195     auto sessionId = GetSessionId();
196     UIEXT_LOGI("LogoutModalUIExtension sessionId %{public}d.", sessionId);
197     auto pipeline = PipelineContext::GetCurrentContext();
198     CHECK_NULL_VOID(pipeline);
199     auto overlay = pipeline->GetOverlayManager();
200     CHECK_NULL_VOID(overlay);
201     overlay->ResetRootNode(-(sessionId));
202 }
203 
Initialize()204 void UIExtensionPattern::Initialize()
205 {
206     if (hasInitialize_) {
207         return;
208     }
209 
210     sessionWrapper_ = SessionWrapperFactory::CreateSessionWrapper(
211         sessionType_, AceType::WeakClaim(this), instanceId_, isTransferringCaller_);
212     accessibilitySessionAdapter_ =
213         AceType::MakeRefPtr<AccessibilitySessionAdapterUIExtension>(sessionWrapper_);
214     hasInitialize_ = true;
215 }
216 
CreateLayoutAlgorithm()217 RefPtr<LayoutAlgorithm> UIExtensionPattern::CreateLayoutAlgorithm()
218 {
219     return MakeRefPtr<UIExtensionLayoutAlgorithm>();
220 }
221 
GetFocusPattern() const222 FocusPattern UIExtensionPattern::GetFocusPattern() const
223 {
224     return { FocusType::NODE, true, FocusStyleType::FORCE_NONE };
225 }
226 
GetAccessibilitySessionAdapter()227 RefPtr<AccessibilitySessionAdapter> UIExtensionPattern::GetAccessibilitySessionAdapter()
228 {
229     return accessibilitySessionAdapter_;
230 }
231 
OnAttachToMainTree()232 void UIExtensionPattern::OnAttachToMainTree()
233 {
234     UIEXT_LOGI("OnAttachToMainTree, isMoving: %{public}d", IsMoving());
235 }
236 
OnDetachFromMainTree()237 void UIExtensionPattern::OnDetachFromMainTree()
238 {
239     UIEXT_LOGI("OnDetachFromMainTree, isMoving: %{public}d", IsMoving());
240 }
241 
OnAttachContext(PipelineContext * context)242 void UIExtensionPattern::OnAttachContext(PipelineContext *context)
243 {
244     CHECK_NULL_VOID(context);
245     auto newInstanceId = context->GetInstanceId();
246     bool isMoving = IsMoving();
247     UIEXT_LOGI("OnAttachContext newInstanceId: %{public}d, oldInstanceId: %{public}d,"
248         " isMoving: %{public}d.", newInstanceId, instanceId_, isMoving);
249     if (newInstanceId != instanceId_) {
250         UnRegisterEvent(instanceId_);
251         RegisterEvent(newInstanceId);
252         instanceId_ = newInstanceId;
253         UpdateSessionInstanceId(newInstanceId);
254     }
255 }
256 
UpdateSessionInstanceId(int32_t instanceId)257 void UIExtensionPattern::UpdateSessionInstanceId(int32_t instanceId)
258 {
259     auto sessionWrapperImpl = AceType::DynamicCast<SessionWrapperImpl>(sessionWrapper_);
260     if (!sessionWrapperImpl) {
261         UIEXT_LOGW("DynamicCast failed, sessionWrapperImpl is nullptr");
262         return;
263     }
264 
265     sessionWrapperImpl->UpdateInstanceId(instanceId);
266 }
267 
RegisterEvent(int32_t instanceId)268 void UIExtensionPattern::RegisterEvent(int32_t instanceId)
269 {
270     RegisterUIExtensionManagerEvent(instanceId);
271     RegisterPipelineEvent(instanceId);
272     hasDetachContext_ = false;
273 }
274 
RegisterPipelineEvent(int32_t instanceId)275 void UIExtensionPattern::RegisterPipelineEvent(int32_t instanceId)
276 {
277     ContainerScope scope(instanceId);
278     auto host = GetHost();
279     CHECK_NULL_VOID(host);
280     auto pipeline = PipelineContext::GetContextByContainerId(instanceId);
281     CHECK_NULL_VOID(pipeline);
282     RegisterPipelineEvent(pipeline);
283 }
284 
RegisterUIExtensionManagerEvent(int32_t instanceId)285 void UIExtensionPattern::RegisterUIExtensionManagerEvent(int32_t instanceId)
286 {
287     auto host = GetHost();
288     CHECK_NULL_VOID(host);
289     auto pipeline = PipelineContext::GetContextByContainerId(instanceId);
290     CHECK_NULL_VOID(pipeline);
291     auto uiExtensionManager = pipeline->GetUIExtensionManager();
292     CHECK_NULL_VOID(uiExtensionManager);
293     // 1. Add alive uec in uiExtensionManager
294     uiExtensionManager->AddAliveUIExtension(host->GetId(), WeakClaim(this));
295 
296     // 2. Add focus uec in uiExtensionManager
297     auto focusHub = host->GetFocusHub();
298     CHECK_NULL_VOID(focusHub);
299     bool isFocusd = focusHub && focusHub->IsCurrentFocus();
300     if (isFocusd) {
301         uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
302     }
303     UIEXT_LOGI("RegisterUIExtensionManagerEvent");
304 }
305 
OnDetachContext(PipelineContext * context)306 void UIExtensionPattern::OnDetachContext(PipelineContext *context)
307 {
308     CHECK_NULL_VOID(context);
309     auto instanceId = context->GetInstanceId();
310     if (instanceId != instanceId_) {
311         UIEXT_LOGW("InstanceId(%{public}d) is inconsistent with the exist Id(%{public}d),",
312             instanceId, instanceId_);
313         return;
314     }
315 
316     bool isMoving = IsMoving();
317     UIEXT_LOGI("OnDetachContext instanceId: %{public}d, isMoving: %{public}d,"
318         " isOnDetachContext: %{public}d.", instanceId, isMoving, hasDetachContext_);
319     if (!isMoving && !hasDetachContext_) {
320         UnRegisterEvent(instanceId);
321     }
322 }
323 
UnRegisterEvent(int32_t instanceId)324 void UIExtensionPattern::UnRegisterEvent(int32_t instanceId)
325 {
326     UnRegisterUIExtensionManagerEvent(instanceId);
327     UnRegisterPipelineEvent(instanceId);
328     hasDetachContext_ = true;
329 }
330 
UnRegisterPipelineEvent(int32_t instanceId)331 void UIExtensionPattern::UnRegisterPipelineEvent(int32_t instanceId)
332 {
333     auto host = GetHost();
334     CHECK_NULL_VOID(host);
335     auto pipeline = PipelineContext::GetContextByContainerId(instanceId);
336     CHECK_NULL_VOID(pipeline);
337     ContainerScope scope(instanceId);
338     UnRegisterPipelineEvent(pipeline, AceType::RawPtr(host));
339 }
340 
UnRegisterUIExtensionManagerEvent(int32_t instanceId)341 void UIExtensionPattern::UnRegisterUIExtensionManagerEvent(int32_t instanceId)
342 {
343     auto host = GetHost();
344     CHECK_NULL_VOID(host);
345     auto pipeline = PipelineContext::GetContextByContainerId(instanceId);
346     CHECK_NULL_VOID(pipeline);
347     auto uiExtensionManager = pipeline->GetUIExtensionManager();
348     CHECK_NULL_VOID(uiExtensionManager);
349     // 1. Delete alive uec in uiExtensionManager
350     uiExtensionManager->RemoveDestroyedUIExtension(GetNodeId());
351 
352     // 2. Delete focus uec in uiExtensionManager
353     auto focusHub = host->GetFocusHub();
354     CHECK_NULL_VOID(focusHub);
355     bool isFocusd = focusHub && focusHub->IsCurrentFocus();
356     if (isFocusd) {
357         uiExtensionManager->RegisterUIExtensionInFocus(nullptr, nullptr);
358     }
359     UIEXT_LOGI("UnRegisterUIExtensionManagerEvent");
360 }
361 
IsMoving()362 bool UIExtensionPattern::IsMoving()
363 {
364     auto host = GetHost();
365     CHECK_NULL_RETURN(host, false);
366     return host->IsMoving();
367 }
368 
UpdateWant(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)369 void UIExtensionPattern::UpdateWant(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
370 {
371     if (!wantWrap) {
372         UIEXT_LOGW("wantWrap is nullptr");
373         return;
374     }
375     auto wantWrapOhos = AceType::DynamicCast<WantWrapOhos>(wantWrap);
376     if (!wantWrapOhos) {
377         UIEXT_LOGW("DynamicCast failed, wantWrapOhos is nullptr");
378         return;
379     }
380     auto want = wantWrapOhos->GetWant();
381     want_ = want.GetElement().GetBundleName().append(want.GetElement().GetAbilityName().c_str());
382     UpdateWant(want);
383 }
384 
MountPlaceholderNode(PlaceholderType type)385 void UIExtensionPattern::MountPlaceholderNode(PlaceholderType type)
386 {
387     if (!IsCanMountPlaceholder(type)) {
388         return;
389     }
390     RefPtr<NG::FrameNode> placeholderNode = nullptr;
391     auto it = placeholderMap_.find(type);
392     if (it != placeholderMap_.end()) {
393         placeholderNode = it->second;
394     }
395     CHECK_NULL_VOID(placeholderNode);
396     auto host = GetHost();
397     CHECK_NULL_VOID(host);
398     host->RemoveChildAtIndex(0);
399     host->AddChild(placeholderNode, 0);
400     ACE_SCOPED_TRACE("MountPlaceholderNode type[%d]", static_cast<int32_t>(type));
401     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
402     SetCurPlaceholderType(type);
403     PostDelayRemovePlaceholder(PLACEHOLDER_TIMEOUT);
404 }
405 
RemovePlaceholderNode()406 void UIExtensionPattern::RemovePlaceholderNode()
407 {
408     if (!IsShowPlaceholder()) {
409         return;
410     }
411     auto host = GetHost();
412     CHECK_NULL_VOID(host);
413     host->RemoveChildAtIndex(0);
414     ACE_SCOPED_TRACE("RemovePlaceholderNode type[%d]", static_cast<int32_t>(curPlaceholderType_));
415     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
416     SetCurPlaceholderType(PlaceholderType::NONE);
417 }
418 
CheckConstraint()419 bool UIExtensionPattern::CheckConstraint()
420 {
421     auto container = Platform::AceContainer::GetContainer(instanceId_);
422     CHECK_NULL_RETURN(container, false);
423     if (container->GetUIContentType() == UIContentType::SECURITY_UI_EXTENSION) {
424         UIEXT_LOGE("Not allowed nesting in SECURITY_UI_EXTENSION.");
425         FireOnErrorCallback(ERROR_CODE_UIEXTENSION_FORBID_CASCADE,
426             PROHIBIT_NESTING_FAIL_NAME, PROHIBIT_NESTING_FAIL_MESSAGE);
427         return false;
428     }
429 
430     return true;
431 }
432 
UpdateWant(const AAFwk::Want & want)433 void UIExtensionPattern::UpdateWant(const AAFwk::Want& want)
434 {
435     if (!CheckConstraint()) {
436         UIEXT_LOGE("Check constraint failed.");
437         return;
438     }
439 
440     CHECK_NULL_VOID(sessionWrapper_);
441     UIEXT_LOGI("The current state is '%{public}s' when UpdateWant.", ToString(state_));
442     bool isBackground = state_ == AbilityState::BACKGROUND;
443     // Prohibit rebuilding the session unless the Want is updated.
444     if (sessionWrapper_->IsSessionValid()) {
445         auto sessionWant = sessionWrapper_->GetWant();
446         if (sessionWant == nullptr) {
447             UIEXT_LOGW("The sessionWrapper want is nulllptr.");
448             return;
449         }
450         if (sessionWant->IsEquals(want)) {
451             return;
452         }
453         UIEXT_LOGI("The old want bundle = %{public}s, ability = %{public}s",
454             sessionWant->GetElement().GetBundleName().c_str(), sessionWant->GetElement().GetAbilityName().c_str());
455         auto host = GetHost();
456         CHECK_NULL_VOID(host);
457         host->RemoveChildAtIndex(0);
458         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
459         SetCurPlaceholderType(PlaceholderType::NONE);
460         NotifyDestroy();
461         // reset callback, in order to register childtree call back again when onConnect to new ability
462         ResetAccessibilityChildTreeCallback();
463     }
464 
465     isKeyAsync_ = want.GetBoolParam(ABILITY_KEY_ASYNC, false);
466     UIExtensionUsage uIExtensionUsage = GetUIExtensionUsage(want);
467     usage_ = uIExtensionUsage;
468     UIEXT_LOGI("The ability KeyAsync %{public}d, uIExtensionUsage: %{public}u.",
469         isKeyAsync_, uIExtensionUsage);
470     MountPlaceholderNode(PlaceholderType::INITIAL);
471     SessionConfig config;
472     config.isAsyncModalBinding = isAsyncModalBinding_;
473     config.uiExtensionUsage = uIExtensionUsage;
474     sessionWrapper_->CreateSession(want, config);
475     if (isBackground) {
476         UIEXT_LOGW("Unable to StartUiextensionAbility while in the background.");
477         return;
478     }
479     auto container = Platform::AceContainer::GetContainer(instanceId_);
480     CHECK_NULL_VOID(container);
481     if (container->IsScenceBoardWindow() && !isModal_ && !hasMountToParent_) {
482         needReNotifyForeground_ = true;
483         UIEXT_LOGI("Should NotifyForeground after MountToParent.");
484         return;
485     }
486     NotifyForeground();
487 }
488 
IsModalUec()489 bool UIExtensionPattern::IsModalUec()
490 {
491     return usage_ == UIExtensionUsage::MODAL;
492 }
493 
IsForeground()494 bool UIExtensionPattern::IsForeground()
495 {
496     return state_ == AbilityState::FOREGROUND;
497 }
498 
GetUIExtensionUsage(const AAFwk::Want & want)499 UIExtensionUsage UIExtensionPattern::GetUIExtensionUsage(const AAFwk::Want& want)
500 {
501     if (sessionType_ == SessionType::EMBEDDED_UI_EXTENSION) {
502         return UIExtensionUsage::EMBEDDED;
503     }
504 
505     if (isModal_) {
506         return UIExtensionUsage::MODAL;
507     }
508 
509     bool wantParamModal = want.GetBoolParam(ABILITY_KEY_IS_MODAL, false);
510     auto bundleName = want.GetElement().GetBundleName();
511     bool startWithAtomicService = StartWith(bundleName, ATOMIC_SERVICE_PREFIX);
512     if (wantParamModal && startWithAtomicService) {
513         return UIExtensionUsage::MODAL;
514     }
515 
516     return UIExtensionUsage::EMBEDDED;
517 }
518 
OnConnect()519 void UIExtensionPattern::OnConnect()
520 {
521     CHECK_RUN_ON(UI);
522     CHECK_NULL_VOID(sessionWrapper_);
523     UIEXT_LOGI("The session is connected and the current state is '%{public}s'.", ToString(state_));
524     ContainerScope scope(instanceId_);
525     contentNode_ = FrameNode::CreateFrameNode(V2::UI_EXTENSION_SURFACE_TAG,
526         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<UIExtensionSurfacePattern>());
527     contentNode_->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
528     contentNode_->SetHitTestMode(HitTestMode::HTMNONE);
529     auto host = GetHost();
530     CHECK_NULL_VOID(host);
531     auto&& opts = host->GetLayoutProperty()->GetSafeAreaExpandOpts();
532     if (opts && opts->Expansive()) {
533         contentNode_->GetLayoutProperty()->UpdateSafeAreaExpandOpts(*opts);
534         contentNode_->MarkModifyDone();
535     }
536     auto context = AceType::DynamicCast<NG::RosenRenderContext>(contentNode_->GetRenderContext());
537     CHECK_NULL_VOID(context);
538     auto surfaceNode = sessionWrapper_->GetSurfaceNode();
539     if (!surfaceNode) {
540         UIEXT_LOGE("Get surfaceNode from session is null.");
541         return;
542     }
543     context->SetRSNode(surfaceNode);
544     if (curPlaceholderType_ != PlaceholderType::INITIAL) {
545         host->AddChild(contentNode_, 0);
546         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
547     }
548     surfaceNode->CreateNodeInRenderThread();
549     surfaceNode->SetForeground(usage_ == UIExtensionUsage::MODAL);
550     FireOnRemoteReadyCallback();
551     auto focusHub = host->GetFocusHub();
552     if ((usage_ == UIExtensionUsage::MODAL) && focusHub) {
553         focusHub->RequestFocusImmediately();
554     }
555     bool isFocused = focusHub && focusHub->IsCurrentFocus();
556     RegisterVisibleAreaChange();
557     DispatchFocusState(isFocused);
558     sessionWrapper_->UpdateSessionViewportConfig();
559     auto pipeline = host->GetContextRefPtr();
560     CHECK_NULL_VOID(pipeline);
561     auto uiExtensionManager = pipeline->GetUIExtensionManager();
562     uiExtensionManager->AddAliveUIExtension(host->GetId(), WeakClaim(this));
563     if (isFocused || (usage_ == UIExtensionUsage::MODAL)) {
564         uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
565     }
566     InitializeAccessibility();
567     ReDispatchDisplayArea();
568     InitBusinessDataHandleCallback();
569     RegisterReplyPageModeCallback();
570     NotifyHostWindowMode();
571 }
572 
InitBusinessDataHandleCallback()573 void UIExtensionPattern::InitBusinessDataHandleCallback()
574 {
575     RegisterEventProxyFlagCallback();
576     RegisterGetAvoidInfoCallback();
577 }
578 
ReplacePlaceholderByContent()579 void UIExtensionPattern::ReplacePlaceholderByContent()
580 {
581     CHECK_RUN_ON(UI);
582     if (!IsShowPlaceholder()) {
583         return;
584     }
585     RemovePlaceholderNode();
586     auto host = GetHost();
587     CHECK_NULL_VOID(host);
588     host->AddChild(contentNode_, 0);
589     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
590 }
591 
OnAreaUpdated()592 void UIExtensionPattern::OnAreaUpdated()
593 {
594     PostDelayRemovePlaceholder(REMOVE_PLACEHOLDER_DELAY_TIME);
595 }
596 
RegisterWindowSceneVisibleChangeCallback(const RefPtr<Pattern> & windowScenePattern)597 void UIExtensionPattern::RegisterWindowSceneVisibleChangeCallback(
598     const RefPtr<Pattern>& windowScenePattern)
599 {
600     auto systemWindowScene = AceType::DynamicCast<SystemWindowScene>(windowScenePattern);
601     CHECK_NULL_VOID(systemWindowScene);
602     auto host = GetHost();
603     CHECK_NULL_VOID(host);
604     auto callback = [weak = WeakClaim(this)](bool visible) {
605         auto pattern = weak.Upgrade();
606         if (pattern) {
607             pattern->OnWindowSceneVisibleChange(visible);
608         }
609     };
610     systemWindowScene->RegisterVisibleChangeCallback(host->GetId(), callback);
611     weakSystemWindowScene_ = systemWindowScene;
612     UIEXT_LOGI("RegisterWindowSceneVisibleChangeCallback %{public}d.", host->GetId());
613 }
614 
UnRegisterWindowSceneVisibleChangeCallback(int32_t nodeId)615 void UIExtensionPattern::UnRegisterWindowSceneVisibleChangeCallback(int32_t nodeId)
616 {
617     auto pattern = weakSystemWindowScene_.Upgrade();
618     CHECK_NULL_VOID(pattern);
619     auto systemWindowScene = AceType::DynamicCast<SystemWindowScene>(pattern);
620     CHECK_NULL_VOID(systemWindowScene);
621     systemWindowScene->UnRegisterVisibleChangeCallback(nodeId);
622     UIEXT_LOGI("UnRegisterWindowSceneVisibleChangeCallback %{public}d.", nodeId);
623 }
624 
OnWindowSceneVisibleChange(bool visible)625 void UIExtensionPattern::OnWindowSceneVisibleChange(bool visible)
626 {
627     UIEXT_LOGI("OnWindowSceneVisibleChange %{public}d.", visible);
628     if (!visible) {
629         OnWindowHide();
630     }
631 }
632 
PostDelayRemovePlaceholder(uint32_t delay)633 void UIExtensionPattern::PostDelayRemovePlaceholder(uint32_t delay)
634 {
635     ContainerScope scope(instanceId_);
636     auto taskExecutor = Container::CurrentTaskExecutor();
637     CHECK_NULL_VOID(taskExecutor);
638     taskExecutor->PostDelayedTask(
639         [weak = WeakClaim(this)]() {
640             auto pattern = weak.Upgrade();
641             CHECK_NULL_VOID(pattern);
642             pattern->ReplacePlaceholderByContent();
643         },
644         TaskExecutor::TaskType::UI, delay, "ArkUIUIExtensionRemovePlaceholder");
645 }
646 
OnExtensionEvent(UIExtCallbackEventId eventId)647 void UIExtensionPattern::OnExtensionEvent(UIExtCallbackEventId eventId)
648 {
649     CHECK_RUN_ON(UI);
650     ContainerScope scope(instanceId_);
651     switch (eventId) {
652         case UIExtCallbackEventId::ON_AREA_CHANGED:
653             OnAreaUpdated();
654             break;
655         case UIExtCallbackEventId::ON_UEA_ACCESSIBILITY_READY:
656             OnUeaAccessibilityEventAsync();
657             break;
658         case UIExtCallbackEventId::ON_DRAW_FIRST:
659             FireOnDrawReadyCallback();
660             break;
661     }
662 }
663 
UpdateFrameNodeState()664 void UIExtensionPattern::UpdateFrameNodeState()
665 {
666     auto frameNode = frameNode_.Upgrade();
667     CHECK_NULL_VOID(frameNode);
668     auto pipeline = frameNode->GetContextRefPtr();
669     CHECK_NULL_VOID(pipeline);
670     auto frontend = pipeline->GetFrontend();
671     CHECK_NULL_VOID(frontend);
672     auto accessibilityManager = frontend->GetAccessibilityManager();
673     CHECK_NULL_VOID(accessibilityManager);
674     accessibilityManager->UpdateFrameNodeState(frameNode->GetId());
675 }
676 
OnUeaAccessibilityEventAsync()677 void UIExtensionPattern::OnUeaAccessibilityEventAsync()
678 {
679     auto frameNode = frameNode_.Upgrade();
680     CHECK_NULL_VOID(frameNode);
681     auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
682     CHECK_NULL_VOID(accessibilityProperty);
683     UpdateFrameNodeState();
684     TransferAccessibilityRectInfo(true); // first connect need info UEC rect info
685     if ((accessibilityChildTreeCallback_ != nullptr) && (accessibilityProperty->GetChildTreeId() != -1)) {
686         UIEXT_LOGI("uec need notify register accessibility again %{public}d, %{public}d.",
687             accessibilityProperty->GetChildWindowId(), accessibilityProperty->GetChildTreeId());
688         ResetAccessibilityChildTreeCallback();
689         InitializeAccessibility();
690     }
691 }
692 
GetSizeChangeReason()693 PlaceholderType UIExtensionPattern::GetSizeChangeReason()
694 {
695     CHECK_NULL_RETURN(sessionWrapper_, PlaceholderType::NONE);
696     if (IsFoldStatusChanged()) {
697         SetFoldStatusChanged(false);
698         return PlaceholderType::FOLD_TO_EXPAND;
699     }
700     if (IsRotateStatusChanged()) {
701         SetRotateStatusChanged(false);
702         return PlaceholderType::ROTATION;
703     }
704     return PlaceholderType::UNDEFINED;
705 }
706 
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)707 void UIExtensionPattern::OnAccessibilityEvent(
708     const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset)
709 {
710     UIEXT_LOGI("The accessibility event is reported and the current state is '%{public}s'.", ToString(state_));
711     ContainerScope scope(instanceId_);
712     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
713     CHECK_NULL_VOID(ngPipeline);
714     uiExtensionOffset = uiExtensionId_ * NG::UI_EXTENSION_OFFSET_MAX + uiExtensionOffset;
715     auto frontend = ngPipeline->GetFrontend();
716     CHECK_NULL_VOID(frontend);
717     auto accessibilityManager = frontend->GetAccessibilityManager();
718     CHECK_NULL_VOID(accessibilityManager);
719     accessibilityManager->SendExtensionAccessibilityEvent(info, uiExtensionOffset);
720 }
721 
OnDisconnect(bool isAbnormal)722 void UIExtensionPattern::OnDisconnect(bool isAbnormal)
723 {
724     CHECK_RUN_ON(UI);
725     UIEXT_LOGI("The session is disconnected and the current state is '%{public}s'.", ToString(state_));
726     auto host = GetHost();
727     CHECK_NULL_VOID(host);
728     host->RemoveChildAtIndex(0);
729     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
730     SetCurPlaceholderType(PlaceholderType::NONE);
731 }
732 
OnSyncGeometryNode(const DirtySwapConfig & config)733 void UIExtensionPattern::OnSyncGeometryNode(const DirtySwapConfig& config)
734 {
735     if (needReNotifyForeground_) {
736         needReNotifyForeground_ = false;
737         UIEXT_LOGI("NotifyForeground onSyncGeometryNode first.");
738         NotifyForeground();
739         needReDispatchDisplayArea_ = true;
740     }
741     DispatchDisplayArea(true);
742 }
743 
ReDispatchDisplayArea()744 void UIExtensionPattern::ReDispatchDisplayArea()
745 {
746     if (needReDispatchDisplayArea_) {
747         UIEXT_LOGI("ReDispatchDisplayArea.");
748         DispatchDisplayArea(true);
749         needReDispatchDisplayArea_ = false;
750     }
751 }
752 
OnWindowShow()753 void UIExtensionPattern::OnWindowShow()
754 {
755     UIEXT_LOGI("The window is being shown and the component is %{public}s.", isVisible_ ? "visible" : "invisible");
756     if (isVisible_) {
757         NotifyForeground();
758     }
759 }
760 
OnWindowHide()761 void UIExtensionPattern::OnWindowHide()
762 {
763     UIEXT_LOGI("The window is being hidden and the component is %{public}s, state is '%{public}s.",
764         isVisible_ ? "visible" : "invisible", ToString(state_));
765     if (isVisible_) {
766         NotifyBackground();
767     } else if (state_ == AbilityState::FOREGROUND) {
768         NotifyBackground(false);
769     }
770 }
771 
OnWindowSizeChanged(int32_t,int32_t,WindowSizeChangeReason type)772 void UIExtensionPattern::OnWindowSizeChanged(int32_t  /*width*/, int32_t  /*height*/, WindowSizeChangeReason type)
773 {
774     if (WindowSizeChangeReason::ROTATION == type) {
775         SetRotateStatusChanged(true);
776     }
777 }
778 
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)779 void UIExtensionPattern::NotifySizeChangeReason(
780     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
781 {
782     CHECK_NULL_VOID(sessionWrapper_);
783     sessionWrapper_->NotifySizeChangeReason(type, rsTransaction);
784 }
785 
OnExtensionDetachToDisplay()786 void UIExtensionPattern::OnExtensionDetachToDisplay()
787 {
788     if (contentNode_ == nullptr) {
789         UIEXT_LOGW("ContentNode is null when OnExtensionDetachToDisplay.");
790         return;
791     }
792 
793     UIEXT_LOGI("OnExtensionDetachToDisplay");
794     auto host = GetHost();
795     CHECK_NULL_VOID(host);
796     host->RemoveChild(contentNode_);
797     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
798 }
799 
NotifyForeground()800 void UIExtensionPattern::NotifyForeground()
801 {
802     if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::FOREGROUND) {
803         UIEXT_LOGI("The state is changing from '%{public}s' to 'FOREGROUND'.", ToString(state_));
804         state_ = AbilityState::FOREGROUND;
805         sessionWrapper_->NotifyForeground();
806         if (displayAreaChanged_) {
807             sessionWrapper_->NotifyDisplayArea(displayArea_);
808             displayAreaChanged_ = false;
809         }
810     }
811 }
812 
NotifyBackground(bool isHandleError)813 void UIExtensionPattern::NotifyBackground(bool isHandleError)
814 {
815     if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ == AbilityState::FOREGROUND) {
816         UIEXT_LOGI("The state is changing from '%{public}s' to 'BACKGROUND'.", ToString(state_));
817         state_ = AbilityState::BACKGROUND;
818         sessionWrapper_->NotifyBackground(isHandleError);
819     }
820 }
821 
NotifyDestroy()822 void UIExtensionPattern::NotifyDestroy()
823 {
824     if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::DESTRUCTION &&
825         state_ != AbilityState::NONE) {
826         UIEXT_LOGI("The state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
827         state_ = AbilityState::DESTRUCTION;
828         sessionWrapper_->NotifyDestroy();
829         sessionWrapper_->DestroySession();
830     }
831 }
832 
833 class UECAccessibilitySAObserverCallback : public AccessibilitySAObserverCallback {
834 public:
UECAccessibilitySAObserverCallback(const WeakPtr<UIExtensionPattern> & weakPattern,int64_t accessibilityId)835     UECAccessibilitySAObserverCallback(
836         const WeakPtr<UIExtensionPattern>& weakPattern, int64_t accessibilityId)
837         : AccessibilitySAObserverCallback(accessibilityId), weakUECPattern_(weakPattern)
838     {}
839 
840     ~UECAccessibilitySAObserverCallback() override = default;
841 
OnState(bool state)842     bool OnState(bool state) override
843     {
844         auto pattern = weakUECPattern_.Upgrade();
845         CHECK_NULL_RETURN(pattern, false);
846         if (state) {
847             // first time turn on Accessibility, add TransferAccessibilityRectInfo
848             pattern->TransferAccessibilityRectInfo(true);
849         }
850         return true;
851     }
852 private:
853     WeakPtr<UIExtensionPattern> weakUECPattern_;
854 };
855 
OnAttachToFrameNode()856 void UIExtensionPattern::OnAttachToFrameNode()
857 {
858     ContainerScope scope(instanceId_);
859     Initialize();
860     auto host = GetHost();
861     CHECK_NULL_VOID(host);
862     auto pipeline = host->GetContextRefPtr();
863     CHECK_NULL_VOID(pipeline);
864     RegisterPipelineEvent(pipeline);
865     UIEXT_LOGI("OnAttachToFrameNode");
866 }
867 
RegisterPipelineEvent(const RefPtr<PipelineContext> & pipeline)868 void UIExtensionPattern::RegisterPipelineEvent(
869     const RefPtr<PipelineContext>& pipeline)
870 {
871     CHECK_NULL_VOID(pipeline);
872     auto host = GetHost();
873     CHECK_NULL_VOID(host);
874     auto eventHub = host->GetEventHub<EventHub>();
875     CHECK_NULL_VOID(eventHub);
876     OnAreaChangedFunc onAreaChangedFunc = [weak = WeakClaim(this)](
877         const RectF& oldRect,
878         const OffsetF& oldOrigin,
879         const RectF& rect,
880         const OffsetF& origin) {
881             auto pattern = weak.Upgrade();
882             CHECK_NULL_VOID(pattern);
883             pattern->DispatchDisplayArea();
884     };
885     eventHub->AddInnerOnAreaChangedCallback(host->GetId(), std::move(onAreaChangedFunc));
886     pipeline->AddOnAreaChangeNode(host->GetId());
887     pipeline->AddWindowSizeChangeCallback(host->GetId());
888     surfacePositionCallBackId_ =
889         pipeline->RegisterSurfacePositionChangedCallback([weak = WeakClaim(this)](int32_t, int32_t) {
890         auto pattern = weak.Upgrade();
891         CHECK_NULL_VOID(pattern);
892         pattern->TransferAccessibilityRectInfo();
893         pattern->DispatchDisplayArea(true);
894     });
895     foldDisplayCallBackId_ =
896         pipeline->RegisterFoldDisplayModeChangedCallback([weak = WeakClaim(this)](FoldDisplayMode foldDisplayMode) {
897         auto pattern = weak.Upgrade();
898         CHECK_NULL_VOID(pattern);
899         pattern->SetFoldStatusChanged(true);
900     });
901     auto frontend = pipeline->GetFrontend();
902     CHECK_NULL_VOID(frontend);
903     auto accessibilityManager = frontend->GetAccessibilityManager();
904     CHECK_NULL_VOID(accessibilityManager);
905     accessibilityManager->AddFrameNodeToUecStatusVec(host);
906     host->RegisterNodeChangeListener();
907     accessibilitySAObserverCallback_ = std::make_shared<UECAccessibilitySAObserverCallback>(
908         WeakClaim(this), host->GetAccessibilityId());
909 #ifndef ACE_UNITTEST
910     accessibilityManager->RegisterAccessibilitySAObserverCallback(host->GetAccessibilityId(),
911         accessibilitySAObserverCallback_);
912 #endif
913     UIEXT_LOGI("RegisterPipelineEvent");
914 }
915 
OnDetachFromFrameNode(FrameNode * frameNode)916 void UIExtensionPattern::OnDetachFromFrameNode(FrameNode* frameNode)
917 {
918     auto id = frameNode->GetId();
919     UnRegisterWindowSceneVisibleChangeCallback(id);
920     ContainerScope scope(instanceId_);
921     auto pipeline = frameNode->GetContextRefPtr();
922     CHECK_NULL_VOID(pipeline);
923     UnRegisterPipelineEvent(pipeline, frameNode);
924 }
925 
UnRegisterPipelineEvent(const RefPtr<PipelineContext> & pipeline,FrameNode * frameNode)926 void UIExtensionPattern::UnRegisterPipelineEvent(
927     const RefPtr<PipelineContext>& pipeline, FrameNode* frameNode)
928 {
929     CHECK_NULL_VOID(pipeline);
930     CHECK_NULL_VOID(frameNode);
931     auto id = frameNode->GetId();
932     pipeline->RemoveOnAreaChangeNode(id);
933     pipeline->RemoveWindowSizeChangeCallback(id);
934     pipeline->RemoveWindowStateChangedCallback(id);
935     pipeline->UnregisterSurfacePositionChangedCallback(surfacePositionCallBackId_);
936     pipeline->UnRegisterFoldDisplayModeChangedCallback(foldDisplayCallBackId_);
937     frameNode->UnregisterNodeChangeListener();
938 #ifndef ACE_UNITTEST
939     auto accessibilityManager = pipeline->GetAccessibilityManager();
940     CHECK_NULL_VOID(accessibilityManager);
941     accessibilityManager->DeregisterAccessibilitySAObserverCallback(frameNode->GetAccessibilityId());
942 #endif
943     UIEXT_LOGI("UnRegisterPipelineEvent");
944 }
945 
OnModifyDone()946 void UIExtensionPattern::OnModifyDone()
947 {
948     Pattern::OnModifyDone();
949     auto host = GetHost();
950     CHECK_NULL_VOID(host);
951     auto hub = host->GetEventHub<EventHub>();
952     CHECK_NULL_VOID(hub);
953     auto gestureHub = hub->GetOrCreateGestureEventHub();
954     CHECK_NULL_VOID(gestureHub);
955     InitTouchEvent(gestureHub);
956     auto inputHub = hub->GetOrCreateInputEventHub();
957     CHECK_NULL_VOID(inputHub);
958     InitMouseEvent(inputHub);
959     InitHoverEvent(inputHub);
960     auto focusHub = host->GetFocusHub();
961     CHECK_NULL_VOID(focusHub);
962     InitKeyEvent(focusHub);
963 #ifdef SUPPORT_DIGITAL_CROWN
964     InitCrownEvent(focusHub);
965 #endif
966 }
967 
InitKeyEventOnFocus(const RefPtr<FocusHub> & focusHub)968 void UIExtensionPattern::InitKeyEventOnFocus(const RefPtr<FocusHub>& focusHub)
969 {
970     focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
971         auto pattern = weak.Upgrade();
972         if (pattern) {
973             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Focus Internal.");
974             pattern->HandleFocusEvent();
975         }
976     });
977 }
978 
InitKeyEventOnBlur(const RefPtr<FocusHub> & focusHub)979 void UIExtensionPattern::InitKeyEventOnBlur(const RefPtr<FocusHub>& focusHub)
980 {
981     focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
982         auto pattern = weak.Upgrade();
983         if (pattern) {
984             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Blur Internal.");
985             pattern->HandleBlurEvent();
986         }
987     });
988 }
989 
InitKeyEventOnClearFocusState(const RefPtr<FocusHub> & focusHub)990 void UIExtensionPattern::InitKeyEventOnClearFocusState(const RefPtr<FocusHub>& focusHub)
991 {
992     focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
993         auto pattern = weak.Upgrade();
994         if (pattern) {
995             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Clear FocusState Internal.");
996             pattern->DispatchFocusActiveEvent(false);
997         }
998     });
999 }
1000 
InitKeyEventOnPaintFocusState(const RefPtr<FocusHub> & focusHub)1001 void UIExtensionPattern::InitKeyEventOnPaintFocusState(const RefPtr<FocusHub>& focusHub)
1002 {
1003     focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
1004         auto pattern = weak.Upgrade();
1005         if (pattern) {
1006             bool forceProcessKeyEvent = pattern->GetForceProcessOnKeyEventInternal();
1007             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1008                 "Paint FocusState Internal will %{public}s Active UIExtension.", forceProcessKeyEvent ? "not" : "");
1009             if (forceProcessKeyEvent) {
1010                 return true;
1011             }
1012             pattern->DispatchFocusActiveEvent(true);
1013             return true;
1014         }
1015         return false;
1016     });
1017 }
1018 
InitKeyEventOnKeyEvent(const RefPtr<FocusHub> & focusHub)1019 void UIExtensionPattern::InitKeyEventOnKeyEvent(const RefPtr<FocusHub>& focusHub)
1020 {
1021     focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
1022         auto pattern = wp.Upgrade();
1023         if (pattern) {
1024             if (event.IsPreIme()) {
1025                 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1026                     "KeyEvent Internal preIme %{public}s.", event.ToString().c_str());
1027                 return pattern->HandleKeyEvent(event);
1028             }
1029             auto host = pattern->GetHost();
1030             CHECK_NULL_RETURN(host, false);
1031             auto pipeline = host->GetContextRefPtr();
1032             CHECK_NULL_RETURN(pipeline, false);
1033             bool isBypassInner =
1034                 event.IsKey({ KeyCode::KEY_TAB }) && pipeline && pipeline->IsTabJustTriggerOnKeyEvent();
1035             bool forceProcessKeyEvent = pattern->GetForceProcessOnKeyEventInternal();
1036             bool sendKey = !isBypassInner || forceProcessKeyEvent;
1037             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1038                 "KeyEvent Internal will %{public}s send %{public}s, bypass[%{public}d], isForce[%{public}d].",
1039                 sendKey ? "" : "not", event.ToString().c_str(), isBypassInner, forceProcessKeyEvent);
1040             if (sendKey) {
1041                 pattern->SetForceProcessOnKeyEventInternal(false);
1042                 return pattern->HandleKeyEvent(event);
1043             }
1044         }
1045         return false;
1046     });
1047 }
1048 
1049 #ifdef SUPPORT_DIGITAL_CROWN
InitCrownEvent(const RefPtr<FocusHub> & focusHub)1050 void UIExtensionPattern::InitCrownEvent(const RefPtr<FocusHub>& focusHub)
1051 {
1052     focusHub->SetOnCrownEventInternal([wp = WeakClaim(this)](const CrownEvent& event) -> bool {
1053         auto pattern = wp.Upgrade();
1054         if (pattern) {
1055             pattern->HandleCrownEvent(event);
1056         }
1057         return false;
1058     });
1059 }
1060 
HandleCrownEvent(const CrownEvent & event)1061 void UIExtensionPattern::HandleCrownEvent(const CrownEvent& event)
1062 {
1063     if (event.action == Ace::CrownAction::UNKNOWN) {
1064         UIEXT_LOGE("action is UNKNOWN");
1065         return;
1066     }
1067     auto pointerEvent = event.GetPointerEvent();
1068     CHECK_NULL_VOID(pointerEvent);
1069     auto host = GetHost();
1070     CHECK_NULL_VOID(host);
1071     Platform::CalculatePointerEvent(pointerEvent, host);
1072     DispatchPointerEvent(pointerEvent);
1073 }
1074 #endif
1075 
InitKeyEvent(const RefPtr<FocusHub> & focusHub)1076 void UIExtensionPattern::InitKeyEvent(const RefPtr<FocusHub>& focusHub)
1077 {
1078     focusHub->SetIsNodeNeedKey(true);
1079     InitKeyEventOnFocus(focusHub);
1080     InitKeyEventOnBlur(focusHub);
1081     InitKeyEventOnClearFocusState(focusHub);
1082     InitKeyEventOnPaintFocusState(focusHub);
1083     InitKeyEventOnKeyEvent(focusHub);
1084 }
1085 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)1086 void UIExtensionPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
1087 {
1088     if (touchEvent_) {
1089         return;
1090     }
1091     auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
1092         auto pattern = weak.Upgrade();
1093         if (pattern) {
1094             pattern->HandleTouchEvent(info);
1095         }
1096     };
1097     if (touchEvent_) {
1098         gestureHub->RemoveTouchEvent(touchEvent_);
1099     }
1100     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
1101     gestureHub->AddTouchEvent(touchEvent_);
1102 }
1103 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)1104 void UIExtensionPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
1105 {
1106     if (mouseEvent_) {
1107         return;
1108     }
1109     auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
1110         auto pattern = weak.Upgrade();
1111         if (pattern) {
1112             pattern->HandleMouseEvent(info);
1113         }
1114     };
1115     if (mouseEvent_) {
1116         inputHub->RemoveOnMouseEvent(mouseEvent_);
1117     }
1118     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
1119     inputHub->AddOnMouseEvent(mouseEvent_);
1120 }
1121 
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)1122 void UIExtensionPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
1123 {
1124     if (hoverEvent_) {
1125         return;
1126     }
1127     auto callback = [weak = WeakClaim(this)](bool isHover) {
1128         auto pattern = weak.Upgrade();
1129         if (pattern) {
1130             pattern->HandleHoverEvent(isHover);
1131         }
1132     };
1133     if (hoverEvent_) {
1134         inputHub->RemoveOnHoverEvent(hoverEvent_);
1135     }
1136     hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
1137     inputHub->AddOnHoverEvent(hoverEvent_);
1138 }
1139 
HandleKeyEvent(const KeyEvent & event)1140 bool UIExtensionPattern::HandleKeyEvent(const KeyEvent& event)
1141 {
1142     return DispatchKeyEventSync(event);
1143 }
1144 
HandleFocusEvent()1145 void UIExtensionPattern::HandleFocusEvent()
1146 {
1147     auto pipeline = PipelineContext::GetCurrentContext();
1148     CHECK_NULL_VOID(pipeline);
1149     if (canFocusSendToUIExtension_) {
1150         if (pipeline->GetIsFocusActive()) {
1151             DispatchFocusActiveEvent(true);
1152         }
1153 
1154         DispatchFocusState(true);
1155         needReSendFocusToUIExtension_ = false;
1156     } else {
1157         needReSendFocusToUIExtension_ = true;
1158     }
1159 
1160     canFocusSendToUIExtension_ = true;
1161     auto uiExtensionManager = pipeline->GetUIExtensionManager();
1162     uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
1163 }
1164 
HandleBlurEvent()1165 void UIExtensionPattern::HandleBlurEvent()
1166 {
1167     DispatchFocusActiveEvent(false);
1168     DispatchFocusState(false);
1169     auto pipeline = PipelineContext::GetCurrentContext();
1170     CHECK_NULL_VOID(pipeline);
1171     auto uiExtensionManager = pipeline->GetUIExtensionManager();
1172     uiExtensionManager->RegisterUIExtensionInFocus(nullptr, nullptr);
1173 }
1174 
HandleTouchEvent(const TouchEventInfo & info)1175 void UIExtensionPattern::HandleTouchEvent(const TouchEventInfo& info)
1176 {
1177     if (info.GetSourceDevice() != SourceType::TOUCH) {
1178         UIEXT_LOGE("The source type is not TOUCH, type %{public}d.", info.GetSourceDevice());
1179         return;
1180     }
1181     const auto pointerEvent = info.GetPointerEvent();
1182     if (!pointerEvent) {
1183         UIEXT_LOGE("The pointerEvent is empty.");
1184         return;
1185     }
1186     auto host = GetHost();
1187     CHECK_NULL_VOID(host);
1188     auto pipeline = PipelineBase::GetCurrentContext();
1189     CHECK_NULL_VOID(pipeline);
1190     std::shared_ptr<MMI::PointerEvent> newPointerEvent = std::make_shared<MMI::PointerEvent>(*pointerEvent);
1191     Platform::CalculatePointerEvent(newPointerEvent, host);
1192     AceExtraInputData::InsertInterpolatePoints(info);
1193     auto focusHub = host->GetFocusHub();
1194     CHECK_NULL_VOID(focusHub);
1195     bool ret = true;
1196     focusState_ = pipeline->IsWindowFocused();
1197     if (focusState_ && !focusHub->IsCurrentFocus()) {
1198         canFocusSendToUIExtension_ = false;
1199         ret = focusHub->RequestFocusImmediately();
1200         if (!ret) {
1201             canFocusSendToUIExtension_ = true;
1202             UIEXT_LOGW("RequestFocusImmediately failed when HandleTouchEvent.");
1203         }
1204     }
1205     DispatchPointerEvent(newPointerEvent);
1206     if (focusState_ && newPointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) {
1207         if (needReSendFocusToUIExtension_) {
1208             HandleFocusEvent();
1209             needReSendFocusToUIExtension_ = false;
1210         }
1211         SetForceProcessOnKeyEventInternal(true);
1212     }
1213 }
1214 
HandleMouseEvent(const MouseInfo & info)1215 void UIExtensionPattern::HandleMouseEvent(const MouseInfo& info)
1216 {
1217     if (info.GetSourceDevice() != SourceType::MOUSE) {
1218         return;
1219     }
1220     if (info.GetPullAction() == MouseAction::PULL_MOVE || info.GetPullAction() == MouseAction::PULL_UP) {
1221         return;
1222     }
1223     const auto pointerEvent = info.GetPointerEvent();
1224     CHECK_NULL_VOID(pointerEvent);
1225     lastPointerEvent_ = pointerEvent;
1226     auto host = GetHost();
1227     CHECK_NULL_VOID(host);
1228     Platform::CalculatePointerEvent(pointerEvent, host);
1229     if (info.GetAction() == MouseAction::PRESS) {
1230         auto hub = host->GetFocusHub();
1231         CHECK_NULL_VOID(hub);
1232         hub->RequestFocusImmediately();
1233         SetForceProcessOnKeyEventInternal(true);
1234     }
1235     DispatchPointerEvent(pointerEvent);
1236 }
1237 
HandleHoverEvent(bool isHover)1238 void UIExtensionPattern::HandleHoverEvent(bool isHover)
1239 {
1240     if (isHover) {
1241         return;
1242     }
1243     CHECK_NULL_VOID(lastPointerEvent_);
1244     lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
1245     DispatchPointerEvent(lastPointerEvent_);
1246 }
1247 
DispatchKeyEvent(const KeyEvent & event)1248 void UIExtensionPattern::DispatchKeyEvent(const KeyEvent& event)
1249 {
1250     CHECK_NULL_VOID(event.rawKeyEvent);
1251     CHECK_NULL_VOID(sessionWrapper_);
1252     sessionWrapper_->NotifyKeyEventAsync(event.rawKeyEvent);
1253 }
1254 
DispatchKeyEventSync(const KeyEvent & event)1255 bool UIExtensionPattern::DispatchKeyEventSync(const KeyEvent& event)
1256 {
1257     CHECK_NULL_RETURN(sessionWrapper_, false);
1258     if (isKeyAsync_) {
1259         sessionWrapper_->NotifyKeyEventAsync(event.rawKeyEvent, false);
1260         return true;
1261     }
1262     bool isTab = event.IsKey({ KeyCode::KEY_TAB });
1263     if (!isTab) {
1264         SetForceProcessOnKeyEventInternal(true);
1265     }
1266     return sessionWrapper_->NotifyKeyEventSync(event.rawKeyEvent, event.isPreIme);
1267 }
1268 
DispatchFocusActiveEvent(bool isFocusActive)1269 void UIExtensionPattern::DispatchFocusActiveEvent(bool isFocusActive)
1270 {
1271     CHECK_NULL_VOID(sessionWrapper_);
1272     sessionWrapper_->NotifyFocusEventAsync(isFocusActive);
1273 }
1274 
DispatchFocusState(bool focusState)1275 void UIExtensionPattern::DispatchFocusState(bool focusState)
1276 {
1277     CHECK_NULL_VOID(sessionWrapper_);
1278     sessionWrapper_->NotifyFocusStateAsync(focusState);
1279 }
1280 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1281 void UIExtensionPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1282 {
1283     if (!pointerEvent) {
1284         UIEXT_LOGE("DispatchPointerEvent pointerEvent is null.");
1285         return;
1286     }
1287     if (!sessionWrapper_) {
1288         UIEXT_LOGE("DispatchPointerEvent sessionWrapper is null.");
1289         return;
1290     }
1291     sessionWrapper_->NotifyPointerEventAsync(pointerEvent);
1292 }
1293 
DispatchDisplayArea(bool isForce)1294 void UIExtensionPattern::DispatchDisplayArea(bool isForce)
1295 {
1296     CHECK_NULL_VOID(sessionWrapper_);
1297     auto host = GetHost();
1298     CHECK_NULL_VOID(host);
1299     auto [displayOffset, err] = host->GetPaintRectGlobalOffsetWithTranslate();
1300     auto geometryNode = host->GetGeometryNode();
1301     CHECK_NULL_VOID(geometryNode);
1302     auto renderContext = host->GetRenderContext();
1303     CHECK_NULL_VOID(renderContext);
1304     auto displaySize = renderContext->GetPaintRectWithoutTransform().GetSize();
1305     auto displayArea = RectF(displayOffset, displaySize);
1306     bool sizeChange = displayArea_ != displayArea;
1307     if (sizeChange || isForce) {
1308         displayArea_ = displayArea;
1309         if (state_ == AbilityState::FOREGROUND) {
1310             if (sizeChange) {
1311                 MountPlaceholderNode(GetSizeChangeReason());
1312             }
1313             sessionWrapper_->NotifyDisplayArea(displayArea_);
1314         } else {
1315             displayAreaChanged_ = true;
1316         }
1317     }
1318 }
1319 
SetEventProxyFlag(int32_t flag)1320 void UIExtensionPattern::SetEventProxyFlag(int32_t flag)
1321 {
1322     auto host = GetHost();
1323     CHECK_NULL_VOID(host);
1324     if (flag != static_cast<int32_t>(EventProxyFlag::EVENT_NONE)
1325         && platformEventProxy_ == nullptr) {
1326         platformEventProxy_ = MakeRefPtr<PlatformEventProxy>();
1327         platformEventProxy_->SetHostNode(host);
1328     }
1329 
1330     if (platformEventProxy_ != nullptr) {
1331         platformEventProxy_->SetEventProxyFlag(flag);
1332     }
1333 }
1334 
HandleDragEvent(const DragPointerEvent & info)1335 void UIExtensionPattern::HandleDragEvent(const DragPointerEvent& info)
1336 {
1337     auto pointerEvent = info.rawPointerEvent;
1338     CHECK_NULL_VOID(pointerEvent);
1339     std::shared_ptr<MMI::PointerEvent> newPointerEvent = std::make_shared<MMI::PointerEvent>(*pointerEvent);
1340     CHECK_NULL_VOID(newPointerEvent);
1341     auto host = GetHost();
1342     CHECK_NULL_VOID(host);
1343     auto pipeline = PipelineBase::GetCurrentContext();
1344     CHECK_NULL_VOID(pipeline);
1345     Platform::CalculatePointerEvent(newPointerEvent, host, true);
1346     Platform::UpdatePointerAction(newPointerEvent, info.action);
1347     DispatchPointerEvent(newPointerEvent);
1348 }
1349 
SetOnRemoteReadyCallback(const std::function<void (const RefPtr<UIExtensionProxy> &)> && callback)1350 void UIExtensionPattern::SetOnRemoteReadyCallback(const std::function<void(const RefPtr<UIExtensionProxy>&)>&& callback)
1351 {
1352     onRemoteReadyCallback_ = std::move(callback);
1353 }
1354 
SetModalOnRemoteReadyCallback(const std::function<void (const std::shared_ptr<ModalUIExtensionProxy> &)> && callback)1355 void UIExtensionPattern::SetModalOnRemoteReadyCallback(
1356     const std::function<void(const std::shared_ptr<ModalUIExtensionProxy>&)>&& callback)
1357 {
1358     onModalRemoteReadyCallback_ = std::move(callback);
1359 }
1360 
FireOnRemoteReadyCallback()1361 void UIExtensionPattern::FireOnRemoteReadyCallback()
1362 {
1363     UIEXT_LOGI("OnRemoteReady the current state is '%{public}s'.", ToString(state_));
1364     ContainerScope scope(instanceId_);
1365     // These two callbacks will be unified in the future.
1366     if (onRemoteReadyCallback_) {
1367         onRemoteReadyCallback_(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1368     }
1369     if (onModalRemoteReadyCallback_) {
1370         onModalRemoteReadyCallback_(std::make_shared<ModalUIExtensionProxyImpl>(sessionWrapper_));
1371     }
1372 }
1373 
SetModalOnDestroy(const std::function<void ()> && callback)1374 void UIExtensionPattern::SetModalOnDestroy(const std::function<void()>&& callback)
1375 {
1376     onModalDestroy_ = std::move(callback);
1377 }
1378 
FireModalOnDestroy()1379 void UIExtensionPattern::FireModalOnDestroy()
1380 {
1381     UIEXT_LOGI("ModalOnDestroy the current state is '%{public}s'.", ToString(state_));
1382     // Native modal page destroy callback
1383     if (onModalDestroy_) {
1384         ContainerScope scope(instanceId_);
1385         onModalDestroy_();
1386     }
1387 }
1388 
SetOnReleaseCallback(const std::function<void (int32_t)> && callback)1389 void UIExtensionPattern::SetOnReleaseCallback(const std::function<void(int32_t)>&& callback)
1390 {
1391     onReleaseCallback_ = std::move(callback);
1392 }
1393 
FireOnReleaseCallback(int32_t releaseCode)1394 void UIExtensionPattern::FireOnReleaseCallback(int32_t releaseCode)
1395 {
1396     UIEXT_LOGI("OnRelease the state is changing from '%{public}s' to 'DESTRUCTION' and releaseCode = %{public}d.",
1397         ToString(state_), releaseCode);
1398     state_ = AbilityState::DESTRUCTION;
1399     SetEventProxyFlag(static_cast<int32_t>(EventProxyFlag::EVENT_NONE));
1400     if (onReleaseCallback_) {
1401         onReleaseCallback_(releaseCode);
1402     }
1403     // Release the session.
1404     if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
1405         sessionWrapper_->OnReleaseDone();
1406     }
1407 }
1408 
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)1409 void UIExtensionPattern::SetOnErrorCallback(
1410     const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
1411 {
1412     onErrorCallback_ = std::move(callback);
1413     if (lastError_.code != 0) {
1414         ErrorMsg error;
1415         std::swap(lastError_, error);
1416         FireOnErrorCallback(error.code, error.name, error.message);
1417     }
1418 }
1419 
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)1420 void UIExtensionPattern::FireOnErrorCallback(int32_t code, const std::string& name, const std::string& message)
1421 {
1422     // 1. As long as the error occurs, the host believes that UIExtensionAbility has been killed.
1423     UIEXT_LOGI("OnError the state is changing from '%{public}s' to 'NONE', errorCode = %{public}d.",
1424         ToString(state_), code);
1425     state_ = AbilityState::NONE;
1426     SetEventProxyFlag(static_cast<int32_t>(EventProxyFlag::EVENT_NONE));
1427     // Release the session.
1428     if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
1429         if (!IsShowPlaceholder()) {
1430             auto host = GetHost();
1431             CHECK_NULL_VOID(host);
1432             host->RemoveChildAtIndex(0);
1433             host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1434         }
1435         if (name.compare("extension_node_transparent") != 0) {
1436             sessionWrapper_->NotifyDestroy(false);
1437             sessionWrapper_->DestroySession();
1438         }
1439     }
1440     if (onErrorCallback_) {
1441         ContainerScope scope(instanceId_);
1442         onErrorCallback_(code, name, message);
1443         return;
1444     }
1445     lastError_ = { code, name, message };
1446 }
1447 
SetOnResultCallback(const std::function<void (int32_t,const AAFwk::Want &)> && callback)1448 void UIExtensionPattern::SetOnResultCallback(const std::function<void(int32_t, const AAFwk::Want&)>&& callback)
1449 {
1450     onResultCallback_ = std::move(callback);
1451 }
1452 
FireOnResultCallback(int32_t code,const AAFwk::Want & want)1453 void UIExtensionPattern::FireOnResultCallback(int32_t code, const AAFwk::Want& want)
1454 {
1455     UIEXT_LOGI("OnResult the state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
1456     if (onResultCallback_ && (state_ != AbilityState::DESTRUCTION)) {
1457         ContainerScope scope(instanceId_);
1458         onResultCallback_(code, want);
1459     }
1460     state_ = AbilityState::DESTRUCTION;
1461 }
1462 
IsCompatibleOldVersion()1463 bool UIExtensionPattern::IsCompatibleOldVersion()
1464 {
1465     ContainerScope scope(instanceId_);
1466     return (sessionType_ == SessionType::UI_EXTENSION_ABILITY) && (onTerminatedCallback_ == nullptr);
1467 }
1468 
SetOnTerminatedCallback(const std::function<void (int32_t,const RefPtr<WantWrap> & wantWrap)> && callback)1469 void UIExtensionPattern::SetOnTerminatedCallback(
1470     const std::function<void(int32_t, const RefPtr<WantWrap>& wantWrap)>&& callback)
1471 {
1472     onTerminatedCallback_ = std::move(callback);
1473 }
1474 
FireOnTerminatedCallback(int32_t code,const RefPtr<WantWrap> & wantWrap)1475 void UIExtensionPattern::FireOnTerminatedCallback(int32_t code, const RefPtr<WantWrap>& wantWrap)
1476 {
1477     UIEXT_LOGI("OnTerminated the state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
1478     if (onTerminatedCallback_ && (state_ != AbilityState::DESTRUCTION)) {
1479         ContainerScope scope(instanceId_);
1480         onTerminatedCallback_(code, wantWrap);
1481     }
1482     state_ = AbilityState::DESTRUCTION;
1483     SetEventProxyFlag(static_cast<int32_t>(EventProxyFlag::EVENT_NONE));
1484 }
1485 
SetOnReceiveCallback(const std::function<void (const AAFwk::WantParams &)> && callback)1486 void UIExtensionPattern::SetOnReceiveCallback(const std::function<void(const AAFwk::WantParams&)>&& callback)
1487 {
1488     onReceiveCallback_ = std::move(callback);
1489 }
1490 
FireOnReceiveCallback(const AAFwk::WantParams & params)1491 void UIExtensionPattern::FireOnReceiveCallback(const AAFwk::WantParams& params)
1492 {
1493     UIEXT_LOGI("OnReceive the current state is '%{public}s'.", ToString(state_));
1494     if (onReceiveCallback_) {
1495         ContainerScope scope(instanceId_);
1496         onReceiveCallback_(params);
1497     }
1498 }
1499 
SetSyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)1500 void UIExtensionPattern::SetSyncCallbacks(
1501     const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
1502 {
1503     onSyncOnCallbackList_ = std::move(callbackList);
1504 }
1505 
FireSyncCallbacks()1506 void UIExtensionPattern::FireSyncCallbacks()
1507 {
1508     UIEXT_LOGI("The size of sync callbacks = %{public}zu.", onSyncOnCallbackList_.size());
1509     ContainerScope scope(instanceId_);
1510     for (const auto& callback : onSyncOnCallbackList_) {
1511         if (callback) {
1512             callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1513         }
1514     }
1515 }
1516 
SetAsyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)1517 void UIExtensionPattern::SetAsyncCallbacks(
1518     const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
1519 {
1520     onAsyncOnCallbackList_ = std::move(callbackList);
1521 }
1522 
FireAsyncCallbacks()1523 void UIExtensionPattern::FireAsyncCallbacks()
1524 {
1525     UIEXT_LOGI("The size of async callbacks = %{public}zu.", onSyncOnCallbackList_.size());
1526     ContainerScope scope(instanceId_);
1527     for (const auto& callback : onAsyncOnCallbackList_) {
1528         if (callback) {
1529             callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1530         }
1531     }
1532 }
1533 
SetBindModalCallback(const std::function<void ()> && callback)1534 void UIExtensionPattern::SetBindModalCallback(const std::function<void()>&& callback)
1535 {
1536     bindModalCallback_ = std::move(callback);
1537 }
1538 
FireBindModalCallback()1539 void UIExtensionPattern::FireBindModalCallback()
1540 {
1541     if (bindModalCallback_) {
1542         bindModalCallback_();
1543     }
1544 }
1545 
SetDensityDpi(bool densityDpi)1546 void UIExtensionPattern::SetDensityDpi(bool densityDpi)
1547 {
1548     densityDpi_ = densityDpi;
1549 }
1550 
GetDensityDpi()1551 bool UIExtensionPattern::GetDensityDpi()
1552 {
1553     return densityDpi_;
1554 }
1555 
OnVisibleChange(bool visible)1556 void UIExtensionPattern::OnVisibleChange(bool visible)
1557 {
1558     UIEXT_LOGI("The component is changing from '%{public}s' to '%{public}s'.", isVisible_ ? "visible" : "invisible",
1559         visible ? "visible" : "invisible");
1560     isVisible_ = visible;
1561     if (visible) {
1562         NotifyForeground();
1563     } else {
1564         NotifyBackground();
1565     }
1566 }
1567 
InitializeAccessibility()1568 void UIExtensionPattern::InitializeAccessibility()
1569 {
1570     if (accessibilityChildTreeCallback_ != nullptr) {
1571         return;
1572     }
1573     auto instanceId = GetInstanceIdFromHost();
1574     ContainerScope scope(instanceId);
1575     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
1576     CHECK_NULL_VOID(ngPipeline);
1577     auto frontend = ngPipeline->GetFrontend();
1578     CHECK_NULL_VOID(frontend);
1579     auto accessibilityManager = frontend->GetAccessibilityManager();
1580     CHECK_NULL_VOID(accessibilityManager);
1581     auto frameNode = frameNode_.Upgrade();
1582     CHECK_NULL_VOID(frameNode);
1583     int64_t accessibilityId = frameNode->GetAccessibilityId();
1584     accessibilityChildTreeCallback_ = std::make_shared<UIExtensionAccessibilityChildTreeCallback>(
1585         WeakClaim(this), accessibilityId);
1586     CHECK_NULL_VOID(accessibilityChildTreeCallback_);
1587     auto realHostWindowId = ngPipeline->GetRealHostWindowId();
1588     realHostWindowId_ = realHostWindowId;
1589     focusWindowId_ = ngPipeline->GetFocusWindowId();
1590     if (accessibilityManager->IsRegister()) {
1591         accessibilityChildTreeCallback_->OnRegister(
1592             realHostWindowId, accessibilityManager->GetTreeId());
1593     }
1594     UIEXT_LOGI("UIExtension: %{public}" PRId64 " register child tree, realHostWindowId: %{public}u",
1595         accessibilityId, realHostWindowId);
1596     accessibilityManager->RegisterAccessibilityChildTreeCallback(accessibilityId, accessibilityChildTreeCallback_);
1597 }
1598 
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)1599 void UIExtensionPattern::OnAccessibilityChildTreeRegister(uint32_t windowId, int32_t treeId, int64_t accessibilityId)
1600 {
1601     UIEXT_LOGI("treeId: %{public}d, id: %{public}" PRId64, treeId, accessibilityId);
1602     if (sessionWrapper_ == nullptr) {
1603         UIEXT_LOGI("sessionWrapper_ is null");
1604         return;
1605     }
1606     sessionWrapper_->TransferAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
1607 }
1608 
OnAccessibilityChildTreeDeregister()1609 void UIExtensionPattern::OnAccessibilityChildTreeDeregister()
1610 {
1611     UIEXT_LOGI("deregister accessibility child tree");
1612     if (sessionWrapper_ == nullptr) {
1613         UIEXT_LOGI("sessionWrapper_ is null");
1614         return;
1615     }
1616     sessionWrapper_->TransferAccessibilityChildTreeDeregister();
1617 }
1618 
OnSetAccessibilityChildTree(int32_t childWindowId,int32_t childTreeId)1619 void UIExtensionPattern::OnSetAccessibilityChildTree(int32_t childWindowId, int32_t childTreeId)
1620 {
1621     auto frameNode = frameNode_.Upgrade();
1622     CHECK_NULL_VOID(frameNode);
1623     auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
1624     CHECK_NULL_VOID(accessibilityProperty);
1625     accessibilityProperty->SetChildWindowId(childWindowId);
1626     accessibilityProperty->SetChildTreeId(childTreeId);
1627 }
1628 
OnAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)1629 void UIExtensionPattern::OnAccessibilityDumpChildInfo(
1630     const std::vector<std::string>& params, std::vector<std::string>& info)
1631 {
1632     UIEXT_LOGI("dump accessibility child info");
1633     if (sessionWrapper_ == nullptr) {
1634         UIEXT_LOGI("sessionWrapper_ is null");
1635         return;
1636     }
1637     sessionWrapper_->TransferAccessibilityDumpChildInfo(params, info);
1638 }
1639 
ResetAccessibilityChildTreeCallback()1640 void UIExtensionPattern::ResetAccessibilityChildTreeCallback()
1641 {
1642     CHECK_NULL_VOID(accessibilityChildTreeCallback_);
1643     auto instanceId = GetInstanceIdFromHost();
1644     ContainerScope scope(instanceId);
1645     auto ngPipeline = NG::PipelineContext::GetCurrentContext();
1646     CHECK_NULL_VOID(ngPipeline);
1647     auto frontend = ngPipeline->GetFrontend();
1648     CHECK_NULL_VOID(frontend);
1649     auto accessibilityManager = frontend->GetAccessibilityManager();
1650     CHECK_NULL_VOID(accessibilityManager);
1651     accessibilityManager->DeregisterAccessibilityChildTreeCallback(
1652         accessibilityChildTreeCallback_->GetAccessibilityId());
1653     accessibilityChildTreeCallback_.reset();
1654     accessibilityChildTreeCallback_ = nullptr;
1655 }
1656 
OnMountToParentDone()1657 void UIExtensionPattern::OnMountToParentDone()
1658 {
1659     UIEXT_LOGI("OnMountToParentDone.");
1660     hasMountToParent_ = true;
1661     if (needReNotifyForeground_) {
1662         auto hostWindowNode = WindowSceneHelper::FindWindowScene(GetHost());
1663         if (hostWindowNode) {
1664             needReNotifyForeground_ = false;
1665             UIEXT_LOGI("NotifyForeground OnMountToParentDone.");
1666             NotifyForeground();
1667         } else {
1668             UIEXT_LOGI("No WindowScene When OnMountToParentDone, wait.");
1669         }
1670     }
1671     auto frameNode = frameNode_.Upgrade();
1672     CHECK_NULL_VOID(frameNode);
1673     if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
1674         UIEXT_LOGD("Frame node status is normal.");
1675         return;
1676     }
1677     auto wantWrap = GetWantWrap();
1678     CHECK_NULL_VOID(wantWrap);
1679     UpdateWant(wantWrap);
1680     SetWantWrap(nullptr);
1681 }
1682 
AfterMountToParent()1683 void UIExtensionPattern::AfterMountToParent()
1684 {
1685     UIEXT_LOGI("AfterMountToParent.");
1686     hasMountToParent_ = true;
1687     if (needReNotifyForeground_) {
1688         auto hostWindowNode = WindowSceneHelper::FindWindowScene(GetHost());
1689         if (hostWindowNode) {
1690             needReNotifyForeground_ = false;
1691             UIEXT_LOGI("NotifyForeground AfterMountToParent.");
1692             NotifyForeground();
1693         } else {
1694             UIEXT_LOGI("No WindowScene When AfterMountToParent, wait.");
1695         }
1696     }
1697 }
1698 
RegisterVisibleAreaChange()1699 void UIExtensionPattern::RegisterVisibleAreaChange()
1700 {
1701     auto pipeline = PipelineContext::GetCurrentContext();
1702     CHECK_NULL_VOID(pipeline);
1703     auto host = GetHost();
1704     CHECK_NULL_VOID(host);
1705     auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
1706         auto uiExtension = weak.Upgrade();
1707         CHECK_NULL_VOID(uiExtension);
1708         uiExtension->HandleVisibleAreaChange(visible, ratio);
1709     };
1710     std::vector<double> ratioList = { SHOW_START, SHOW_FULL };
1711     pipeline->AddVisibleAreaChangeNode(host, ratioList, callback, false);
1712 }
1713 
HandleVisibleAreaChange(bool visible,double ratio)1714 void UIExtensionPattern::HandleVisibleAreaChange(bool visible, double ratio)
1715 {
1716     if (IsMoving()) {
1717         UIEXT_LOGI("HandleVisibleAreaChange when uec is moving.");
1718         return;
1719     }
1720 
1721     UIEXT_LOGI("HandleVisibleAreaChange visible: %{public}d, curVisible: %{public}d, "
1722         "ratio: %{public}f, displayArea: %{public}s.", visible, curVisible_,
1723         ratio, displayArea_.ToString().c_str());
1724     bool needCheckDisplayArea = NearEqual(ratio, SHOW_FULL) && curVisible_ && visible;
1725     bool curVisible = !NearEqual(ratio, SHOW_START);
1726     if (curVisible_ != curVisible) {
1727         curVisible_ = curVisible;
1728         OnVisibleChange(curVisible_);
1729     }
1730 
1731     if (needCheckDisplayArea) {
1732         DispatchDisplayArea(false);
1733     }
1734 }
1735 
OnLanguageConfigurationUpdate()1736 void UIExtensionPattern::OnLanguageConfigurationUpdate()
1737 {
1738     CHECK_NULL_VOID(sessionWrapper_);
1739     sessionWrapper_->NotifyConfigurationUpdate();
1740 }
1741 
OnColorConfigurationUpdate()1742 void UIExtensionPattern::OnColorConfigurationUpdate()
1743 {
1744     CHECK_NULL_VOID(sessionWrapper_);
1745     sessionWrapper_->NotifyConfigurationUpdate();
1746 }
1747 
GetSessionId() const1748 int32_t UIExtensionPattern::GetSessionId() const
1749 {
1750     return sessionWrapper_ ? sessionWrapper_->GetSessionId() : 0;
1751 }
1752 
GetUiExtensionId()1753 int32_t UIExtensionPattern::GetUiExtensionId()
1754 {
1755     return uiExtensionId_;
1756 }
1757 
GetNodeId() const1758 int32_t UIExtensionPattern::GetNodeId() const
1759 {
1760     auto host = GetHost();
1761     return host ? host->GetId() : -1;
1762 }
1763 
GetInstanceId() const1764 int32_t UIExtensionPattern::GetInstanceId() const
1765 {
1766     return instanceId_;
1767 }
1768 
GetInstanceIdFromHost() const1769 int32_t UIExtensionPattern::GetInstanceIdFromHost() const
1770 {
1771     auto instanceId = GetHostInstanceId();
1772     if (instanceId != instanceId_) {
1773         UIEXT_LOGW("UIExtension pattern instanceId %{public}d not equal frame node instanceId %{public}d",
1774             instanceId_, instanceId);
1775     }
1776     return instanceId;
1777 }
1778 
DispatchOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)1779 void UIExtensionPattern::DispatchOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
1780 {
1781     CHECK_NULL_VOID(sessionWrapper_);
1782     sessionWrapper_->NotifyOriginAvoidArea(avoidArea, type);
1783 }
1784 
SetWantWrap(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)1785 void UIExtensionPattern::SetWantWrap(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
1786 {
1787     curWant_ = wantWrap;
1788 }
1789 
GetWantWrap()1790 RefPtr<OHOS::Ace::WantWrap> UIExtensionPattern::GetWantWrap()
1791 {
1792     return curWant_;
1793 }
1794 
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)1795 int64_t UIExtensionPattern::WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
1796 {
1797     return uiExtensionId_ * extensionOffset + abilityId;
1798 }
1799 
ToString(AbilityState state)1800 const char* UIExtensionPattern::ToString(AbilityState state)
1801 {
1802     switch (state) {
1803         case AbilityState::FOREGROUND:
1804             return "FOREGROUND";
1805         case AbilityState::BACKGROUND:
1806             return "BACKGROUND";
1807         case AbilityState::DESTRUCTION:
1808             return "DESTRUCTION";
1809         case AbilityState::NONE:
1810         default:
1811             return "NONE";
1812     }
1813 }
1814 
DumpInfo()1815 void UIExtensionPattern::DumpInfo()
1816 {
1817     CHECK_NULL_VOID(sessionWrapper_);
1818     UIEXT_LOGI("Dump UIE Info In String Format");
1819     DumpLog::GetInstance().AddDesc(std::string("focusWindowId: ").append(std::to_string(focusWindowId_)));
1820     DumpLog::GetInstance().AddDesc(std::string("realHostWindowId: ").append(std::to_string(realHostWindowId_)));
1821     DumpLog::GetInstance().AddDesc(std::string("want: ").append(want_));
1822     DumpLog::GetInstance().AddDesc(std::string("displayArea: ").append(displayArea_.ToString()));
1823     DumpLog::GetInstance().AddDesc(std::string("reason: ").append(std::to_string(sessionWrapper_->GetReasonDump())));
1824     DumpLog::GetInstance().AddDesc(std::string("focusStatus: ").append(std::to_string(focusState_)));
1825     DumpLog::GetInstance().AddDesc(std::string("abilityState: ").append(ToString(state_)));
1826     std::string eventProxyStr = "[]";
1827     if (platformEventProxy_) {
1828         eventProxyStr = platformEventProxy_->GetCurEventProxyToString();
1829     }
1830     DumpLog::GetInstance().AddDesc(std::string("eventProxy: ").append(eventProxyStr));
1831 
1832     auto container = Platform::AceContainer::GetContainer(instanceId_);
1833     CHECK_NULL_VOID(container);
1834     std::vector<std::string> params = container->GetUieParams();
1835     // Use -nouie to choose not dump extra uie info
1836     if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1837         UIEXT_LOGI("Not Support Dump Extra UIE Info");
1838     } else {
1839         if (!container->IsUIExtensionWindow()) {
1840             params.push_back(PID_FLAG);
1841         }
1842         params.push_back(std::to_string(getpid()));
1843         std::vector<std::string> dumpInfo;
1844         sessionWrapper_->NotifyUieDump(params, dumpInfo);
1845         for (std::string info : dumpInfo) {
1846             DumpLog::GetInstance().AddDesc(std::string("UI Extension info: ").append(info));
1847         }
1848     }
1849 }
1850 
DumpInfo(std::unique_ptr<JsonValue> & json)1851 void UIExtensionPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
1852 {
1853     CHECK_NULL_VOID(sessionWrapper_);
1854     UIEXT_LOGI("Dump UIE Info In Json Format");
1855     json->Put("focusWindowId: ", std::to_string(focusWindowId_).c_str());
1856     json->Put("realHostWindowId: ", std::to_string(realHostWindowId_).c_str());
1857     json->Put("want: ", want_.c_str());
1858     json->Put("displayArea: ", displayArea_.ToString().c_str());
1859     json->Put("reason: ", std::to_string(sessionWrapper_->GetReasonDump()).c_str());
1860     json->Put("focusStatus: ", std::to_string(focusState_).c_str());
1861     json->Put("abilityState: ", ToString(state_));
1862     std::string eventProxyStr = "[]";
1863     if (platformEventProxy_) {
1864         eventProxyStr = platformEventProxy_->GetCurEventProxyToString();
1865     }
1866     json->Put("eventProxy: ", eventProxyStr.c_str());
1867 
1868     auto container = Platform::AceContainer::GetContainer(instanceId_);
1869     CHECK_NULL_VOID(container);
1870     std::vector<std::string> params = container->GetUieParams();
1871     // Use -nouie to choose not dump extra uie info
1872     if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1873         UIEXT_LOGI("Not Support Dump Extra UIE Info");
1874     } else {
1875         if (!container->IsUIExtensionWindow()) {
1876             params.push_back(PID_FLAG);
1877         }
1878         params.push_back(std::to_string(getpid()));
1879         std::vector<std::string> dumpInfo;
1880         sessionWrapper_->NotifyUieDump(params, dumpInfo);
1881         for (std::string info : dumpInfo) {
1882             json->Put("UI Extension info: ", info.c_str());
1883         }
1884     }
1885 }
1886 
DumpOthers()1887 void UIExtensionPattern::DumpOthers()
1888 {
1889     CHECK_NULL_VOID(sessionWrapper_);
1890     auto container = Platform::AceContainer::GetContainer(instanceId_);
1891     CHECK_NULL_VOID(container);
1892     std::vector<std::string> params = container->GetUieParams();
1893     // Use -nouie to choose not dump extra uie info
1894     if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1895         UIEXT_LOGI("Not Support Dump Extra UIE Info");
1896     } else {
1897         if (params.back() == "-json") {
1898             params.insert(params.end() - 1, std::to_string(getpid()));
1899             if (!container->IsUIExtensionWindow()) {
1900                 params.insert(params.end() - 1, PID_FLAG);
1901             }
1902         } else {
1903             if (!container->IsUIExtensionWindow()) {
1904                 params.push_back(PID_FLAG);
1905             }
1906             params.push_back(std::to_string(getpid()));
1907         }
1908         std::vector<std::string> dumpInfo;
1909         sessionWrapper_->NotifyUieDump(params, dumpInfo);
1910         for (std::string info : dumpInfo) {
1911             std::stringstream ss(info);
1912             std::string line;
1913             DumpLog::GetInstance().Print("\n------ UIExtension Dump ------");
1914             while (getline(ss, line, ';')) {
1915                 DumpLog::GetInstance().Print(line);
1916             }
1917         }
1918     }
1919 }
1920 
RegisterEventProxyFlagCallback()1921 void UIExtensionPattern::RegisterEventProxyFlagCallback()
1922 {
1923     RegisterUIExtBusinessConsumeCallback(UIContentBusinessCode::EVENT_PROXY,
1924         [weak = WeakClaim(this)](const AAFwk::Want& data) -> int32_t {
1925             auto pattern = weak.Upgrade();
1926             CHECK_NULL_RETURN(pattern, -1);
1927             std::string type = "";
1928             int32_t eventFlags = 0;
1929             if (data.HasParameter("type")) {
1930                 type = data.GetStringParam("type");
1931             }
1932             if (type == "OccupyEvents") {
1933                 if (data.HasParameter("eventFlags")) {
1934                     eventFlags = data.GetIntParam("eventFlags", 0);
1935                 }
1936                 pattern->SetEventProxyFlag(eventFlags);
1937                 return 0;
1938             } else {
1939                 return -1;
1940             }
1941         });
1942 }
1943 
RegisterReplyPageModeCallback()1944 void UIExtensionPattern::RegisterReplyPageModeCallback()
1945 {
1946     auto callback = [weak = WeakClaim(this)](const AAFwk::Want& data, std::optional<AAFwk::Want>& reply) -> int32_t {
1947         auto pattern = weak.Upgrade();
1948         CHECK_NULL_RETURN(pattern, -1);
1949         auto host = pattern->GetHost();
1950         CHECK_NULL_RETURN(host, -1);
1951         auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
1952         CHECK_NULL_RETURN(accessibilityProperty, -1);
1953 
1954         if (reply.has_value() && data.HasParameter("requestPageMode")) {
1955             reply->SetParam("pageMode", accessibilityProperty->GetAccessibilitySamePage());
1956             return 0;
1957         }
1958         return -1;
1959     };
1960     RegisterUIExtBusinessConsumeReplyCallback(UIContentBusinessCode::SEND_PAGE_MODE, callback);
1961 }
1962 
RegisterGetAvoidInfoCallback()1963 void UIExtensionPattern::RegisterGetAvoidInfoCallback()
1964 {
1965     auto callback = [weak = WeakClaim(this)](const AAFwk::Want&) -> int32_t {
1966         auto pattern = weak.Upgrade();
1967         CHECK_NULL_RETURN(pattern, -1);
1968         auto host = pattern->GetHost();
1969         CHECK_NULL_RETURN(host, -1);
1970         auto context = host->GetContext();
1971         CHECK_NULL_RETURN(context, -1);
1972         auto avoidInfoMgr = context->GetAvoidInfoManager();
1973         CHECK_NULL_RETURN(avoidInfoMgr, -1);
1974         AAFwk::Want avoidInfoWant;
1975         const auto& info = pattern->GetAvoidInfo();
1976         avoidInfoMgr->BuildAvoidInfo(info, avoidInfoWant);
1977         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1978             "UECPattern send avoidInfo: %{public}s.", info.ToString().c_str());
1979         pattern->SendBusinessData(UIContentBusinessCode::NOTIFY_AVOID_INFO_CHANGE,
1980             std::move(avoidInfoWant), BusinessDataSendType::ASYNC);
1981         return 0;
1982     };
1983     RegisterUIExtBusinessConsumeCallback(UIContentBusinessCode::GET_AVOID_INFO, callback);
1984 }
1985 
SendBusinessDataSyncReply(UIContentBusinessCode code,const AAFwk::Want & data,AAFwk::Want & reply,RSSubsystemId subSystemId)1986 bool UIExtensionPattern::SendBusinessDataSyncReply(
1987     UIContentBusinessCode code, const AAFwk::Want& data, AAFwk::Want& reply, RSSubsystemId subSystemId)
1988 {
1989     CHECK_NULL_RETURN(sessionWrapper_, false);
1990     UIEXT_LOGI("SendBusinessDataSyncReply businessCode=%{public}u.", code);
1991     return sessionWrapper_->SendBusinessDataSyncReply(code, data, reply, subSystemId);
1992 }
1993 
SendBusinessData(UIContentBusinessCode code,const AAFwk::Want & data,BusinessDataSendType type,RSSubsystemId subSystemId)1994 bool UIExtensionPattern::SendBusinessData(
1995     UIContentBusinessCode code, const AAFwk::Want& data, BusinessDataSendType type, RSSubsystemId subSystemId)
1996 {
1997     CHECK_NULL_RETURN(sessionWrapper_, false);
1998     UIEXT_LOGI("SendBusinessData businessCode=%{public}u.", code);
1999     return sessionWrapper_->SendBusinessData(code, data, type, subSystemId);
2000 }
2001 
OnUIExtBusinessReceiveReply(UIContentBusinessCode code,const AAFwk::Want & data,std::optional<AAFwk::Want> & reply)2002 void UIExtensionPattern::OnUIExtBusinessReceiveReply(
2003     UIContentBusinessCode code, const AAFwk::Want& data, std::optional<AAFwk::Want>& reply)
2004 {
2005     UIEXT_LOGI("OnUIExtBusinessReceiveReply businessCode=%{public}u.", code);
2006     auto it = businessDataUECConsumeReplyCallbacks_.find(code);
2007     if (it == businessDataUECConsumeReplyCallbacks_.end()) {
2008         return;
2009     }
2010     auto callback = it->second;
2011     CHECK_NULL_VOID(callback);
2012     callback(data, reply);
2013 }
2014 
OnUIExtBusinessReceive(UIContentBusinessCode code,const AAFwk::Want & data)2015 void UIExtensionPattern::OnUIExtBusinessReceive(
2016     UIContentBusinessCode code, const AAFwk::Want& data)
2017 {
2018     UIEXT_LOGI("OnUIExtBusinessReceive businessCode=%{public}u.", code);
2019     auto it = businessDataUECConsumeCallbacks_.find(code);
2020     if (it == businessDataUECConsumeCallbacks_.end()) {
2021         return;
2022     }
2023     auto callback = it->second;
2024     CHECK_NULL_VOID(callback);
2025     callback(data);
2026 }
2027 
RegisterUIExtBusinessConsumeReplyCallback(UIContentBusinessCode code,BusinessDataUECConsumeReplyCallback callback)2028 void UIExtensionPattern::RegisterUIExtBusinessConsumeReplyCallback(
2029     UIContentBusinessCode code, BusinessDataUECConsumeReplyCallback callback)
2030 {
2031     UIEXT_LOGI("RegisterUIExtBusinessConsumeReplyCallback businessCode=%{public}u.", code);
2032     businessDataUECConsumeReplyCallbacks_.try_emplace(code, callback);
2033 }
2034 
RegisterUIExtBusinessConsumeCallback(UIContentBusinessCode code,BusinessDataUECConsumeCallback callback)2035 void UIExtensionPattern::RegisterUIExtBusinessConsumeCallback(
2036     UIContentBusinessCode code, BusinessDataUECConsumeCallback callback)
2037 {
2038     UIEXT_LOGI("RegisterUIExtBusinessConsumeCallback businessCode=%{public}u.", code);
2039     businessDataUECConsumeCallbacks_.try_emplace(code, callback);
2040 }
2041 
SetOnDrawReadyCallback(const std::function<void ()> && callback)2042 void UIExtensionPattern::SetOnDrawReadyCallback(const std::function<void()>&& callback)
2043 {
2044     onDrawReadyCallback_ = std::move(callback);
2045 }
2046 
FireOnDrawReadyCallback()2047 void UIExtensionPattern::FireOnDrawReadyCallback()
2048 {
2049     ReplacePlaceholderByContent();
2050     if (onDrawReadyCallback_) {
2051         onDrawReadyCallback_();
2052     }
2053 }
2054 
NotifyHostWindowMode()2055 void UIExtensionPattern::NotifyHostWindowMode()
2056 {
2057     auto container = Platform::AceContainer::GetContainer(instanceId_);
2058     CHECK_NULL_VOID(container);
2059     auto mode = container->GetWindowMode();
2060     NotifyHostWindowMode(mode);
2061 }
2062 
NotifyHostWindowMode(Rosen::WindowMode mode)2063 void UIExtensionPattern::NotifyHostWindowMode(Rosen::WindowMode mode)
2064 {
2065     UIEXT_LOGI("NotifyHostWindowMode: instanceId = %{public}d, followStrategy = %{public}d, mode = %{public}d",
2066         instanceId_, isWindowModeFollowHost_, static_cast<int32_t>(mode));
2067     CHECK_NULL_VOID(sessionWrapper_);
2068     if (isWindowModeFollowHost_ && mode != Rosen::WindowMode::WINDOW_MODE_UNDEFINED) {
2069         int32_t windowMode = static_cast<int32_t>(mode);
2070         sessionWrapper_->NotifyHostWindowMode(windowMode);
2071     }
2072 }
2073 
IsAncestorNodeGeometryChange(FrameNodeChangeInfoFlag flag)2074 bool UIExtensionPattern::IsAncestorNodeGeometryChange(FrameNodeChangeInfoFlag flag)
2075 {
2076     return ((flag & FRAME_NODE_CHANGE_GEOMETRY_CHANGE) == FRAME_NODE_CHANGE_GEOMETRY_CHANGE);
2077 }
2078 
IsAncestorNodeTransformChange(FrameNodeChangeInfoFlag flag)2079 bool UIExtensionPattern::IsAncestorNodeTransformChange(FrameNodeChangeInfoFlag flag)
2080 {
2081     return ((flag & FRAME_NODE_CHANGE_TRANSFORM_CHANGE) == FRAME_NODE_CHANGE_TRANSFORM_CHANGE);
2082 }
2083 
OnFrameNodeChanged(FrameNodeChangeInfoFlag flag)2084 void UIExtensionPattern::OnFrameNodeChanged(FrameNodeChangeInfoFlag flag)
2085 {
2086     if (IsAncestorNodeGeometryChange(flag)) {
2087         DispatchDisplayArea();
2088     }
2089     if (!(IsAncestorNodeTransformChange(flag) || IsAncestorNodeGeometryChange(flag))) {
2090         return;
2091     }
2092     TransferAccessibilityRectInfo();
2093 }
2094 
GetAccessibilityRectInfo() const2095 AccessibilityParentRectInfo UIExtensionPattern::GetAccessibilityRectInfo() const
2096 {
2097     ACE_SCOPED_TRACE("GetAccessibilityRectInfo");
2098     AccessibilityParentRectInfo rectInfo;
2099     auto host = GetHost();
2100     CHECK_NULL_RETURN(host, rectInfo);
2101     auto pipeline = host->GetContextRefPtr();
2102     if (pipeline) {
2103         auto accessibilityManager = pipeline->GetAccessibilityManager();
2104         if (accessibilityManager) {
2105             return accessibilityManager->GetTransformRectInfoRelativeToWindow(host, pipeline);
2106         }
2107     }
2108     auto rect = host->GetTransformRectRelativeToWindow(true);
2109     VectorF finalScale = host->GetTransformScaleRelativeToWindow();
2110     rectInfo.left = static_cast<int32_t>(rect.Left());
2111     rectInfo.top = static_cast<int32_t>(rect.Top());
2112     rectInfo.scaleX = finalScale.x;
2113     rectInfo.scaleY = finalScale.y;
2114     return rectInfo;
2115 }
2116 
2117 // Once enter this function, must calculate and transfer data to provider
TransferAccessibilityRectInfo(bool isForce)2118 void UIExtensionPattern::TransferAccessibilityRectInfo(bool isForce)
2119 {
2120     if (!(isForce || AceApplicationInfo::GetInstance().IsAccessibilityEnabled())) {
2121         return;
2122     }
2123     auto parentRectInfo = GetAccessibilityRectInfo();
2124     AAFwk::Want data;
2125     data.SetParam("left", parentRectInfo.left);
2126     data.SetParam("top", parentRectInfo.top);
2127     data.SetParam("scaleX", parentRectInfo.scaleX);
2128     data.SetParam("scaleY", parentRectInfo.scaleY);
2129     data.SetParam("centerX", parentRectInfo.rotateTransform.centerX);
2130     data.SetParam("centerY", parentRectInfo.rotateTransform.centerY);
2131     data.SetParam("innerCenterX", parentRectInfo.rotateTransform.innerCenterX);
2132     data.SetParam("innerCenterY", parentRectInfo.rotateTransform.innerCenterY);
2133     data.SetParam("rotateDegree", parentRectInfo.rotateTransform.rotateDegree);
2134     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
2135         "UEC Transform rect param[scaleX:%{public}f, scaleY:%{public}f], rotateDegree: %{public}d.",
2136         parentRectInfo.scaleX, parentRectInfo.scaleY, parentRectInfo.rotateTransform.rotateDegree);
2137     SendBusinessData(UIContentBusinessCode::TRANSFORM_PARAM, data, BusinessDataSendType::ASYNC);
2138 }
2139 
UpdateWMSUIExtProperty(UIContentBusinessCode code,const AAFwk::Want & data,RSSubsystemId subSystemId)2140 void UIExtensionPattern::UpdateWMSUIExtProperty(
2141     UIContentBusinessCode code, const AAFwk::Want& data, RSSubsystemId subSystemId)
2142 {
2143     if (state_ != AbilityState::FOREGROUND) {
2144         UIEXT_LOGI("UEC UpdatWMSUIExtProperty state=%{public}s.", ToString(state_));
2145         return;
2146     }
2147     SendBusinessData(code, data, BusinessDataSendType::ASYNC, subSystemId);
2148 }
2149 } // namespace OHOS::Ace::NG
2150