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