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