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
331 CHECK_NULL_VOID(sessionWrapper_);
332 UIEXT_LOGI("The current state is '%{public}s' when UpdateWant, needCheck: '%{public}d'.",
333 ToString(state_), needCheckWindowSceneId_);
334 bool isBackground = state_ == AbilityState::BACKGROUND;
335 // Prohibit rebuilding the session unless the Want is updated.
336 if (sessionWrapper_->IsSessionValid()) {
337 auto sessionWant = sessionWrapper_->GetWant();
338 if (sessionWant == nullptr) {
339 UIEXT_LOGW("The sessionWrapper want is nullptr.");
340 return;
341 }
342 if (sessionWant->IsEquals(want)) {
343 return;
344 }
345 UIEXT_LOGI("The old want bundle = %{public}s, ability = %{public}s",
346 sessionWant->GetElement().GetBundleName().c_str(), sessionWant->GetElement().GetAbilityName().c_str());
347 auto host = GetHost();
348 CHECK_NULL_VOID(host);
349 host->RemoveChildAtIndex(0);
350 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
351 SetCurPlaceholderType(PlaceholderType::NONE);
352 NotifyDestroy();
353 // reset callback, in order to register childtree call back again when onConnect to new ability
354 ResetAccessibilityChildTreeCallback();
355 }
356
357 isKeyAsync_ = want.GetBoolParam(ABILITY_KEY_ASYNC, false);
358 UIExtensionUsage uIExtensionUsage = GetUIExtensionUsage(want);
359 usage_ = uIExtensionUsage;
360 UIEXT_LOGI("The ability KeyAsync %{public}d, uIExtensionUsage: %{public}u.",
361 isKeyAsync_, uIExtensionUsage);
362 MountPlaceholderNode(PlaceholderType::INITIAL);
363 SessionConfig config;
364 config.isAsyncModalBinding = isAsyncModalBinding_;
365 config.uiExtensionUsage = uIExtensionUsage;
366 sessionWrapper_->CreateSession(want, config);
367 if (isBackground) {
368 UIEXT_LOGW("Unable to StartUiextensionAbility while in the background.");
369 return;
370 }
371 auto container = Platform::AceContainer::GetContainer(instanceId_);
372 CHECK_NULL_VOID(container);
373 if (needCheckWindowSceneId_ && container->IsScenceBoardWindow() &&
374 uIExtensionUsage != UIExtensionUsage::MODAL && !hasMountToParent_) {
375 needReNotifyForeground_ = true;
376 UIEXT_LOGI("Should NotifyForeground after MountToParent.");
377 return;
378 }
379 NotifyForeground();
380 }
381
IsModalUec()382 bool UIExtensionPattern::IsModalUec()
383 {
384 return usage_ == UIExtensionUsage::MODAL;
385 }
386
IsForeground()387 bool UIExtensionPattern::IsForeground()
388 {
389 return state_ == AbilityState::FOREGROUND;
390 }
391
GetUIExtensionUsage(const AAFwk::Want & want)392 UIExtensionUsage UIExtensionPattern::GetUIExtensionUsage(const AAFwk::Want& want)
393 {
394 if (sessionType_ == SessionType::EMBEDDED_UI_EXTENSION) {
395 return UIExtensionUsage::EMBEDDED;
396 }
397
398 if (isModal_) {
399 return UIExtensionUsage::MODAL;
400 }
401
402 bool wantParamModal = want.GetBoolParam(ABILITY_KEY_IS_MODAL, false);
403 auto bundleName = want.GetElement().GetBundleName();
404 bool startWithAtomicService = StartWith(bundleName, ATOMIC_SERVICE_PREFIX);
405 if (wantParamModal && startWithAtomicService) {
406 return UIExtensionUsage::MODAL;
407 }
408
409 return UIExtensionUsage::EMBEDDED;
410 }
411
OnConnect()412 void UIExtensionPattern::OnConnect()
413 {
414 CHECK_RUN_ON(UI);
415 CHECK_NULL_VOID(sessionWrapper_);
416 UIEXT_LOGI("The session is connected and the current state is '%{public}s'.", ToString(state_));
417 ContainerScope scope(instanceId_);
418 contentNode_ = FrameNode::CreateFrameNode(V2::UI_EXTENSION_SURFACE_TAG,
419 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<UIExtensionSurfacePattern>());
420 contentNode_->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
421 contentNode_->SetHitTestMode(HitTestMode::HTMNONE);
422 auto host = GetHost();
423 CHECK_NULL_VOID(host);
424 auto&& opts = host->GetLayoutProperty()->GetSafeAreaExpandOpts();
425 if (opts && opts->Expansive()) {
426 contentNode_->GetLayoutProperty()->UpdateSafeAreaExpandOpts(*opts);
427 contentNode_->MarkModifyDone();
428 }
429 auto context = AceType::DynamicCast<NG::RosenRenderContext>(contentNode_->GetRenderContext());
430 CHECK_NULL_VOID(context);
431 auto surfaceNode = sessionWrapper_->GetSurfaceNode();
432 if (!surfaceNode) {
433 UIEXT_LOGE("Get surfaceNode from session is null.");
434 return;
435 }
436 context->SetRSNode(surfaceNode);
437 RemovePlaceholderNode();
438 host->AddChild(contentNode_, 0);
439 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
440 surfaceNode->CreateNodeInRenderThread();
441 surfaceNode->SetForeground(usage_ == UIExtensionUsage::MODAL);
442 FireOnRemoteReadyCallback();
443 auto focusHub = host->GetFocusHub();
444 if ((usage_ == UIExtensionUsage::MODAL) && focusHub) {
445 focusHub->RequestFocusImmediately();
446 }
447 bool isFocused = focusHub && focusHub->IsCurrentFocus();
448 RegisterVisibleAreaChange();
449 DispatchFocusState(isFocused);
450 DispatchFollowHostDensity(GetDensityDpi());
451 auto pipeline = host->GetContextRefPtr();
452 CHECK_NULL_VOID(pipeline);
453 auto uiExtensionManager = pipeline->GetUIExtensionManager();
454 uiExtensionManager->AddAliveUIExtension(host->GetId(), WeakClaim(this));
455 if (isFocused || (usage_ == UIExtensionUsage::MODAL)) {
456 uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
457 }
458 InitializeAccessibility();
459 ReDispatchDisplayArea();
460 }
461
ReplacePlaceholderByContent()462 void UIExtensionPattern::ReplacePlaceholderByContent()
463 {
464 CHECK_RUN_ON(UI);
465 if (!IsShowPlaceholder()) {
466 return;
467 }
468 RemovePlaceholderNode();
469 auto host = GetHost();
470 CHECK_NULL_VOID(host);
471 host->AddChild(contentNode_, 0);
472 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
473 }
474
OnAreaUpdated()475 void UIExtensionPattern::OnAreaUpdated()
476 {
477 PostDelayRemovePlaceholder(REMOVE_PLACEHOLDER_DELAY_TIME);
478 }
479
RegisterWindowSceneVisibleChangeCallback(const RefPtr<Pattern> & windowScenePattern)480 void UIExtensionPattern::RegisterWindowSceneVisibleChangeCallback(
481 const RefPtr<Pattern>& windowScenePattern)
482 {
483 auto systemWindowScene = AceType::DynamicCast<SystemWindowScene>(windowScenePattern);
484 CHECK_NULL_VOID(systemWindowScene);
485 auto host = GetHost();
486 CHECK_NULL_VOID(host);
487 auto callback = [weak = WeakClaim(this)](bool visible) {
488 auto pattern = weak.Upgrade();
489 if (pattern) {
490 pattern->OnWindowSceneVisibleChange(visible);
491 }
492 };
493 systemWindowScene->RegisterVisibleChangeCallback(host->GetId(), callback);
494 weakSystemWindowScene_ = systemWindowScene;
495 UIEXT_LOGI("RegisterWindowSceneVisibleChangeCallback %{public}d.", host->GetId());
496 }
497
UnRegisterWindowSceneVisibleChangeCallback(int32_t nodeId)498 void UIExtensionPattern::UnRegisterWindowSceneVisibleChangeCallback(int32_t nodeId)
499 {
500 auto pattern = weakSystemWindowScene_.Upgrade();
501 CHECK_NULL_VOID(pattern);
502 auto systemWindowScene = AceType::DynamicCast<SystemWindowScene>(pattern);
503 CHECK_NULL_VOID(systemWindowScene);
504 systemWindowScene->UnRegisterVisibleChangeCallback(nodeId);
505 UIEXT_LOGI("UnRegisterWindowSceneVisibleChangeCallback %{public}d.", nodeId);
506 }
507
OnWindowSceneVisibleChange(bool visible)508 void UIExtensionPattern::OnWindowSceneVisibleChange(bool visible)
509 {
510 UIEXT_LOGI("OnWindowSceneVisibleChange %{public}d.", visible);
511 if (!visible) {
512 OnWindowHide();
513 }
514 }
515
PostDelayRemovePlaceholder(uint32_t delay)516 void UIExtensionPattern::PostDelayRemovePlaceholder(uint32_t delay)
517 {
518 ContainerScope scope(instanceId_);
519 auto taskExecutor = Container::CurrentTaskExecutor();
520 CHECK_NULL_VOID(taskExecutor);
521 taskExecutor->PostDelayedTask(
522 [weak = WeakClaim(this)]() {
523 auto pattern = weak.Upgrade();
524 CHECK_NULL_VOID(pattern);
525 pattern->ReplacePlaceholderByContent();
526 },
527 TaskExecutor::TaskType::UI, delay, "ArkUIUIExtensionRemovePlaceholder");
528 }
529
OnExtensionEvent(UIExtCallbackEventId eventId)530 void UIExtensionPattern::OnExtensionEvent(UIExtCallbackEventId eventId)
531 {
532 CHECK_RUN_ON(UI);
533 ContainerScope scope(instanceId_);
534 switch (eventId) {
535 case UIExtCallbackEventId::ON_AREA_CHANGED:
536 OnAreaUpdated();
537 break;
538 case UIExtCallbackEventId::ON_UEA_ACCESSIBILITY_READY:
539 OnUeaAccessibilityEventAsync();
540 break;
541 }
542 }
543
OnUeaAccessibilityEventAsync()544 void UIExtensionPattern::OnUeaAccessibilityEventAsync()
545 {
546 auto frameNode = frameNode_.Upgrade();
547 CHECK_NULL_VOID(frameNode);
548 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
549 CHECK_NULL_VOID(accessibilityProperty);
550 if ((accessibilityChildTreeCallback_ != nullptr) && (accessibilityProperty->GetChildTreeId() != -1)) {
551 UIEXT_LOGI("uec need notify register accessibility again %{public}d, %{public}d.",
552 accessibilityProperty->GetChildWindowId(), accessibilityProperty->GetChildTreeId());
553 ResetAccessibilityChildTreeCallback();
554 InitializeAccessibility();
555 }
556 }
557
GetSizeChangeReason()558 PlaceholderType UIExtensionPattern::GetSizeChangeReason()
559 {
560 CHECK_NULL_RETURN(sessionWrapper_, PlaceholderType::NONE);
561 if (IsFoldStatusChanged()) {
562 SetFoldStatusChanged(false);
563 return PlaceholderType::FOLD_TO_EXPAND;
564 }
565 if (IsRotateStatusChanged()) {
566 SetRotateStatusChanged(false);
567 return PlaceholderType::ROTATION;
568 }
569 return PlaceholderType::UNDEFINED;
570 }
571
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)572 void UIExtensionPattern::OnAccessibilityEvent(
573 const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset)
574 {
575 UIEXT_LOGI("The accessibility event is reported and the current state is '%{public}s'.", ToString(state_));
576 ContainerScope scope(instanceId_);
577 auto ngPipeline = NG::PipelineContext::GetCurrentContext();
578 CHECK_NULL_VOID(ngPipeline);
579 uiExtensionOffset = uiExtensionId_ * NG::UI_EXTENSION_OFFSET_MAX + uiExtensionOffset;
580 auto frontend = ngPipeline->GetFrontend();
581 CHECK_NULL_VOID(frontend);
582 auto accessibilityManager = frontend->GetAccessibilityManager();
583 CHECK_NULL_VOID(accessibilityManager);
584 accessibilityManager->SendExtensionAccessibilityEvent(info, uiExtensionOffset);
585 }
586
OnDisconnect(bool isAbnormal)587 void UIExtensionPattern::OnDisconnect(bool isAbnormal)
588 {
589 CHECK_RUN_ON(UI);
590 UIEXT_LOGI("The session is disconnected and the current state is '%{public}s'.", ToString(state_));
591 auto host = GetHost();
592 CHECK_NULL_VOID(host);
593 host->RemoveChildAtIndex(0);
594 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
595 SetCurPlaceholderType(PlaceholderType::NONE);
596 }
597
OnSyncGeometryNode(const DirtySwapConfig & config)598 void UIExtensionPattern::OnSyncGeometryNode(const DirtySwapConfig& config)
599 {
600 if (needReNotifyForeground_) {
601 needReNotifyForeground_ = false;
602 UIEXT_LOGI("NotifyForeground onSyncGeometryNode first.");
603 NotifyForeground();
604 needReDispatchDisplayArea_ = true;
605 }
606 DispatchDisplayArea(true);
607 }
608
ReDispatchDisplayArea()609 void UIExtensionPattern::ReDispatchDisplayArea()
610 {
611 if (needReDispatchDisplayArea_) {
612 UIEXT_LOGI("ReDispatchDisplayArea.");
613 DispatchDisplayArea(true);
614 needReDispatchDisplayArea_ = false;
615 }
616 }
617
OnWindowShow()618 void UIExtensionPattern::OnWindowShow()
619 {
620 UIEXT_LOGI("The window is being shown and the component is %{public}s.", isVisible_ ? "visible" : "invisible");
621 if (isVisible_) {
622 NotifyForeground();
623 }
624 }
625
OnWindowHide()626 void UIExtensionPattern::OnWindowHide()
627 {
628 UIEXT_LOGI("The window is being hidden and the component is %{public}s, state is '%{public}s.",
629 isVisible_ ? "visible" : "invisible", ToString(state_));
630 if (isVisible_) {
631 NotifyBackground();
632 } else if (state_ == AbilityState::FOREGROUND) {
633 NotifyBackground(false);
634 }
635 }
636
OnWindowSizeChanged(int32_t,int32_t,WindowSizeChangeReason type)637 void UIExtensionPattern::OnWindowSizeChanged(int32_t /*width*/, int32_t /*height*/, WindowSizeChangeReason type)
638 {
639 if (WindowSizeChangeReason::ROTATION == type) {
640 SetRotateStatusChanged(true);
641 }
642 }
643
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)644 void UIExtensionPattern::NotifySizeChangeReason(
645 WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
646 {
647 CHECK_NULL_VOID(sessionWrapper_);
648 sessionWrapper_->NotifySizeChangeReason(type, rsTransaction);
649 }
650
OnExtensionDetachToDisplay()651 void UIExtensionPattern::OnExtensionDetachToDisplay()
652 {
653 if (contentNode_ == nullptr) {
654 UIEXT_LOGW("ContentNode is null when OnExtensionDetachToDisplay.");
655 return;
656 }
657
658 UIEXT_LOGI("OnExtensionDetachToDisplay");
659 auto host = GetHost();
660 CHECK_NULL_VOID(host);
661 host->RemoveChild(contentNode_);
662 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
663 }
664
NotifyForeground()665 void UIExtensionPattern::NotifyForeground()
666 {
667 if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::FOREGROUND) {
668 UIEXT_LOGI("The state is changing from '%{public}s' to 'FOREGROUND'.", ToString(state_));
669 state_ = AbilityState::FOREGROUND;
670 sessionWrapper_->NotifyForeground();
671 }
672 }
673
NotifyBackground(bool isHandleError)674 void UIExtensionPattern::NotifyBackground(bool isHandleError)
675 {
676 if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ == AbilityState::FOREGROUND) {
677 UIEXT_LOGI("The state is changing from '%{public}s' to 'BACKGROUND'.", ToString(state_));
678 state_ = AbilityState::BACKGROUND;
679 sessionWrapper_->NotifyBackground(isHandleError);
680 }
681 }
682
NotifyDestroy()683 void UIExtensionPattern::NotifyDestroy()
684 {
685 if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::DESTRUCTION &&
686 state_ != AbilityState::NONE) {
687 UIEXT_LOGI("The state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
688 state_ = AbilityState::DESTRUCTION;
689 sessionWrapper_->NotifyDestroy();
690 sessionWrapper_->DestroySession();
691 }
692 }
693
OnAttachToFrameNode()694 void UIExtensionPattern::OnAttachToFrameNode()
695 {
696 ContainerScope scope(instanceId_);
697 auto pipeline = PipelineContext::GetCurrentContext();
698 CHECK_NULL_VOID(pipeline);
699 auto host = GetHost();
700 CHECK_NULL_VOID(host);
701 auto eventHub = host->GetEventHub<EventHub>();
702 CHECK_NULL_VOID(eventHub);
703 OnAreaChangedFunc onAreaChangedFunc = [weak = WeakClaim(this)](
704 const RectF& oldRect,
705 const OffsetF& oldOrigin,
706 const RectF& rect,
707 const OffsetF& origin) {
708 auto pattern = weak.Upgrade();
709 CHECK_NULL_VOID(pattern);
710 pattern->DispatchDisplayArea();
711 };
712 eventHub->AddInnerOnAreaChangedCallback(host->GetId(), std::move(onAreaChangedFunc));
713 pipeline->AddOnAreaChangeNode(host->GetId());
714 pipeline->AddWindowSizeChangeCallback(host->GetId());
715 surfacePositionCallBackId_ =
716 pipeline->RegisterSurfacePositionChangedCallback([weak = WeakClaim(this)](int32_t, int32_t) {
717 auto pattern = weak.Upgrade();
718 CHECK_NULL_VOID(pattern);
719 pattern->DispatchDisplayArea(true);
720 });
721 foldDisplayCallBackId_ =
722 pipeline->RegisterFoldDisplayModeChangedCallback([weak = WeakClaim(this)](FoldDisplayMode foldDisplayMode) {
723 auto pattern = weak.Upgrade();
724 CHECK_NULL_VOID(pattern);
725 pattern->SetFoldStatusChanged(true);
726 });
727 UIEXT_LOGI("OnAttachToFrameNode");
728 }
729
OnDetachFromFrameNode(FrameNode * frameNode)730 void UIExtensionPattern::OnDetachFromFrameNode(FrameNode* frameNode)
731 {
732 auto id = frameNode->GetId();
733 UnRegisterWindowSceneVisibleChangeCallback(id);
734 ContainerScope scope(instanceId_);
735 auto pipeline = PipelineContext::GetCurrentContext();
736 CHECK_NULL_VOID(pipeline);
737 pipeline->RemoveOnAreaChangeNode(id);
738 pipeline->RemoveWindowSizeChangeCallback(id);
739 pipeline->RemoveWindowStateChangedCallback(id);
740 pipeline->UnregisterSurfacePositionChangedCallback(surfacePositionCallBackId_);
741 pipeline->UnRegisterFoldDisplayModeChangedCallback(foldDisplayCallBackId_);
742 }
743
OnModifyDone()744 void UIExtensionPattern::OnModifyDone()
745 {
746 Pattern::OnModifyDone();
747 auto host = GetHost();
748 CHECK_NULL_VOID(host);
749 auto hub = host->GetEventHub<EventHub>();
750 CHECK_NULL_VOID(hub);
751 auto gestureHub = hub->GetOrCreateGestureEventHub();
752 CHECK_NULL_VOID(gestureHub);
753 InitTouchEvent(gestureHub);
754 auto inputHub = hub->GetOrCreateInputEventHub();
755 CHECK_NULL_VOID(inputHub);
756 InitMouseEvent(inputHub);
757 InitHoverEvent(inputHub);
758 auto focusHub = host->GetFocusHub();
759 CHECK_NULL_VOID(focusHub);
760 InitKeyEvent(focusHub);
761 }
762
InitKeyEvent(const RefPtr<FocusHub> & focusHub)763 void UIExtensionPattern::InitKeyEvent(const RefPtr<FocusHub>& focusHub)
764 {
765 focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
766 auto pattern = weak.Upgrade();
767 if (pattern) {
768 pattern->HandleFocusEvent();
769 }
770 });
771
772 focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
773 auto pattern = weak.Upgrade();
774 if (pattern) {
775 pattern->HandleBlurEvent();
776 }
777 });
778
779 focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
780 auto pattern = weak.Upgrade();
781 if (pattern) {
782 pattern->DispatchFocusActiveEvent(false);
783 }
784 });
785 focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
786 auto pattern = weak.Upgrade();
787 if (pattern) {
788 pattern->DispatchFocusActiveEvent(true);
789 return true;
790 }
791 return false;
792 });
793
794 focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
795 auto pattern = wp.Upgrade();
796 if (pattern) {
797 return pattern->HandleKeyEvent(event);
798 }
799 return false;
800 });
801 }
802
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)803 void UIExtensionPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
804 {
805 if (touchEvent_) {
806 return;
807 }
808 auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
809 auto pattern = weak.Upgrade();
810 if (pattern) {
811 pattern->HandleTouchEvent(info);
812 }
813 };
814 if (touchEvent_) {
815 gestureHub->RemoveTouchEvent(touchEvent_);
816 }
817 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
818 gestureHub->AddTouchEvent(touchEvent_);
819 }
820
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)821 void UIExtensionPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
822 {
823 if (mouseEvent_) {
824 return;
825 }
826 auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
827 auto pattern = weak.Upgrade();
828 if (pattern) {
829 pattern->HandleMouseEvent(info);
830 }
831 };
832 if (mouseEvent_) {
833 inputHub->RemoveOnMouseEvent(mouseEvent_);
834 }
835 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
836 inputHub->AddOnMouseEvent(mouseEvent_);
837 }
838
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)839 void UIExtensionPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
840 {
841 if (hoverEvent_) {
842 return;
843 }
844 auto callback = [weak = WeakClaim(this)](bool isHover) {
845 auto pattern = weak.Upgrade();
846 if (pattern) {
847 pattern->HandleHoverEvent(isHover);
848 }
849 };
850 if (hoverEvent_) {
851 inputHub->RemoveOnHoverEvent(hoverEvent_);
852 }
853 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
854 inputHub->AddOnHoverEvent(hoverEvent_);
855 }
856
HandleKeyEvent(const KeyEvent & event)857 bool UIExtensionPattern::HandleKeyEvent(const KeyEvent& event)
858 {
859 return DispatchKeyEventSync(event);
860 }
861
HandleFocusEvent()862 void UIExtensionPattern::HandleFocusEvent()
863 {
864 auto pipeline = PipelineContext::GetCurrentContext();
865 CHECK_NULL_VOID(pipeline);
866 if (canFocusSendToUIExtension_) {
867 if (pipeline->GetIsFocusActive()) {
868 DispatchFocusActiveEvent(true);
869 }
870
871 DispatchFocusState(true);
872 needReSendFocusToUIExtension_ = false;
873 } else {
874 needReSendFocusToUIExtension_ = true;
875 }
876
877 canFocusSendToUIExtension_ = true;
878 auto uiExtensionManager = pipeline->GetUIExtensionManager();
879 uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
880 }
881
HandleBlurEvent()882 void UIExtensionPattern::HandleBlurEvent()
883 {
884 DispatchFocusActiveEvent(false);
885 DispatchFocusState(false);
886 auto pipeline = PipelineContext::GetCurrentContext();
887 CHECK_NULL_VOID(pipeline);
888 auto uiExtensionManager = pipeline->GetUIExtensionManager();
889 uiExtensionManager->RegisterUIExtensionInFocus(nullptr, nullptr);
890 }
891
HandleTouchEvent(const TouchEventInfo & info)892 void UIExtensionPattern::HandleTouchEvent(const TouchEventInfo& info)
893 {
894 if (info.GetSourceDevice() != SourceType::TOUCH) {
895 UIEXT_LOGE("The source type is not TOUCH.");
896 return;
897 }
898 const auto pointerEvent = info.GetPointerEvent();
899 if (!pointerEvent) {
900 UIEXT_LOGE("The pointerEvent is empty.");
901 return;
902 }
903 auto host = GetHost();
904 CHECK_NULL_VOID(host);
905 auto pipeline = PipelineBase::GetCurrentContext();
906 CHECK_NULL_VOID(pipeline);
907 AceExtraInputData::InsertInterpolatePoints(info);
908 std::shared_ptr<MMI::PointerEvent> newPointerEvent = std::make_shared<MMI::PointerEvent>(*pointerEvent);
909 SetPointerEventExtraProperty(newPointerEvent, pointerEvent);
910 Platform::CalculatePointerEvent(newPointerEvent, host);
911 auto focusHub = host->GetFocusHub();
912 CHECK_NULL_VOID(focusHub);
913 bool ret = true;
914 if (pipeline->IsWindowFocused() && !focusHub->IsCurrentFocus()) {
915 canFocusSendToUIExtension_ = false;
916 ret = focusHub->RequestFocusImmediately();
917 if (!ret) {
918 canFocusSendToUIExtension_ = true;
919 UIEXT_LOGW("RequestFocusImmediately failed when HandleTouchEvent.");
920 }
921 }
922 focusState_ = pipeline->IsWindowFocused();
923 DispatchPointerEvent(newPointerEvent);
924 if (pipeline->IsWindowFocused() && needReSendFocusToUIExtension_ &&
925 newPointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) {
926 HandleFocusEvent();
927 needReSendFocusToUIExtension_ = false;
928 }
929 }
930
HandleMouseEvent(const MouseInfo & info)931 void UIExtensionPattern::HandleMouseEvent(const MouseInfo& info)
932 {
933 if (info.GetSourceDevice() != SourceType::MOUSE) {
934 return;
935 }
936 if (info.GetPullAction() == MouseAction::PULL_MOVE || info.GetPullAction() == MouseAction::PULL_UP) {
937 return;
938 }
939 const auto pointerEvent = info.GetPointerEvent();
940 CHECK_NULL_VOID(pointerEvent);
941 lastPointerEvent_ = pointerEvent;
942 auto host = GetHost();
943 CHECK_NULL_VOID(host);
944 Platform::CalculatePointerEvent(pointerEvent, host);
945 if (info.GetAction() == MouseAction::PRESS) {
946 auto hub = host->GetFocusHub();
947 CHECK_NULL_VOID(hub);
948 hub->RequestFocusImmediately();
949 }
950 DispatchPointerEvent(pointerEvent);
951 }
952
HandleHoverEvent(bool isHover)953 void UIExtensionPattern::HandleHoverEvent(bool isHover)
954 {
955 if (isHover) {
956 return;
957 }
958 CHECK_NULL_VOID(lastPointerEvent_);
959 lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
960 DispatchPointerEvent(lastPointerEvent_);
961 }
962
DispatchKeyEvent(const KeyEvent & event)963 void UIExtensionPattern::DispatchKeyEvent(const KeyEvent& event)
964 {
965 CHECK_NULL_VOID(event.rawKeyEvent);
966 CHECK_NULL_VOID(sessionWrapper_);
967 sessionWrapper_->NotifyKeyEventAsync(event.rawKeyEvent);
968 }
969
DispatchKeyEventSync(const KeyEvent & event)970 bool UIExtensionPattern::DispatchKeyEventSync(const KeyEvent& event)
971 {
972 CHECK_NULL_RETURN(sessionWrapper_, false);
973 if (isKeyAsync_) {
974 sessionWrapper_->NotifyKeyEventAsync(event.rawKeyEvent, false);
975 return true;
976 }
977
978 return sessionWrapper_->NotifyKeyEventSync(event.rawKeyEvent, event.isPreIme);
979 }
980
DispatchFocusActiveEvent(bool isFocusActive)981 void UIExtensionPattern::DispatchFocusActiveEvent(bool isFocusActive)
982 {
983 CHECK_NULL_VOID(sessionWrapper_);
984 sessionWrapper_->NotifyFocusEventAsync(isFocusActive);
985 }
986
DispatchFocusState(bool focusState)987 void UIExtensionPattern::DispatchFocusState(bool focusState)
988 {
989 CHECK_NULL_VOID(sessionWrapper_);
990 sessionWrapper_->NotifyFocusStateAsync(focusState);
991 }
992
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)993 void UIExtensionPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
994 {
995 if (!pointerEvent) {
996 UIEXT_LOGE("DispatchPointerEvent pointerEvent is null.");
997 return;
998 }
999 if (!sessionWrapper_) {
1000 UIEXT_LOGE("DispatchPointerEvent sessionWrapper is null.");
1001 return;
1002 }
1003 sessionWrapper_->NotifyPointerEventAsync(pointerEvent);
1004 }
1005
DispatchDisplayArea(bool isForce)1006 void UIExtensionPattern::DispatchDisplayArea(bool isForce)
1007 {
1008 CHECK_NULL_VOID(sessionWrapper_);
1009 auto host = GetHost();
1010 CHECK_NULL_VOID(host);
1011 auto [displayOffset, err] = host->GetPaintRectGlobalOffsetWithTranslate();
1012 auto geometryNode = host->GetGeometryNode();
1013 CHECK_NULL_VOID(geometryNode);
1014 auto renderContext = host->GetRenderContext();
1015 CHECK_NULL_VOID(renderContext);
1016 auto displaySize = renderContext->GetPaintRectWithoutTransform().GetSize();
1017 auto displayArea = RectF(displayOffset, displaySize);
1018 bool sizeChange = displayArea_ != displayArea;
1019 if (sizeChange || isForce) {
1020 displayArea_ = displayArea;
1021 if (sizeChange) {
1022 MountPlaceholderNode(GetSizeChangeReason());
1023 }
1024 sessionWrapper_->NotifyDisplayArea(displayArea_);
1025 }
1026 }
1027
HandleDragEvent(const PointerEvent & info)1028 void UIExtensionPattern::HandleDragEvent(const PointerEvent& info)
1029 {
1030 auto pointerEvent = info.rawPointerEvent;
1031 CHECK_NULL_VOID(pointerEvent);
1032 auto host = GetHost();
1033 CHECK_NULL_VOID(host);
1034 auto pipeline = PipelineBase::GetCurrentContext();
1035 CHECK_NULL_VOID(pipeline);
1036 Platform::CalculatePointerEvent(pointerEvent, host, true);
1037 Platform::UpdatePointerAction(pointerEvent, info.action);
1038 DispatchPointerEvent(pointerEvent);
1039 }
1040
SetOnRemoteReadyCallback(const std::function<void (const RefPtr<UIExtensionProxy> &)> && callback)1041 void UIExtensionPattern::SetOnRemoteReadyCallback(const std::function<void(const RefPtr<UIExtensionProxy>&)>&& callback)
1042 {
1043 onRemoteReadyCallback_ = std::move(callback);
1044 }
1045
SetModalOnRemoteReadyCallback(const std::function<void (const std::shared_ptr<ModalUIExtensionProxy> &)> && callback)1046 void UIExtensionPattern::SetModalOnRemoteReadyCallback(
1047 const std::function<void(const std::shared_ptr<ModalUIExtensionProxy>&)>&& callback)
1048 {
1049 onModalRemoteReadyCallback_ = std::move(callback);
1050 }
1051
FireOnRemoteReadyCallback()1052 void UIExtensionPattern::FireOnRemoteReadyCallback()
1053 {
1054 UIEXT_LOGI("OnRemoteReady the current state is '%{public}s'.", ToString(state_));
1055 ContainerScope scope(instanceId_);
1056 // These two callbacks will be unified in the future.
1057 if (onRemoteReadyCallback_) {
1058 onRemoteReadyCallback_(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1059 }
1060 if (onModalRemoteReadyCallback_) {
1061 onModalRemoteReadyCallback_(std::make_shared<ModalUIExtensionProxyImpl>(sessionWrapper_));
1062 }
1063 }
1064
SetModalOnDestroy(const std::function<void ()> && callback)1065 void UIExtensionPattern::SetModalOnDestroy(const std::function<void()>&& callback)
1066 {
1067 onModalDestroy_ = std::move(callback);
1068 }
1069
FireModalOnDestroy()1070 void UIExtensionPattern::FireModalOnDestroy()
1071 {
1072 UIEXT_LOGI("ModalOnDestroy the current state is '%{public}s'.", ToString(state_));
1073 // Native modal page destroy callback
1074 if (onModalDestroy_) {
1075 ContainerScope scope(instanceId_);
1076 onModalDestroy_();
1077 }
1078 }
1079
SetOnReleaseCallback(const std::function<void (int32_t)> && callback)1080 void UIExtensionPattern::SetOnReleaseCallback(const std::function<void(int32_t)>&& callback)
1081 {
1082 onReleaseCallback_ = std::move(callback);
1083 }
1084
FireOnReleaseCallback(int32_t releaseCode)1085 void UIExtensionPattern::FireOnReleaseCallback(int32_t releaseCode)
1086 {
1087 UIEXT_LOGI("OnRelease the state is changing from '%{public}s' to 'DESTRUCTION' and releaseCode = %{public}d.",
1088 ToString(state_), releaseCode);
1089 state_ = AbilityState::DESTRUCTION;
1090 if (onReleaseCallback_) {
1091 onReleaseCallback_(releaseCode);
1092 }
1093 // Release the session.
1094 if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
1095 sessionWrapper_->OnReleaseDone();
1096 }
1097 }
1098
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)1099 void UIExtensionPattern::SetOnErrorCallback(
1100 const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
1101 {
1102 onErrorCallback_ = std::move(callback);
1103 if (lastError_.code != 0) {
1104 ErrorMsg error;
1105 std::swap(lastError_, error);
1106 FireOnErrorCallback(error.code, error.name, error.message);
1107 }
1108 }
1109
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)1110 void UIExtensionPattern::FireOnErrorCallback(int32_t code, const std::string& name, const std::string& message)
1111 {
1112 // 1. As long as the error occurs, the host believes that UIExtensionAbility has been killed.
1113 UIEXT_LOGI("OnError the state is changing from '%{public}s' to 'NONE'.", ToString(state_));
1114 state_ = AbilityState::NONE;
1115 // Release the session.
1116 if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
1117 if (!IsShowPlaceholder()) {
1118 auto host = GetHost();
1119 CHECK_NULL_VOID(host);
1120 host->RemoveChildAtIndex(0);
1121 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1122 }
1123 sessionWrapper_->NotifyDestroy(false);
1124 sessionWrapper_->DestroySession();
1125 }
1126 if (onErrorCallback_) {
1127 ContainerScope scope(instanceId_);
1128 onErrorCallback_(code, name, message);
1129 return;
1130 }
1131 lastError_ = { code, name, message };
1132 }
1133
SetOnResultCallback(const std::function<void (int32_t,const AAFwk::Want &)> && callback)1134 void UIExtensionPattern::SetOnResultCallback(const std::function<void(int32_t, const AAFwk::Want&)>&& callback)
1135 {
1136 onResultCallback_ = std::move(callback);
1137 }
1138
FireOnResultCallback(int32_t code,const AAFwk::Want & want)1139 void UIExtensionPattern::FireOnResultCallback(int32_t code, const AAFwk::Want& want)
1140 {
1141 UIEXT_LOGI("OnResult the state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
1142 if (onResultCallback_ && (state_ != AbilityState::DESTRUCTION)) {
1143 ContainerScope scope(instanceId_);
1144 onResultCallback_(code, want);
1145 }
1146 state_ = AbilityState::DESTRUCTION;
1147 }
1148
IsCompatibleOldVersion()1149 bool UIExtensionPattern::IsCompatibleOldVersion()
1150 {
1151 ContainerScope scope(instanceId_);
1152 return (sessionType_ == SessionType::UI_EXTENSION_ABILITY) && (onTerminatedCallback_ == nullptr);
1153 }
1154
SetOnTerminatedCallback(const std::function<void (int32_t,const RefPtr<WantWrap> & wantWrap)> && callback)1155 void UIExtensionPattern::SetOnTerminatedCallback(
1156 const std::function<void(int32_t, const RefPtr<WantWrap>& wantWrap)>&& callback)
1157 {
1158 onTerminatedCallback_ = std::move(callback);
1159 }
1160
FireOnTerminatedCallback(int32_t code,const RefPtr<WantWrap> & wantWrap)1161 void UIExtensionPattern::FireOnTerminatedCallback(int32_t code, const RefPtr<WantWrap>& wantWrap)
1162 {
1163 UIEXT_LOGI("OnTerminated the state is changing from '%{public}s' to 'DESTRUCTION'.", ToString(state_));
1164 if (onTerminatedCallback_ && (state_ != AbilityState::DESTRUCTION)) {
1165 ContainerScope scope(instanceId_);
1166 onTerminatedCallback_(code, wantWrap);
1167 }
1168 state_ = AbilityState::DESTRUCTION;
1169 }
1170
SetOnReceiveCallback(const std::function<void (const AAFwk::WantParams &)> && callback)1171 void UIExtensionPattern::SetOnReceiveCallback(const std::function<void(const AAFwk::WantParams&)>&& callback)
1172 {
1173 onReceiveCallback_ = std::move(callback);
1174 }
1175
FireOnReceiveCallback(const AAFwk::WantParams & params)1176 void UIExtensionPattern::FireOnReceiveCallback(const AAFwk::WantParams& params)
1177 {
1178 UIEXT_LOGI("OnReceive the current state is '%{public}s'.", ToString(state_));
1179 if (onReceiveCallback_) {
1180 ContainerScope scope(instanceId_);
1181 onReceiveCallback_(params);
1182 }
1183 }
1184
SetSyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)1185 void UIExtensionPattern::SetSyncCallbacks(
1186 const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
1187 {
1188 onSyncOnCallbackList_ = std::move(callbackList);
1189 }
1190
FireSyncCallbacks()1191 void UIExtensionPattern::FireSyncCallbacks()
1192 {
1193 UIEXT_LOGD("The size of sync callbacks = %{public}zu.", onSyncOnCallbackList_.size());
1194 ContainerScope scope(instanceId_);
1195 for (const auto& callback : onSyncOnCallbackList_) {
1196 if (callback) {
1197 callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1198 }
1199 }
1200 }
1201
SetAsyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)1202 void UIExtensionPattern::SetAsyncCallbacks(
1203 const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
1204 {
1205 onAsyncOnCallbackList_ = std::move(callbackList);
1206 }
1207
FireAsyncCallbacks()1208 void UIExtensionPattern::FireAsyncCallbacks()
1209 {
1210 UIEXT_LOGD("The size of async callbacks = %{public}zu.", onSyncOnCallbackList_.size());
1211 ContainerScope scope(instanceId_);
1212 for (const auto& callback : onAsyncOnCallbackList_) {
1213 if (callback) {
1214 callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
1215 }
1216 }
1217 }
1218
SetBindModalCallback(const std::function<void ()> && callback)1219 void UIExtensionPattern::SetBindModalCallback(const std::function<void()>&& callback)
1220 {
1221 bindModalCallback_ = std::move(callback);
1222 }
1223
FireBindModalCallback()1224 void UIExtensionPattern::FireBindModalCallback()
1225 {
1226 if (bindModalCallback_) {
1227 bindModalCallback_();
1228 }
1229 }
1230
SetDensityDpi(bool densityDpi)1231 void UIExtensionPattern::SetDensityDpi(bool densityDpi)
1232 {
1233 densityDpi_ = densityDpi;
1234 }
1235
DispatchFollowHostDensity(bool densityDpi)1236 void UIExtensionPattern::DispatchFollowHostDensity(bool densityDpi)
1237 {
1238 densityDpi_ = densityDpi;
1239 CHECK_NULL_VOID(sessionWrapper_);
1240 sessionWrapper_->SetDensityDpiImpl(densityDpi_);
1241 }
1242
OnDpiConfigurationUpdate()1243 void UIExtensionPattern::OnDpiConfigurationUpdate()
1244 {
1245 if (GetDensityDpi()) {
1246 DispatchFollowHostDensity(true);
1247 }
1248 }
1249
GetDensityDpi()1250 bool UIExtensionPattern::GetDensityDpi()
1251 {
1252 return densityDpi_;
1253 }
1254
OnVisibleChange(bool visible)1255 void UIExtensionPattern::OnVisibleChange(bool visible)
1256 {
1257 UIEXT_LOGI("The component is changing from '%{public}s' to '%{public}s'.", isVisible_ ? "visible" : "invisible",
1258 visible ? "visible" : "invisible");
1259 isVisible_ = visible;
1260 if (visible) {
1261 NotifyForeground();
1262 } else {
1263 NotifyBackground();
1264 }
1265 }
1266
InitializeAccessibility()1267 void UIExtensionPattern::InitializeAccessibility()
1268 {
1269 if (accessibilityChildTreeCallback_ != nullptr) {
1270 return;
1271 }
1272 auto instanceId = GetInstanceIdFromHost();
1273 ContainerScope scope(instanceId);
1274 auto ngPipeline = NG::PipelineContext::GetCurrentContext();
1275 CHECK_NULL_VOID(ngPipeline);
1276 auto frontend = ngPipeline->GetFrontend();
1277 CHECK_NULL_VOID(frontend);
1278 auto accessibilityManager = frontend->GetAccessibilityManager();
1279 CHECK_NULL_VOID(accessibilityManager);
1280 auto frameNode = frameNode_.Upgrade();
1281 CHECK_NULL_VOID(frameNode);
1282 int64_t accessibilityId = frameNode->GetAccessibilityId();
1283 accessibilityChildTreeCallback_ = std::make_shared<UIExtensionAccessibilityChildTreeCallback>(
1284 WeakClaim(this), accessibilityId);
1285 CHECK_NULL_VOID(accessibilityChildTreeCallback_);
1286 auto realHostWindowId = ngPipeline->GetRealHostWindowId();
1287 realHostWindowId_ = realHostWindowId;
1288 focusWindowId_ = ngPipeline->GetFocusWindowId();
1289 if (accessibilityManager->IsRegister()) {
1290 accessibilityChildTreeCallback_->OnRegister(
1291 realHostWindowId, accessibilityManager->GetTreeId());
1292 }
1293 UIEXT_LOGI("UIExtension: %{public}" PRId64 " register child tree, realHostWindowId: %{public}u",
1294 accessibilityId, realHostWindowId);
1295 accessibilityManager->RegisterAccessibilityChildTreeCallback(accessibilityId, accessibilityChildTreeCallback_);
1296 }
1297
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)1298 void UIExtensionPattern::OnAccessibilityChildTreeRegister(uint32_t windowId, int32_t treeId, int64_t accessibilityId)
1299 {
1300 UIEXT_LOGI("treeId: %{public}d, id: %{public}" PRId64, treeId, accessibilityId);
1301 if (sessionWrapper_ == nullptr) {
1302 UIEXT_LOGI("sessionWrapper_ is null");
1303 return;
1304 }
1305 sessionWrapper_->TransferAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
1306 }
1307
OnAccessibilityChildTreeDeregister()1308 void UIExtensionPattern::OnAccessibilityChildTreeDeregister()
1309 {
1310 UIEXT_LOGI("deregister accessibility child tree");
1311 if (sessionWrapper_ == nullptr) {
1312 UIEXT_LOGI("sessionWrapper_ is null");
1313 return;
1314 }
1315 sessionWrapper_->TransferAccessibilityChildTreeDeregister();
1316 }
1317
OnSetAccessibilityChildTree(int32_t childWindowId,int32_t childTreeId)1318 void UIExtensionPattern::OnSetAccessibilityChildTree(int32_t childWindowId, int32_t childTreeId)
1319 {
1320 auto frameNode = frameNode_.Upgrade();
1321 CHECK_NULL_VOID(frameNode);
1322 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
1323 if (accessibilityProperty != nullptr) {
1324 accessibilityProperty->SetChildWindowId(childWindowId);
1325 accessibilityProperty->SetChildTreeId(childTreeId);
1326 }
1327 }
1328
OnAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)1329 void UIExtensionPattern::OnAccessibilityDumpChildInfo(
1330 const std::vector<std::string>& params, std::vector<std::string>& info)
1331 {
1332 UIEXT_LOGI("dump accessibility child info");
1333 if (sessionWrapper_ == nullptr) {
1334 UIEXT_LOGI("sessionWrapper_ is null");
1335 return;
1336 }
1337 sessionWrapper_->TransferAccessibilityDumpChildInfo(params, info);
1338 }
1339
ResetAccessibilityChildTreeCallback()1340 void UIExtensionPattern::ResetAccessibilityChildTreeCallback()
1341 {
1342 CHECK_NULL_VOID(accessibilityChildTreeCallback_);
1343 auto instanceId = GetInstanceIdFromHost();
1344 ContainerScope scope(instanceId);
1345 auto ngPipeline = NG::PipelineContext::GetCurrentContext();
1346 CHECK_NULL_VOID(ngPipeline);
1347 auto frontend = ngPipeline->GetFrontend();
1348 CHECK_NULL_VOID(frontend);
1349 auto accessibilityManager = frontend->GetAccessibilityManager();
1350 CHECK_NULL_VOID(accessibilityManager);
1351 accessibilityManager->DeregisterAccessibilityChildTreeCallback(
1352 accessibilityChildTreeCallback_->GetAccessibilityId());
1353 accessibilityChildTreeCallback_.reset();
1354 accessibilityChildTreeCallback_ = nullptr;
1355 }
1356
OnMountToParentDone()1357 void UIExtensionPattern::OnMountToParentDone()
1358 {
1359 UIEXT_LOGI("OnMountToParentDone.");
1360 hasMountToParent_ = true;
1361 if (needReNotifyForeground_) {
1362 auto hostWindowNode = WindowSceneHelper::FindWindowScene(GetHost());
1363 if (hostWindowNode) {
1364 needReNotifyForeground_ = false;
1365 UIEXT_LOGI("NotifyForeground OnMountToParentDone.");
1366 NotifyForeground();
1367 } else {
1368 UIEXT_LOGI("No WindowScene when OnMountToParentDone, wait.");
1369 }
1370 }
1371 auto frameNode = frameNode_.Upgrade();
1372 CHECK_NULL_VOID(frameNode);
1373 if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
1374 UIEXT_LOGD("Frame node status is normal.");
1375 return;
1376 }
1377 auto wantWrap = GetWantWrap();
1378 CHECK_NULL_VOID(wantWrap);
1379 UpdateWant(wantWrap);
1380 SetWantWrap(nullptr);
1381 }
1382
AfterMountToParent()1383 void UIExtensionPattern::AfterMountToParent()
1384 {
1385 UIEXT_LOGI("AfterMountToParent.");
1386 hasMountToParent_ = true;
1387 if (needReNotifyForeground_) {
1388 auto hostWindowNode = WindowSceneHelper::FindWindowScene(GetHost());
1389 if (hostWindowNode) {
1390 needReNotifyForeground_ = false;
1391 UIEXT_LOGI("NotifyForeground AfterMountToParent.");
1392 NotifyForeground();
1393 } else {
1394 UIEXT_LOGI("No WindowScene when AfterMountToParent, wait.");
1395 }
1396 }
1397 }
1398
RegisterVisibleAreaChange()1399 void UIExtensionPattern::RegisterVisibleAreaChange()
1400 {
1401 auto pipeline = PipelineContext::GetCurrentContext();
1402 CHECK_NULL_VOID(pipeline);
1403 auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
1404 auto uiExtension = weak.Upgrade();
1405 CHECK_NULL_VOID(uiExtension);
1406 uiExtension->HandleVisibleAreaChange(visible, ratio);
1407 };
1408 auto host = GetHost();
1409 CHECK_NULL_VOID(host);
1410 std::vector<double> ratioList = { SHOW_START, SHOW_FULL };
1411 pipeline->AddVisibleAreaChangeNode(host, ratioList, callback, false);
1412 }
1413
HandleVisibleAreaChange(bool visible,double ratio)1414 void UIExtensionPattern::HandleVisibleAreaChange(bool visible, double ratio)
1415 {
1416 UIEXT_LOGI("HandleVisibleAreaChange visible: %{public}d, curVisible: %{public}d, "
1417 "ratio: %{public}f, displayArea: %{public}s.", visible, curVisible_,
1418 ratio, displayArea_.ToString().c_str());
1419 bool needCheckDisplayArea = NearEqual(ratio, SHOW_FULL) && curVisible_ && visible;
1420 bool curVisible = !NearEqual(ratio, SHOW_START);
1421 if (curVisible_ != curVisible) {
1422 curVisible_ = curVisible;
1423 OnVisibleChange(curVisible_);
1424 }
1425
1426 if (needCheckDisplayArea) {
1427 DispatchDisplayArea(false);
1428 }
1429 }
1430
OnLanguageConfigurationUpdate()1431 void UIExtensionPattern::OnLanguageConfigurationUpdate()
1432 {
1433 CHECK_NULL_VOID(sessionWrapper_);
1434 sessionWrapper_->NotifyConfigurationUpdate();
1435 }
1436
OnColorConfigurationUpdate()1437 void UIExtensionPattern::OnColorConfigurationUpdate()
1438 {
1439 CHECK_NULL_VOID(sessionWrapper_);
1440 sessionWrapper_->NotifyConfigurationUpdate();
1441 }
1442
GetSessionId()1443 int32_t UIExtensionPattern::GetSessionId()
1444 {
1445 return sessionWrapper_ ? sessionWrapper_->GetSessionId() : 0;
1446 }
1447
GetUiExtensionId()1448 int32_t UIExtensionPattern::GetUiExtensionId()
1449 {
1450 return uiExtensionId_;
1451 }
1452
GetNodeId()1453 int32_t UIExtensionPattern::GetNodeId()
1454 {
1455 auto host = GetHost();
1456 return host ? host->GetId() : -1;
1457 }
1458
GetInstanceId()1459 int32_t UIExtensionPattern::GetInstanceId()
1460 {
1461 return instanceId_;
1462 }
1463
GetInstanceIdFromHost()1464 int32_t UIExtensionPattern::GetInstanceIdFromHost()
1465 {
1466 auto instanceId = GetHostInstanceId();
1467 if (instanceId != instanceId_) {
1468 UIEXT_LOGW("UIExtension pattern instanceId %{public}d not equal frame node instanceId %{public}d",
1469 instanceId_, instanceId);
1470 }
1471 return instanceId;
1472 }
1473
DispatchOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)1474 void UIExtensionPattern::DispatchOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
1475 {
1476 CHECK_NULL_VOID(sessionWrapper_);
1477 sessionWrapper_->NotifyOriginAvoidArea(avoidArea, type);
1478 }
1479
SetWantWrap(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)1480 void UIExtensionPattern::SetWantWrap(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
1481 {
1482 curWant_ = wantWrap;
1483 }
1484
GetWantWrap()1485 RefPtr<OHOS::Ace::WantWrap> UIExtensionPattern::GetWantWrap()
1486 {
1487 return curWant_;
1488 }
1489
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)1490 int64_t UIExtensionPattern::WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
1491 {
1492 return uiExtensionId_ * extensionOffset + abilityId;
1493 }
1494
ToString(AbilityState state)1495 const char* UIExtensionPattern::ToString(AbilityState state)
1496 {
1497 switch (state) {
1498 case AbilityState::FOREGROUND:
1499 return "FOREGROUND";
1500 case AbilityState::BACKGROUND:
1501 return "BACKGROUND";
1502 case AbilityState::DESTRUCTION:
1503 return "DESTRUCTION";
1504 case AbilityState::NONE:
1505 default:
1506 return "NONE";
1507 }
1508 }
1509
DumpInfo()1510 void UIExtensionPattern::DumpInfo()
1511 {
1512 CHECK_NULL_VOID(sessionWrapper_);
1513 UIEXT_LOGI("Dump UIE Info In String Format");
1514 DumpLog::GetInstance().AddDesc(std::string("focusWindowId: ").append(std::to_string(focusWindowId_)));
1515 DumpLog::GetInstance().AddDesc(std::string("realHostWindowId: ").append(std::to_string(realHostWindowId_)));
1516 DumpLog::GetInstance().AddDesc(std::string("want: ").append(want_));
1517 DumpLog::GetInstance().AddDesc(std::string("displayArea: ").append(displayArea_.ToString()));
1518 DumpLog::GetInstance().AddDesc(std::string("reason: ").append(std::to_string(sessionWrapper_->GetReasonDump())));
1519 DumpLog::GetInstance().AddDesc(std::string("focusStatus: ").append(std::to_string(focusState_)));
1520 DumpLog::GetInstance().AddDesc(std::string("abilityState: ").append(ToString(state_)));
1521
1522 auto container = Platform::AceContainer::GetContainer(instanceId_);
1523 CHECK_NULL_VOID(container);
1524 std::vector<std::string> params = container->GetUieParams();
1525 // Use -nouie to choose not dump extra uie info
1526 if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1527 UIEXT_LOGI("Not Support Dump Extra UIE Info");
1528 } else {
1529 if (!container->IsUIExtensionWindow()) {
1530 params.push_back(PID_FLAG);
1531 }
1532 params.push_back(std::to_string(getpid()));
1533 std::vector<std::string> dumpInfo;
1534 sessionWrapper_->NotifyUieDump(params, dumpInfo);
1535 for (std::string info : dumpInfo) {
1536 DumpLog::GetInstance().AddDesc(std::string("UI Extension info: ").append(info));
1537 }
1538 }
1539 }
1540
DumpInfo(std::unique_ptr<JsonValue> & json)1541 void UIExtensionPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
1542 {
1543 CHECK_NULL_VOID(sessionWrapper_);
1544 UIEXT_LOGI("Dump UIE Info In Json Format");
1545 json->Put("focusWindowId: ", std::to_string(focusWindowId_).c_str());
1546 json->Put("realHostWindowId: ", std::to_string(realHostWindowId_).c_str());
1547 json->Put("want: ", want_.c_str());
1548 json->Put("displayArea: ", displayArea_.ToString().c_str());
1549 json->Put("reason: ", std::to_string(sessionWrapper_->GetReasonDump()).c_str());
1550 json->Put("focusStatus: ", std::to_string(focusState_).c_str());
1551 json->Put("abilityState: ", ToString(state_));
1552
1553 auto container = Platform::AceContainer::GetContainer(instanceId_);
1554 CHECK_NULL_VOID(container);
1555 std::vector<std::string> params = container->GetUieParams();
1556 // Use -nouie to choose not dump extra uie info
1557 if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1558 UIEXT_LOGI("Not Support Dump Extra UIE Info");
1559 } else {
1560 if (!container->IsUIExtensionWindow()) {
1561 params.push_back(PID_FLAG);
1562 }
1563 params.push_back(std::to_string(getpid()));
1564 std::vector<std::string> dumpInfo;
1565 sessionWrapper_->NotifyUieDump(params, dumpInfo);
1566 for (std::string info : dumpInfo) {
1567 json->Put("UI Extension info: ", info.c_str());
1568 }
1569 }
1570 }
1571
DumpOthers()1572 void UIExtensionPattern::DumpOthers()
1573 {
1574 CHECK_NULL_VOID(sessionWrapper_);
1575 auto container = Platform::AceContainer::GetContainer(instanceId_);
1576 CHECK_NULL_VOID(container);
1577 std::vector<std::string> params = container->GetUieParams();
1578 if (params.empty()) {
1579 return;
1580 }
1581 // Use -nouie to choose not dump extra uie info
1582 if (std::find(params.begin(), params.end(), NO_EXTRA_UIE_DUMP) != params.end()) {
1583 UIEXT_LOGI("Not Support Dump Extra UIE Info");
1584 } else {
1585 if (params.back() == "-json") {
1586 params.insert(params.end() - 1, std::to_string(getpid()));
1587 if (!container->IsUIExtensionWindow()) {
1588 params.insert(params.end() - 1, PID_FLAG);
1589 }
1590 } else {
1591 if (!container->IsUIExtensionWindow()) {
1592 params.push_back(PID_FLAG);
1593 }
1594 params.push_back(std::to_string(getpid()));
1595 }
1596 std::vector<std::string> dumpInfo;
1597 sessionWrapper_->NotifyUieDump(params, dumpInfo);
1598 for (std::string info : dumpInfo) {
1599 std::stringstream ss(info);
1600 std::string line;
1601 DumpLog::GetInstance().Print("\n------ UIExtension Dump ------");
1602 while (getline(ss, line, ';')) {
1603 DumpLog::GetInstance().Print(line);
1604 }
1605 }
1606 }
1607 }
1608 } // namespace OHOS::Ace::NG
1609