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