• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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