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