1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/pattern/ui_extension/ui_extension_pattern.h"
17
18 #include "key_event.h"
19 #include "pointer_event.h"
20 #include "session/host/include/extension_session.h"
21 #include "session/host/include/session.h"
22 #include "ui/rs_surface_node.h"
23
24 #include "adapter/ohos/entrance/ace_container.h"
25 #include "adapter/ohos/entrance/mmi_event_convertor.h"
26 #include "adapter/ohos/osal/want_wrap_ohos.h"
27 #include "base/geometry/offset.h"
28 #include "base/utils/utils.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/modal_ui_extension_proxy_impl.h"
33 #include "core/components_ng/pattern/ui_extension/session_wrapper_factory.h"
34 #include "core/components_ng/pattern/ui_extension/session_wrapper_impl.h"
35 #include "core/components_ng/pattern/ui_extension/ui_extension_layout_algorithm.h"
36 #include "core/components_ng/pattern/ui_extension/ui_extension_proxy.h"
37 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
38 #include "core/components_ng/render/adapter/rosen_render_context.h"
39 #include "core/components_ng/render/adapter/rosen_window.h"
40 #include "core/event/ace_events.h"
41 #include "core/event/mouse_event.h"
42 #include "core/event/touch_event.h"
43 #include "core/pipeline/pipeline_context.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45
46 namespace OHOS::Ace::NG {
UIExtensionPattern(bool isTransferringCaller,bool isModal,bool isAsyncModalBinding)47 UIExtensionPattern::UIExtensionPattern(bool isTransferringCaller, bool isModal, bool isAsyncModalBinding)
48 : isTransferringCaller_(isTransferringCaller), isModal_(isModal), isAsyncModalBinding_(isAsyncModalBinding)
49 {
50 sessionWrapper_ = SessionWrapperFactory::CreateSessionWrapper(
51 SessionTye::UI_EXTENSION_ABILITY, AceType::WeakClaim(this), instanceId_, isTransferringCaller_);
52 auto pipeline = PipelineContext::GetCurrentContext();
53 CHECK_NULL_VOID(pipeline);
54 auto uiExtensionManager = pipeline->GetUIExtensionManager();
55 CHECK_NULL_VOID(uiExtensionManager);
56 uiExtensionId_ = uiExtensionManager->ApplyExtensionId();
57 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Id = %{public}d, TransferrCaller = %{public}d, isModal = %{public}d",
58 uiExtensionId_, isTransferringCaller_, isModal_);
59 }
60
~UIExtensionPattern()61 UIExtensionPattern::~UIExtensionPattern()
62 {
63 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExtension with id = %{public}d is destroyed.", uiExtensionId_);
64 NotifyDestroy();
65 FireModalOnDestroy();
66 auto pipeline = PipelineContext::GetCurrentContext();
67 CHECK_NULL_VOID(pipeline);
68 auto uiExtensionManager = pipeline->GetUIExtensionManager();
69 CHECK_NULL_VOID(uiExtensionManager);
70 uiExtensionManager->RecycleExtensionId(uiExtensionId_);
71 uiExtensionManager->RemoveDestroyedUIExtension(GetNodeId());
72 }
73
CreateLayoutAlgorithm()74 RefPtr<LayoutAlgorithm> UIExtensionPattern::CreateLayoutAlgorithm()
75 {
76 return MakeRefPtr<UIExtensionLayoutAlgorithm>();
77 }
78
GetFocusPattern() const79 FocusPattern UIExtensionPattern::GetFocusPattern() const
80 {
81 return { FocusType::NODE, true, FocusStyleType::NONE };
82 }
83
InitializeDynamicComponent(const std::string & hapPath,const std::string & abcPath,const std::string & entryPoint,void * runtime)84 void UIExtensionPattern::InitializeDynamicComponent(
85 const std::string& hapPath, const std::string& abcPath, const std::string& entryPoint, void* runtime)
86 {
87 componentType_ = ComponentType::DYNAMIC;
88
89 if (!dynamicComponentRenderer_) {
90 ContainerScope scope(instanceId_);
91 dynamicComponentRenderer_ = DynamicComponentRenderer::Create(GetHost(), hapPath, abcPath, entryPoint, runtime);
92 CHECK_NULL_VOID(dynamicComponentRenderer_);
93 dynamicComponentRenderer_->CreateContent();
94 }
95 }
96
UpdateWant(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)97 void UIExtensionPattern::UpdateWant(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
98 {
99 auto want = AceType::DynamicCast<WantWrapOhos>(wantWrap)->GetWant();
100 UpdateWant(want);
101 }
102
UpdateWant(const AAFwk::Want & want)103 void UIExtensionPattern::UpdateWant(const AAFwk::Want& want)
104 {
105 CHECK_NULL_VOID(sessionWrapper_);
106 // Prohibit rebuilding the session unless the Want is updated.
107 if (sessionWrapper_->IsSessionValid()) {
108 if (sessionWrapper_->GetWant()->IsEquals(want)) {
109 return;
110 }
111 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "The old want is %{private}s, id = %{public}d",
112 sessionWrapper_->GetWant()->ToString().c_str(), uiExtensionId_);
113 auto host = GetHost();
114 CHECK_NULL_VOID(host);
115 host->RemoveChild(contentNode_);
116 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
117 NotifyDestroy();
118 }
119 sessionWrapper_->CreateSession(want, isAsyncModalBinding_);
120 NotifyForeground();
121 }
122
OnConnect()123 void UIExtensionPattern::OnConnect()
124 {
125 CHECK_RUN_ON(UI);
126 CHECK_NULL_VOID(sessionWrapper_);
127 ContainerScope scope(instanceId_);
128 contentNode_ = FrameNode::CreateFrameNode(
129 V2::UI_EXTENSION_SURFACE_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
130 contentNode_->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
131 contentNode_->SetHitTestMode(HitTestMode::HTMNONE);
132 auto host = GetHost();
133 CHECK_NULL_VOID(host);
134 auto&& opts = host->GetLayoutProperty()->GetSafeAreaExpandOpts();
135 if (opts && opts->Expansive()) {
136 contentNode_->GetLayoutProperty()->UpdateSafeAreaExpandOpts(*opts);
137 contentNode_->MarkModifyDone();
138 }
139 auto context = AceType::DynamicCast<NG::RosenRenderContext>(contentNode_->GetRenderContext());
140 CHECK_NULL_VOID(context);
141 auto surfaceNode = sessionWrapper_->GetSurfaceNode();
142 CHECK_NULL_VOID(surfaceNode);
143 context->SetRSNode(surfaceNode);
144 host->AddChild(contentNode_, 0);
145 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
146 surfaceNode->CreateNodeInRenderThread();
147 surfaceNode->SetForeground(isModal_);
148 FireOnRemoteReadyCallback();
149 if (isModal_) {
150 auto focusHub = host->GetFocusHub();
151 CHECK_NULL_VOID(focusHub);
152 focusHub->RequestFocusImmediately();
153 }
154 bool isFocused = IsCurrentFocus();
155 RegisterVisibleAreaChange();
156 DispatchFocusState(isFocused);
157 auto pipeline = PipelineContext::GetCurrentContext();
158 CHECK_NULL_VOID(pipeline);
159 auto uiExtensionManager = pipeline->GetUIExtensionManager();
160 uiExtensionManager->AddAliveUIExtension(host->GetId(), WeakClaim(this));
161 if (isFocused || isModal_) {
162 uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
163 }
164 TAG_LOGI(
165 AceLogTag::ACE_UIEXTENSIONCOMPONENT, "The UIExtensionComponent is connected, id = %{public}d.", uiExtensionId_);
166 }
167
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)168 void UIExtensionPattern::OnAccessibilityEvent(
169 const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset)
170 {
171 TAG_LOGI(
172 AceLogTag::ACE_UIEXTENSIONCOMPONENT, "The accessibility event is reported, id = %{public}d.", uiExtensionId_);
173 ContainerScope scope(instanceId_);
174 auto ngPipeline = NG::PipelineContext::GetCurrentContext();
175 CHECK_NULL_VOID(ngPipeline);
176 uiExtensionOffset = uiExtensionId_ * NG::UI_EXTENSION_OFFSET_MAX + uiExtensionOffset;
177 auto frontend = ngPipeline->GetFrontend();
178 CHECK_NULL_VOID(frontend);
179 auto accessibilityManager = frontend->GetAccessibilityManager();
180 CHECK_NULL_VOID(accessibilityManager);
181 accessibilityManager->SendExtensionAccessibilityEvent(info, uiExtensionOffset);
182 }
183
OnDisconnect()184 void UIExtensionPattern::OnDisconnect()
185 {
186 CHECK_RUN_ON(UI);
187 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
188 "The session is disconnected and state = %{public}d, id = %{public}d.", state_, uiExtensionId_);
189 FireOnReleaseCallback(static_cast<int32_t>(ReleaseCode::DESTROY_NORMAL));
190 }
191
OnExtensionDied()192 void UIExtensionPattern::OnExtensionDied()
193 {
194 CHECK_RUN_ON(UI);
195 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "The session is died and state = %{public}d, id = %{public}d.",
196 state_, uiExtensionId_);
197 auto host = GetHost();
198 CHECK_NULL_VOID(host);
199 host->RemoveChild(contentNode_);
200 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
201 FireOnReleaseCallback(static_cast<int32_t>(ReleaseCode::CONNECT_BROKEN));
202 }
203
OnAreaChangedInner()204 void UIExtensionPattern::OnAreaChangedInner()
205 {
206 DispatchDisplayArea();
207 }
208
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)209 bool UIExtensionPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
210 {
211 if (componentType_ == ComponentType::DYNAMIC) {
212 return OnDirtyLayoutWrapperSwapForDynamicComponent(dirty, config);
213 }
214 CHECK_NULL_RETURN(sessionWrapper_, false);
215 CHECK_NULL_RETURN(dirty, false);
216 auto host = dirty->GetHostNode();
217 CHECK_NULL_RETURN(host, false);
218 auto [displayOffset, err] = host->GetPaintRectGlobalOffsetWithTranslate();
219 auto geometryNode = dirty->GetGeometryNode();
220 CHECK_NULL_RETURN(geometryNode, false);
221 auto displaySize = geometryNode->GetFrameSize();
222 displayArea_ = RectF(displayOffset, displaySize);
223 sessionWrapper_->RefreshDisplayArea(displayArea_);
224 return false;
225 }
226
OnDirtyLayoutWrapperSwapForDynamicComponent(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)227 bool UIExtensionPattern::OnDirtyLayoutWrapperSwapForDynamicComponent(
228 const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
229 {
230 CHECK_NULL_RETURN(dynamicComponentRenderer_, false);
231
232 CHECK_NULL_RETURN(dirty, false);
233 auto host = dirty->GetHostNode();
234 CHECK_NULL_RETURN(host, false);
235 auto offset = host->GetPaintRectGlobalOffsetWithTranslate().first;
236 auto size = dirty->GetGeometryNode()->GetFrameSize();
237 Ace::ViewportConfig vpConfig;
238 vpConfig.SetSize(size.Width(), size.Height());
239 vpConfig.SetPosition(offset.GetX(), offset.GetY());
240 float density = 1.0f;
241 int32_t orientation = 0;
242 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
243 if (defaultDisplay) {
244 density = defaultDisplay->GetVirtualPixelRatio();
245 orientation = static_cast<int32_t>(defaultDisplay->GetOrientation());
246 }
247 vpConfig.SetDensity(density);
248 vpConfig.SetOrientation(orientation);
249 dynamicComponentRenderer_->UpdateViewportConfig(vpConfig, Rosen::WindowSizeChangeReason::UNDEFINED, nullptr);
250 return false;
251 }
252
OnWindowShow()253 void UIExtensionPattern::OnWindowShow()
254 {
255 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
256 "Show window, state = %{public}d, visible = %{public}d, id = %{public}d.", state_, isVisible_, uiExtensionId_);
257 if (isVisible_) {
258 NotifyForeground();
259 }
260 }
261
OnWindowHide()262 void UIExtensionPattern::OnWindowHide()
263 {
264 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
265 "Hide window, state = %{public}d, visible = %{public}d, id = %{public}d.", state_, isVisible_, uiExtensionId_);
266 if (isVisible_) {
267 NotifyBackground();
268 }
269 }
270
NotifyForeground()271 void UIExtensionPattern::NotifyForeground()
272 {
273 if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::FOREGROUND) {
274 state_ = AbilityState::FOREGROUND;
275 sessionWrapper_->NotifyForeground();
276 }
277 }
278
NotifyBackground()279 void UIExtensionPattern::NotifyBackground()
280 {
281 if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ == AbilityState::FOREGROUND) {
282 state_ = AbilityState::BACKGROUND;
283 sessionWrapper_->NotifyBackground();
284 }
285 }
286
NotifyDestroy()287 void UIExtensionPattern::NotifyDestroy()
288 {
289 if (sessionWrapper_ && sessionWrapper_->IsSessionValid() && state_ != AbilityState::DESTRUCTION &&
290 state_ != AbilityState::NONE) {
291 state_ = AbilityState::DESTRUCTION;
292 sessionWrapper_->NotifyDestroy();
293 sessionWrapper_->DestroySession();
294 }
295 }
296
OnAttachToFrameNode()297 void UIExtensionPattern::OnAttachToFrameNode()
298 {
299 ContainerScope scope(instanceId_);
300 auto pipeline = PipelineContext::GetCurrentContext();
301 CHECK_NULL_VOID(pipeline);
302 auto host = GetHost();
303 CHECK_NULL_VOID(host);
304 pipeline->AddOnAreaChangeNode(host->GetId());
305 callbackId_ = pipeline->RegisterSurfacePositionChangedCallback([weak = WeakClaim(this)](int32_t, int32_t) {
306 auto pattern = weak.Upgrade();
307 if (pattern) {
308 pattern->DispatchDisplayArea(true);
309 }
310 });
311 }
312
OnDetachFromFrameNode(FrameNode * frameNode)313 void UIExtensionPattern::OnDetachFromFrameNode(FrameNode* frameNode)
314 {
315 if (componentType_ == ComponentType::DYNAMIC) {
316 CHECK_NULL_VOID(dynamicComponentRenderer_);
317 dynamicComponentRenderer_->DestroyContent();
318 dynamicComponentRenderer_ = nullptr;
319 return;
320 }
321
322 auto id = frameNode->GetId();
323 ContainerScope scope(instanceId_);
324 auto pipeline = PipelineContext::GetCurrentContext();
325 CHECK_NULL_VOID(pipeline);
326 pipeline->RemoveWindowStateChangedCallback(id);
327 pipeline->UnregisterSurfacePositionChangedCallback(callbackId_);
328 }
329
OnModifyDone()330 void UIExtensionPattern::OnModifyDone()
331 {
332 Pattern::OnModifyDone();
333 auto host = GetHost();
334 CHECK_NULL_VOID(host);
335 auto hub = host->GetEventHub<EventHub>();
336 CHECK_NULL_VOID(hub);
337 auto gestureHub = hub->GetOrCreateGestureEventHub();
338 CHECK_NULL_VOID(gestureHub);
339 InitTouchEvent(gestureHub);
340 auto inputHub = hub->GetOrCreateInputEventHub();
341 CHECK_NULL_VOID(inputHub);
342 InitMouseEvent(inputHub);
343 InitHoverEvent(inputHub);
344 auto focusHub = host->GetFocusHub();
345 CHECK_NULL_VOID(focusHub);
346 InitKeyEvent(focusHub);
347 }
348
InitKeyEvent(const RefPtr<FocusHub> & focusHub)349 void UIExtensionPattern::InitKeyEvent(const RefPtr<FocusHub>& focusHub)
350 {
351 focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
352 auto pattern = weak.Upgrade();
353 if (pattern) {
354 pattern->HandleFocusEvent();
355 }
356 });
357
358 focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
359 auto pattern = weak.Upgrade();
360 if (pattern) {
361 pattern->HandleBlurEvent();
362 }
363 });
364
365 focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
366 auto pattern = weak.Upgrade();
367 if (pattern) {
368 pattern->DispatchFocusActiveEvent(false);
369 }
370 });
371 focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
372 auto pattern = weak.Upgrade();
373 if (pattern) {
374 pattern->DispatchFocusActiveEvent(true);
375 return true;
376 }
377 return false;
378 });
379
380 focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
381 auto pattern = wp.Upgrade();
382 if (pattern) {
383 return pattern->HandleKeyEvent(event);
384 }
385 return false;
386 });
387 }
388
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)389 void UIExtensionPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
390 {
391 if (touchEvent_) {
392 return;
393 }
394 auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
395 auto pattern = weak.Upgrade();
396 if (pattern) {
397 pattern->HandleTouchEvent(info);
398 }
399 };
400 if (touchEvent_) {
401 gestureHub->RemoveTouchEvent(touchEvent_);
402 }
403 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
404 gestureHub->AddTouchEvent(touchEvent_);
405 }
406
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)407 void UIExtensionPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
408 {
409 if (mouseEvent_) {
410 return;
411 }
412 auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
413 auto pattern = weak.Upgrade();
414 if (pattern) {
415 pattern->HandleMouseEvent(info);
416 }
417 };
418 if (mouseEvent_) {
419 inputHub->RemoveOnMouseEvent(mouseEvent_);
420 }
421 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
422 inputHub->AddOnMouseEvent(mouseEvent_);
423 }
424
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)425 void UIExtensionPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
426 {
427 if (hoverEvent_) {
428 return;
429 }
430 auto callback = [weak = WeakClaim(this)](bool isHover) {
431 auto pattern = weak.Upgrade();
432 if (pattern) {
433 pattern->HandleHoverEvent(isHover);
434 }
435 };
436 if (hoverEvent_) {
437 inputHub->RemoveOnHoverEvent(hoverEvent_);
438 }
439 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
440 inputHub->AddOnHoverEvent(hoverEvent_);
441 }
442
HandleKeyEvent(const KeyEvent & event)443 bool UIExtensionPattern::HandleKeyEvent(const KeyEvent& event)
444 {
445 return DispatchKeyEventSync(event.rawKeyEvent);
446 }
447
HandleFocusEvent()448 void UIExtensionPattern::HandleFocusEvent()
449 {
450 auto pipeline = PipelineContext::GetCurrentContext();
451 if (pipeline->GetIsFocusActive()) {
452 DispatchFocusActiveEvent(true);
453 }
454 DispatchFocusState(true);
455 auto uiExtensionManager = pipeline->GetUIExtensionManager();
456 uiExtensionManager->RegisterUIExtensionInFocus(WeakClaim(this), sessionWrapper_);
457 }
458
HandleBlurEvent()459 void UIExtensionPattern::HandleBlurEvent()
460 {
461 DispatchFocusActiveEvent(false);
462 DispatchFocusState(false);
463 auto pipeline = PipelineContext::GetCurrentContext();
464 CHECK_NULL_VOID(pipeline);
465 auto uiExtensionManager = pipeline->GetUIExtensionManager();
466 uiExtensionManager->RegisterUIExtensionInFocus(nullptr, nullptr);
467 }
468
HandleTouchEvent(const TouchEventInfo & info)469 void UIExtensionPattern::HandleTouchEvent(const TouchEventInfo& info)
470 {
471 if (info.GetSourceDevice() != SourceType::TOUCH) {
472 return;
473 }
474 const auto pointerEvent = info.GetPointerEvent();
475 CHECK_NULL_VOID(pointerEvent);
476 auto host = GetHost();
477 CHECK_NULL_VOID(host);
478 auto selfGlobalOffset = host->GetTransformRelativeOffset();
479 auto scale = host->GetTransformScale();
480 auto pipeline = PipelineBase::GetCurrentContext();
481 CHECK_NULL_VOID(pipeline);
482 auto window = static_cast<RosenWindow*>(pipeline->GetWindow());
483 CHECK_NULL_VOID(window);
484 auto rsWindow = window->GetRSWindow();
485 auto udegree = WindowPattern::CalculateTranslateDegree(host->GetId());
486 if (rsWindow->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD) {
487 Platform::CalculateWindowCoordinate(selfGlobalOffset, pointerEvent, scale, udegree);
488 } else {
489 Platform::CalculatePointerEvent(selfGlobalOffset, pointerEvent, scale, udegree);
490 }
491 auto focusHub = host->GetFocusHub();
492 CHECK_NULL_VOID(focusHub);
493 focusHub->RequestFocusImmediately();
494 DispatchPointerEvent(pointerEvent);
495 }
496
HandleMouseEvent(const MouseInfo & info)497 void UIExtensionPattern::HandleMouseEvent(const MouseInfo& info)
498 {
499 if (info.GetSourceDevice() != SourceType::MOUSE) {
500 return;
501 }
502 const auto pointerEvent = info.GetPointerEvent();
503 CHECK_NULL_VOID(pointerEvent);
504 lastPointerEvent_ = pointerEvent;
505 auto host = GetHost();
506 CHECK_NULL_VOID(host);
507 auto selfGlobalOffset = host->GetTransformRelativeOffset();
508 auto scale = host->GetTransformScale();
509 Platform::CalculatePointerEvent(selfGlobalOffset, pointerEvent, scale);
510 if (info.GetAction() == MouseAction::PRESS) {
511 auto hub = host->GetFocusHub();
512 CHECK_NULL_VOID(hub);
513 hub->RequestFocusImmediately();
514 }
515 DispatchPointerEvent(pointerEvent);
516 }
517
HandleHoverEvent(bool isHover)518 void UIExtensionPattern::HandleHoverEvent(bool isHover)
519 {
520 if (isHover) {
521 return;
522 }
523 CHECK_NULL_VOID(lastPointerEvent_);
524 lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
525 DispatchPointerEvent(lastPointerEvent_);
526 }
527
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)528 void UIExtensionPattern::DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
529 {
530 CHECK_NULL_VOID(keyEvent);
531 if (componentType_ == ComponentType::DYNAMIC) {
532 CHECK_NULL_VOID(dynamicComponentRenderer_);
533 dynamicComponentRenderer_->TransferKeyEvent(keyEvent);
534 } else if (sessionWrapper_) {
535 sessionWrapper_->NotifyKeyEventAsync(keyEvent);
536 }
537 }
538
DispatchKeyEventSync(const std::shared_ptr<MMI::KeyEvent> & keyEvent)539 bool UIExtensionPattern::DispatchKeyEventSync(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
540 {
541 return sessionWrapper_ && sessionWrapper_->NotifyKeyEventSync(keyEvent);
542 }
543
DispatchFocusActiveEvent(bool isFocusActive)544 void UIExtensionPattern::DispatchFocusActiveEvent(bool isFocusActive)
545 {
546 CHECK_NULL_VOID(sessionWrapper_);
547 sessionWrapper_->NotifyFocusEventAsync(isFocusActive);
548 }
549
DispatchFocusState(bool focusState)550 void UIExtensionPattern::DispatchFocusState(bool focusState)
551 {
552 CHECK_NULL_VOID(sessionWrapper_);
553 sessionWrapper_->NotifyFocusStateAsync(focusState);
554 }
555
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)556 void UIExtensionPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
557 {
558 CHECK_NULL_VOID(pointerEvent);
559 if (componentType_ == ComponentType::DYNAMIC) {
560 CHECK_NULL_VOID(dynamicComponentRenderer_);
561 dynamicComponentRenderer_->TransferPointerEvent(pointerEvent);
562 } else if (sessionWrapper_) {
563 sessionWrapper_->NotifyPointerEventAsync(pointerEvent);
564 }
565 }
566
DispatchDisplayArea(bool isForce)567 void UIExtensionPattern::DispatchDisplayArea(bool isForce)
568 {
569 CHECK_NULL_VOID(sessionWrapper_);
570 auto host = GetHost();
571 CHECK_NULL_VOID(host);
572 auto [displayOffset, err] = host->GetPaintRectGlobalOffsetWithTranslate();
573 auto geometryNode = host->GetGeometryNode();
574 CHECK_NULL_VOID(geometryNode);
575 auto displaySize = geometryNode->GetFrameSize();
576 auto displayArea = RectF(displayOffset, displaySize);
577 if (displayArea_ != displayArea || isForce) {
578 displayArea_ = displayArea;
579 sessionWrapper_->RefreshDisplayArea(displayArea_);
580 }
581 }
582
HandleDragEvent(const PointerEvent & info)583 void UIExtensionPattern::HandleDragEvent(const PointerEvent& info)
584 {
585 const auto pointerEvent = info.rawPointerEvent;
586 CHECK_NULL_VOID(pointerEvent);
587 auto host = GetHost();
588 CHECK_NULL_VOID(host);
589 auto selfGlobalOffset = host->GetTransformRelativeOffset();
590 auto scale = host->GetTransformScale();
591 auto pipeline = PipelineBase::GetCurrentContext();
592 CHECK_NULL_VOID(pipeline);
593 auto window = static_cast<RosenWindow*>(pipeline->GetWindow());
594 CHECK_NULL_VOID(window);
595 auto rsWindow = window->GetRSWindow();
596 auto udegree = WindowPattern::CalculateTranslateDegree(host->GetId());
597 if (rsWindow->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD) {
598 Platform::CalculateWindowCoordinate(selfGlobalOffset, pointerEvent, scale, udegree);
599 } else {
600 Platform::CalculatePointerEvent(selfGlobalOffset, pointerEvent, scale, udegree);
601 }
602 DispatchPointerEvent(pointerEvent);
603 }
604
SetOnRemoteReadyCallback(const std::function<void (const RefPtr<UIExtensionProxy> &)> && callback)605 void UIExtensionPattern::SetOnRemoteReadyCallback(const std::function<void(const RefPtr<UIExtensionProxy>&)>&& callback)
606 {
607 onRemoteReadyCallback_ = std::move(callback);
608 }
609
SetModalOnRemoteReadyCallback(const std::function<void (const std::shared_ptr<ModalUIExtensionProxy> &)> && callback)610 void UIExtensionPattern::SetModalOnRemoteReadyCallback(
611 const std::function<void(const std::shared_ptr<ModalUIExtensionProxy>&)>&& callback)
612 {
613 onModalRemoteReadyCallback_ = std::move(callback);
614 }
615
FireOnRemoteReadyCallback()616 void UIExtensionPattern::FireOnRemoteReadyCallback()
617 {
618 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
619 "The onRemoteReady is called and state = %{public}d, id = %{public}d.", state_, uiExtensionId_);
620 ContainerScope scope(instanceId_);
621 // These two callbacks will be unified in the future.
622 if (onRemoteReadyCallback_) {
623 onRemoteReadyCallback_(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
624 }
625 if (onModalRemoteReadyCallback_) {
626 onModalRemoteReadyCallback_(std::make_shared<ModalUIExtensionProxyImpl>(sessionWrapper_));
627 }
628 }
629
SetModalOnDestroy(const std::function<void ()> && callback)630 void UIExtensionPattern::SetModalOnDestroy(const std::function<void()>&& callback)
631 {
632 onModalDestroy_ = std::move(callback);
633 }
634
FireModalOnDestroy()635 void UIExtensionPattern::FireModalOnDestroy()
636 {
637 // Native modal page destroy callback
638 if (onModalDestroy_) {
639 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
640 "The onModalDestroy is called and state = %{public}d, id = %{public}d.", state_, uiExtensionId_);
641 ContainerScope scope(instanceId_);
642 onModalDestroy_();
643 }
644 }
645
SetOnReleaseCallback(const std::function<void (int32_t)> && callback)646 void UIExtensionPattern::SetOnReleaseCallback(const std::function<void(int32_t)>&& callback)
647 {
648 onReleaseCallback_ = std::move(callback);
649 }
650
FireOnReleaseCallback(int32_t releaseCode)651 void UIExtensionPattern::FireOnReleaseCallback(int32_t releaseCode)
652 {
653 state_ = AbilityState::DESTRUCTION;
654 if (onReleaseCallback_) {
655 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
656 "The onRelease is called and state = %{public}d, id = %{public}d.", state_, uiExtensionId_);
657 onReleaseCallback_(releaseCode);
658 }
659 // Release the session.
660 if (sessionWrapper_ && sessionWrapper_->IsSessionValid()) {
661 sessionWrapper_->DestroySession();
662 }
663 }
664
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)665 void UIExtensionPattern::SetOnErrorCallback(
666 const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
667 {
668 onErrorCallback_ = std::move(callback);
669 if (lastError_.code != 0) {
670 ErrorMsg error;
671 std::swap(lastError_, error);
672 FireOnErrorCallback(error.code, error.name, error.message);
673 }
674 }
675
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)676 void UIExtensionPattern::FireOnErrorCallback(int32_t code, const std::string& name, const std::string& message)
677 {
678 // 1. As long as the error occurs, the host believes that UIExtensionAbility has been killed.
679 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
680 "Error: Id = %{public}d, state = %{public}d, code=%{public}d, name=%{public}s", uiExtensionId_, state_, code,
681 name.c_str());
682 state_ = AbilityState::NONE;
683 if (onErrorCallback_) {
684 ContainerScope scope(instanceId_);
685 onErrorCallback_(code, name, message);
686 return;
687 }
688 lastError_ = { code, name, message };
689 }
690
SetOnResultCallback(const std::function<void (int32_t,const AAFwk::Want &)> && callback)691 void UIExtensionPattern::SetOnResultCallback(const std::function<void(int32_t, const AAFwk::Want&)>&& callback)
692 {
693 onResultCallback_ = std::move(callback);
694 }
695
FireOnResultCallback(int32_t code,const AAFwk::Want & want)696 void UIExtensionPattern::FireOnResultCallback(int32_t code, const AAFwk::Want& want)
697 {
698 if (onResultCallback_ && (state_ != AbilityState::DESTRUCTION)) {
699 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "The onResult is called and state = %{public}d, id = %{public}d.",
700 state_, uiExtensionId_);
701 ContainerScope scope(instanceId_);
702 onResultCallback_(code, want);
703 }
704 state_ = AbilityState::DESTRUCTION;
705 }
706
SetOnReceiveCallback(const std::function<void (const AAFwk::WantParams &)> && callback)707 void UIExtensionPattern::SetOnReceiveCallback(const std::function<void(const AAFwk::WantParams&)>&& callback)
708 {
709 onReceiveCallback_ = std::move(callback);
710 }
711
FireOnReceiveCallback(const AAFwk::WantParams & params)712 void UIExtensionPattern::FireOnReceiveCallback(const AAFwk::WantParams& params)
713 {
714 if (onReceiveCallback_) {
715 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
716 "The onReceive is called and state = %{public}d, id = %{public}d.", state_, uiExtensionId_);
717 ContainerScope scope(instanceId_);
718 onReceiveCallback_(params);
719 }
720 }
721
SetSyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)722 void UIExtensionPattern::SetSyncCallbacks(
723 const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
724 {
725 onSyncOnCallbackList_ = std::move(callbackList);
726 }
727
FireSyncCallbacks()728 void UIExtensionPattern::FireSyncCallbacks()
729 {
730 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
731 "The size of sync callbacks = %{public}zu and state = %{public}d, id = %{public}d.",
732 onSyncOnCallbackList_.size(), state_, uiExtensionId_);
733 ContainerScope scope(instanceId_);
734 for (const auto& callback : onSyncOnCallbackList_) {
735 if (callback) {
736 callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
737 }
738 }
739 }
740
SetAsyncCallbacks(const std::list<std::function<void (const RefPtr<UIExtensionProxy> &)>> && callbackList)741 void UIExtensionPattern::SetAsyncCallbacks(
742 const std::list<std::function<void(const RefPtr<UIExtensionProxy>&)>>&& callbackList)
743 {
744 onAsyncOnCallbackList_ = std::move(callbackList);
745 }
746
FireAsyncCallbacks()747 void UIExtensionPattern::FireAsyncCallbacks()
748 {
749 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
750 "The size of async callbacks = %{public}zu and state = %{public}d, id = %{public}d.",
751 onSyncOnCallbackList_.size(), state_, uiExtensionId_);
752 ContainerScope scope(instanceId_);
753 for (const auto& callback : onAsyncOnCallbackList_) {
754 if (callback) {
755 callback(MakeRefPtr<UIExtensionProxy>(sessionWrapper_, Claim(this)));
756 }
757 }
758 }
759
SetBindModalCallback(const std::function<void ()> && callback)760 void UIExtensionPattern::SetBindModalCallback(const std::function<void()>&& callback)
761 {
762 bindModalCallback_ = std::move(callback);
763 }
764
FireBindModalCallback()765 void UIExtensionPattern::FireBindModalCallback()
766 {
767 if (bindModalCallback_) {
768 bindModalCallback_();
769 }
770 }
771
OnVisibleChange(bool visible)772 void UIExtensionPattern::OnVisibleChange(bool visible)
773 {
774 TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
775 "The visual state of the window changes, state = %{public}d, visible = %{public}d, id = %{public}d.", state_,
776 isVisible_, uiExtensionId_);
777 isVisible_ = visible;
778 if (visible) {
779 NotifyForeground();
780 } else {
781 NotifyBackground();
782 }
783 }
784
RegisterVisibleAreaChange()785 void UIExtensionPattern::RegisterVisibleAreaChange()
786 {
787 auto pipeline = PipelineContext::GetCurrentContext();
788 CHECK_NULL_VOID(pipeline);
789 auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
790 auto uiExtension = weak.Upgrade();
791 CHECK_NULL_VOID(uiExtension);
792 uiExtension->OnVisibleChange(visible);
793 };
794 auto host = GetHost();
795 CHECK_NULL_VOID(host);
796 pipeline->AddVisibleAreaChangeNode(host, 0.0f, callback, false);
797 }
798
IsCurrentFocus() const799 bool UIExtensionPattern::IsCurrentFocus() const
800 {
801 auto host = GetHost();
802 CHECK_NULL_RETURN(host, false);
803 auto focusHub = host->GetFocusHub();
804 CHECK_NULL_RETURN(focusHub, false);
805 return focusHub->IsCurrentFocus();
806 }
807
OnLanguageConfigurationUpdate()808 void UIExtensionPattern::OnLanguageConfigurationUpdate()
809 {
810 CHECK_NULL_VOID(sessionWrapper_);
811 sessionWrapper_->NotifyConfigurationUpdate();
812 }
813
OnColorConfigurationUpdate()814 void UIExtensionPattern::OnColorConfigurationUpdate()
815 {
816 CHECK_NULL_VOID(sessionWrapper_);
817 sessionWrapper_->NotifyConfigurationUpdate();
818 }
819
GetSessionId()820 int32_t UIExtensionPattern::GetSessionId()
821 {
822 return sessionWrapper_ ? sessionWrapper_->GetSessionId() : 0;
823 }
824
GetUiExtensionId()825 int32_t UIExtensionPattern::GetUiExtensionId()
826 {
827 return uiExtensionId_;
828 }
829
GetNodeId()830 int32_t UIExtensionPattern::GetNodeId()
831 {
832 auto host = GetHost();
833 return host ? host->GetId() : -1;
834 }
835
GetInstanceId()836 int32_t UIExtensionPattern::GetInstanceId()
837 {
838 return instanceId_;
839 }
840
DispatchOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)841 void UIExtensionPattern::DispatchOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
842 {
843 CHECK_NULL_VOID(sessionWrapper_);
844 sessionWrapper_->NotifyOriginAvoidArea(avoidArea, type);
845 }
846
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)847 int64_t UIExtensionPattern::WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
848 {
849 return uiExtensionId_ * extensionOffset + abilityId;
850 }
851
SearchExtensionElementInfoByAccessibilityId(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)852 void UIExtensionPattern::SearchExtensionElementInfoByAccessibilityId(
853 int64_t elementId, int32_t mode, int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output)
854 {
855 CHECK_NULL_VOID(sessionWrapper_);
856 sessionWrapper_->SearchExtensionElementInfoByAccessibilityId(elementId, mode, baseParent, output);
857 }
858
SearchElementInfosByText(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)859 void UIExtensionPattern::SearchElementInfosByText(int64_t elementId, const std::string& text, int64_t baseParent,
860 std::list<Accessibility::AccessibilityElementInfo>& output)
861 {
862 CHECK_NULL_VOID(sessionWrapper_);
863 sessionWrapper_->SearchElementInfosByText(elementId, text, baseParent, output);
864 }
865
FindFocusedElementInfo(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)866 void UIExtensionPattern::FindFocusedElementInfo(
867 int64_t elementId, int32_t focusType, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)
868 {
869 CHECK_NULL_VOID(sessionWrapper_);
870 sessionWrapper_->FindFocusedElementInfo(elementId, focusType, baseParent, output);
871 }
872
FocusMoveSearch(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)873 void UIExtensionPattern::FocusMoveSearch(
874 int64_t elementId, int32_t direction, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)
875 {
876 CHECK_NULL_VOID(sessionWrapper_);
877 sessionWrapper_->FocusMoveSearch(elementId, direction, baseParent, output);
878 }
879
TransferExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)880 bool UIExtensionPattern::TransferExecuteAction(
881 int64_t elementId, const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)
882 {
883 return sessionWrapper_ && sessionWrapper_->TransferExecuteAction(elementId, actionArguments, action, offset);
884 }
885 } // namespace OHOS::Ace::NG
886