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