• 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 <cstdint>
19 
20 #include "session/host/include/extension_session.h"
21 #include "session_manager/include/extension_session_manager.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/utils/utils.h"
28 #include "core/components_ng/event/event_hub.h"
29 #include "core/components_ng/pattern/pattern.h"
30 #include "core/components_ng/pattern/text_field/text_field_manager.h"
31 #include "core/components_ng/pattern/ui_extension/ui_extension_layout_algorithm.h"
32 #include "core/components_ng/pattern/ui_extension/ui_extension_proxy.h"
33 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
34 #include "core/components_ng/render/adapter/rosen_render_context.h"
35 #include "core/event/ace_events.h"
36 #include "core/event/mouse_event.h"
37 #include "core/event/touch_event.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39 
40 namespace OHOS::Ace::NG {
UIExtensionPattern(const RefPtr<OHOS::Ace::WantWrap> & wantWrap)41 UIExtensionPattern::UIExtensionPattern(const RefPtr<OHOS::Ace::WantWrap>& wantWrap)
42 {
43     auto container = AceType::DynamicCast<Platform::AceContainer>(Container::Current());
44     CHECK_NULL_VOID_NOLOG(container);
45     auto callerToken = container->GetToken();
46     auto want = AceType::DynamicCast<WantWrapOhos>(wantWrap)->GetWant();
47     if (want.GetElement().GetBundleName() == "AbilityComp") {
48         return;
49     }
50     Rosen::SessionInfo extensionSessionInfo = {
51         .bundleName_ = want.GetElement().GetBundleName(),
52         .abilityName_ = want.GetElement().GetAbilityName(),
53         .callerToken_ = callerToken,
54         .want = new (std::nothrow) Want(want),
55     };
56     session_ = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSession(extensionSessionInfo);
57     CHECK_NULL_VOID(session_);
58     RegisterLifecycleListener();
59     LOGI("UIExtension request UIExtensionAbility start");
60     RequestExtensionSessionActivation();
61     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
62     sptr<Rosen::ExtensionSession::ExtensionSessionEventCallback> extSessionEventCallback =
63         new (std::nothrow) Rosen::ExtensionSession::ExtensionSessionEventCallback();
64     extensionSession->RegisterExtensionSessionEventCallback(extSessionEventCallback);
65 }
66 
UIExtensionPattern(const AAFwk::Want & want)67 UIExtensionPattern::UIExtensionPattern(const AAFwk::Want& want)
68 {
69     auto container = AceType::DynamicCast<Platform::AceContainer>(Container::Current());
70     CHECK_NULL_VOID_NOLOG(container);
71     auto callerToken = container->GetToken();
72     Rosen::SessionInfo extensionSessionInfo = {
73         .bundleName_ = want.GetElement().GetBundleName(),
74         .abilityName_ = want.GetElement().GetAbilityName(),
75         .callerToken_ = callerToken,
76         .want = new (std::nothrow) Want(want),
77     };
78     session_ = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSession(extensionSessionInfo);
79     CHECK_NULL_VOID(session_);
80     RegisterLifecycleListener();
81     LOGI("Native Modal UIExtension request UIExtensionAbility start");
82     RequestExtensionSessionActivation();
83     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
84     sptr<Rosen::ExtensionSession::ExtensionSessionEventCallback> extSessionEventCallback =
85         new (std::nothrow) Rosen::ExtensionSession::ExtensionSessionEventCallback();
86     extensionSession->RegisterExtensionSessionEventCallback(extSessionEventCallback);
87 }
88 
~UIExtensionPattern()89 UIExtensionPattern::~UIExtensionPattern()
90 {
91     UnregisterLifecycleListener();
92     UnregisterAbilityResultListener();
93     RequestExtensionSessionDestruction();
94 }
95 
OnConnect()96 void UIExtensionPattern::OnConnect()
97 {
98     LOGI("UIExtension OnConnect called");
99     ContainerScope scope(instanceId_);
100     auto pipeline = PipelineBase::GetCurrentContext();
101     CHECK_NULL_VOID_NOLOG(pipeline);
102     auto taskExecutor = pipeline->GetTaskExecutor();
103     CHECK_NULL_VOID_NOLOG(taskExecutor);
104     taskExecutor->PostTask(
105         [weak = WeakClaim(this)]() {
106             auto extensionPattern = weak.Upgrade();
107             CHECK_NULL_VOID_NOLOG(extensionPattern);
108             extensionPattern->OnConnectInner();
109         },
110         TaskExecutor::TaskType::UI);
111 }
112 
OnConnectInner()113 void UIExtensionPattern::OnConnectInner()
114 {
115     ContainerScope scope(instanceId_);
116     auto surfaceNode = session_->GetSurfaceNode();
117     CHECK_NULL_VOID_NOLOG(surfaceNode);
118     CHECK_NULL_VOID_NOLOG(contentNode_);
119     auto context = AceType::DynamicCast<NG::RosenRenderContext>(contentNode_->GetRenderContext());
120     CHECK_NULL_VOID_NOLOG(context);
121     context->SetRSNode(surfaceNode);
122     auto host = GetHost();
123     CHECK_NULL_VOID_NOLOG(host);
124     host->AddChild(contentNode_, 0);
125     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
126     surfaceNode->CreateNodeInRenderThread();
127     auto pipeline = PipelineBase::GetCurrentContext();
128     if (onRemoteReadyCallback_) {
129         onRemoteReadyCallback_(MakeRefPtr<UIExtensionProxy>(session_));
130     }
131     RegisterVisibleAreaChange();
132     TransferFocusState(IsCurrentFocus());
133 }
134 
OnDisconnect()135 void UIExtensionPattern::OnDisconnect()
136 {
137     LOGI("UIExtension OnDisconnect called");
138     ContainerScope scope(instanceId_);
139     auto pipeline = PipelineBase::GetCurrentContext();
140     CHECK_NULL_VOID_NOLOG(pipeline);
141     auto taskExecutor = pipeline->GetTaskExecutor();
142     CHECK_NULL_VOID_NOLOG(taskExecutor);
143     isDestruction_ = true;
144     taskExecutor->PostTask(
145         [weak = WeakClaim(this)]() {
146             auto extensionPattern = weak.Upgrade();
147             CHECK_NULL_VOID_NOLOG(extensionPattern);
148             if (extensionPattern->onReleaseCallback_) {
149                 extensionPattern->onReleaseCallback_(static_cast<int32_t>(ReleaseCode::DESTROY_NORMAL));
150             }
151         },
152         TaskExecutor::TaskType::UI);
153 }
154 
OnExtensionDied()155 void UIExtensionPattern::OnExtensionDied()
156 {
157     LOGI("UIExtensionPattern OnExtensionDied called");
158     ContainerScope scope(instanceId_);
159     auto pipeline = PipelineBase::GetCurrentContext();
160     CHECK_NULL_VOID_NOLOG(pipeline);
161     auto taskExecutor = pipeline->GetTaskExecutor();
162     CHECK_NULL_VOID_NOLOG(taskExecutor);
163     taskExecutor->PostTask(
164         [weak = WeakClaim(this)]() {
165             auto extensionPattern = weak.Upgrade();
166             CHECK_NULL_VOID_NOLOG(extensionPattern);
167             if (extensionPattern->onReleaseCallback_) {
168                 extensionPattern->isDestruction_ = true;
169                 extensionPattern->onReleaseCallback_(static_cast<int32_t>(ReleaseCode::CONNECT_BROKEN));
170             }
171         },
172         TaskExecutor::TaskType::UI);
173 }
174 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)175 bool UIExtensionPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
176 {
177     CHECK_NULL_RETURN(dirty, false);
178     auto host = dirty->GetHostNode();
179     CHECK_NULL_RETURN(host, false);
180     auto globalOffsetWithTranslate = host->GetPaintRectGlobalOffsetWithTranslate();
181     auto geometryNode = dirty->GetGeometryNode();
182     CHECK_NULL_RETURN(geometryNode, false);
183     auto frameRect = geometryNode->GetFrameRect();
184 
185     Rosen::WSRect windowRect {
186         .posX_ = std::round(globalOffsetWithTranslate.GetX()),
187         .posY_ = std::round(globalOffsetWithTranslate.GetY()),
188         .width_ = std::round(frameRect.Width()),
189         .height_ = std::round(frameRect.Height())
190     };
191 
192     CHECK_NULL_RETURN(session_, false);
193     session_->UpdateRect(windowRect, Rosen::SizeChangeReason::UNDEFINED);
194     return false;
195 }
196 
OnWindowShow()197 void UIExtensionPattern::OnWindowShow()
198 {
199     RequestExtensionSessionActivation();
200 }
201 
OnWindowHide()202 void UIExtensionPattern::OnWindowHide()
203 {
204     RequestExtensionSessionBackground();
205 }
206 
RequestExtensionSessionActivation()207 void UIExtensionPattern::RequestExtensionSessionActivation()
208 {
209     auto pipeline = PipelineBase::GetCurrentContext();
210     CHECK_NULL_VOID_NOLOG(pipeline);
211     auto hostWindowId = pipeline->GetFocusWindowId();
212     LOGI("ui_extension request host windowId %{public}u", hostWindowId);
213     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
214     auto errcode = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionActivation(
215         extensionSession, hostWindowId);
216     if (errcode != OHOS::Rosen::WSError::WS_OK) {
217         int32_t code = static_cast<int32_t>(errcode);
218         std::string name = "start_ability_fail";
219         std::string message = "Start ui extension ability failed, please check the want of UIextensionAbility.";
220         lastError_ = { code, name, message };
221         if (onErrorCallback_) {
222             ErrorMsg error;
223             std::swap(lastError_, error);
224             onErrorCallback_(error.code, error.name, error.message);
225         }
226     }
227 }
228 
RequestExtensionSessionBackground()229 void UIExtensionPattern::RequestExtensionSessionBackground()
230 {
231     LOGI("UIExtension request UIExtensionAbility background, isDestruction_=%{public}u", isDestruction_);
232     if (!isDestruction_) {
233         sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
234         auto errcode =
235             Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionBackground(extensionSession);
236         if (errcode != OHOS::Rosen::WSError::WS_OK) {
237             if (onErrorCallback_) {
238                 int32_t code = static_cast<int32_t>(errcode);
239                 std::string name = "background_fail";
240                 std::string message = "background ui extension ability failed, please check AMS log.";
241                 onErrorCallback_(code, name, message);
242             }
243         }
244     }
245 }
246 
RequestExtensionSessionDestruction()247 void UIExtensionPattern::RequestExtensionSessionDestruction()
248 {
249     LOGI("UIExtension request UIExtensionAbility destroy, isDestruction_=%{public}u", isDestruction_);
250     if (!isDestruction_) {
251         sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
252         auto errcode =
253             Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestruction(extensionSession);
254         if (errcode != OHOS::Rosen::WSError::WS_OK) {
255             if (onErrorCallback_) {
256                 int32_t code = static_cast<int32_t>(errcode);
257                 std::string name = "terminate_fail";
258                 std::string message = "terminate ui extension ability failed, please check AMS log.";
259                 onErrorCallback_(code, name, message);
260             }
261         }
262     }
263 }
264 
CreateLayoutAlgorithm()265 RefPtr<LayoutAlgorithm> UIExtensionPattern::CreateLayoutAlgorithm()
266 {
267     return MakeRefPtr<UIExtensionLayoutAlgorithm>();
268 }
269 
OnDetachFromFrameNode(FrameNode * frameNode)270 void UIExtensionPattern::OnDetachFromFrameNode(FrameNode* frameNode)
271 {
272     auto id = frameNode->GetId();
273     auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
274     CHECK_NULL_VOID_NOLOG(pipeline);
275     pipeline->RemoveWindowStateChangedCallback(id);
276     auto textFieldManager = DynamicCast<TextFieldManagerNG>(pipeline->GetTextFieldManager());
277     if (textFieldManager) {
278         textFieldManager->ClearOnFocusTextField();
279     }
280 }
281 
GetFocusPattern() const282 FocusPattern UIExtensionPattern::GetFocusPattern() const
283 {
284     return { FocusType::NODE, true, FocusStyleType::NONE };
285 }
286 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)287 void UIExtensionPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
288 {
289     focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
290         auto pattern = weak.Upgrade();
291         if (pattern) {
292             pattern->HandleFocusEvent();
293         }
294     });
295 
296     focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
297         auto pattern = weak.Upgrade();
298         if (pattern) {
299             pattern->HandleBlurEvent();
300         }
301     });
302 
303     focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
304         auto pattern = weak.Upgrade();
305         if (pattern) {
306             pattern->DisPatchFocusActiveEvent(false);
307         }
308     });
309     focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
310         auto pattern = weak.Upgrade();
311         if (pattern) {
312             pattern->DisPatchFocusActiveEvent(true);
313             return true;
314         }
315         return false;
316     });
317 
318     focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
319         auto pattern = wp.Upgrade();
320         if (pattern) {
321             return pattern->OnKeyEvent(event);
322         }
323         return false;
324     });
325 }
326 
HandleFocusEvent()327 void UIExtensionPattern::HandleFocusEvent()
328 {
329     auto pipeline = PipelineContext::GetCurrentContext();
330     if (pipeline->GetIsFocusActive()) {
331         WindowPattern::DisPatchFocusActiveEvent(true);
332     }
333     TransferFocusState(true);
334 }
335 
HandleBlurEvent()336 void UIExtensionPattern::HandleBlurEvent()
337 {
338     WindowPattern::DisPatchFocusActiveEvent(false);
339     TransferFocusState(false);
340     auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
341     CHECK_NULL_VOID_NOLOG(pipeline);
342     auto textFieldManager = DynamicCast<TextFieldManagerNG>(pipeline->GetTextFieldManager());
343     if (textFieldManager) {
344         textFieldManager->ClearOnFocusTextField();
345     }
346 }
347 
KeyEventConsumed(const KeyEvent & event)348 bool UIExtensionPattern::KeyEventConsumed(const KeyEvent& event)
349 {
350     bool isConsumed = false;
351     WindowPattern::DispatchKeyEventForConsumed(event.rawKeyEvent, isConsumed);
352     return isConsumed;
353 }
354 
OnKeyEvent(const KeyEvent & event)355 bool UIExtensionPattern::OnKeyEvent(const KeyEvent& event)
356 {
357     if (event.code == KeyCode::KEY_TAB && event.action == KeyAction::DOWN) {
358         auto pipeline = PipelineContext::GetCurrentContext();
359         CHECK_NULL_RETURN(pipeline, false);
360         // tab trigger consume the key event
361         return pipeline->IsTabJustTriggerOnKeyEvent();
362     } else {
363         return KeyEventConsumed(event);
364     }
365 }
366 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)367 void UIExtensionPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
368 {
369     if (touchEvent_) {
370         return;
371     }
372     auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
373         auto pattern = weak.Upgrade();
374         if (pattern) {
375             pattern->HandleTouchEvent(info);
376         }
377     };
378     if (touchEvent_) {
379         gestureHub->RemoveTouchEvent(touchEvent_);
380     }
381     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
382     gestureHub->AddTouchEvent(touchEvent_);
383 }
384 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)385 void UIExtensionPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
386 {
387     if (mouseEvent_) {
388         return;
389     }
390     auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
391         auto pattern = weak.Upgrade();
392         if (pattern) {
393             pattern->HandleMouseEvent(info);
394         }
395     };
396     if (mouseEvent_) {
397         inputHub->RemoveOnMouseEvent(mouseEvent_);
398     }
399     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
400     inputHub->AddOnMouseEvent(mouseEvent_);
401 }
402 
HandleTouchEvent(const TouchEventInfo & info)403 void UIExtensionPattern::HandleTouchEvent(const TouchEventInfo& info)
404 {
405     if (info.GetSourceDevice() != SourceType::TOUCH) {
406         return;
407     }
408     const auto pointerEvent = info.GetPointerEvent();
409     CHECK_NULL_VOID_NOLOG(pointerEvent);
410     auto host = GetHost();
411     CHECK_NULL_VOID_NOLOG(host);
412     auto selfGlobalOffset = host->GetTransformRelativeOffset();
413     auto scale = host->GetTransformScale();
414     Platform::CalculatePointerEvent(selfGlobalOffset, pointerEvent, scale);
415     auto hub = host->GetFocusHub();
416     CHECK_NULL_VOID(hub);
417     hub->RequestFocusImmediately();
418 
419     auto touchType = info.GetTouches().front().GetTouchType();
420     if (touchType == TouchType::DOWN) {
421         auto touchOffsetToWindow = info.GetTouches().front().GetGlobalLocation();
422         auto touchOffsetToFrameNode = info.GetTouches().front().GetLocalLocation();
423         auto rectToWindow = host->GetTransformRectRelativeToWindow();
424         UpdateTextFieldManager({ rectToWindow.GetOffset().GetX(), touchOffsetToWindow.GetY() },
425             rectToWindow.Height() - touchOffsetToFrameNode.GetY());
426     }
427 
428     WindowPattern::DispatchPointerEvent(pointerEvent);
429 }
430 
HandleMouseEvent(const MouseInfo & info)431 void UIExtensionPattern::HandleMouseEvent(const MouseInfo& info)
432 {
433     if (info.GetSourceDevice() != SourceType::MOUSE) {
434         return;
435     }
436     const auto pointerEvent = info.GetPointerEvent();
437     CHECK_NULL_VOID_NOLOG(pointerEvent);
438     auto host = GetHost();
439     CHECK_NULL_VOID_NOLOG(host);
440     auto selfGlobalOffset = host->GetTransformRelativeOffset();
441     auto scale = host->GetTransformScale();
442     Platform::CalculatePointerEvent(selfGlobalOffset, pointerEvent, scale);
443     if (info.GetAction() == MouseAction::PRESS) {
444         auto hub = host->GetFocusHub();
445         CHECK_NULL_VOID(hub);
446         hub->RequestFocusImmediately();
447 
448         auto mouseOffsetToWindow = info.GetGlobalLocation();
449         auto mouseOffsetToFrameNode = info.GetLocalLocation();
450         auto rectToWindow = host->GetTransformRectRelativeToWindow();
451         UpdateTextFieldManager({ rectToWindow.GetOffset().GetX(), mouseOffsetToWindow.GetY() },
452             rectToWindow.Height() - mouseOffsetToFrameNode.GetY());
453     }
454     WindowPattern::DispatchPointerEvent(pointerEvent);
455 }
456 
OnModifyDone()457 void UIExtensionPattern::OnModifyDone()
458 {
459     Pattern::OnModifyDone();
460     auto host = GetHost();
461     CHECK_NULL_VOID_NOLOG(host);
462     auto hub = host->GetEventHub<EventHub>();
463     CHECK_NULL_VOID_NOLOG(hub);
464     auto gestureHub = hub->GetOrCreateGestureEventHub();
465     CHECK_NULL_VOID_NOLOG(gestureHub);
466     InitTouchEvent(gestureHub);
467     auto inputHub = hub->GetOrCreateInputEventHub();
468     CHECK_NULL_VOID_NOLOG(inputHub);
469     InitMouseEvent(inputHub);
470     auto focusHub = host->GetFocusHub();
471     CHECK_NULL_VOID_NOLOG(focusHub);
472     InitOnKeyEvent(focusHub);
473 }
474 
UnregisterAbilityResultListener()475 void UIExtensionPattern::UnregisterAbilityResultListener()
476 {
477     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
478 }
479 
SetOnRemoteReadyCallback(const std::function<void (const RefPtr<UIExtensionProxy> &)> && callback)480 void UIExtensionPattern::SetOnRemoteReadyCallback(const std::function<void(const RefPtr<UIExtensionProxy>&)>&& callback)
481 {
482     onRemoteReadyCallback_ = std::move(callback);
483 
484     auto pipeline = PipelineBase::GetCurrentContext();
485     CHECK_NULL_VOID_NOLOG(pipeline);
486     auto taskExecutor = pipeline->GetTaskExecutor();
487     CHECK_NULL_VOID_NOLOG(taskExecutor);
488     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
489     auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback();
490     extSessionEventCallback->notifyRemoteReadyFunc_ =
491         [weak = WeakClaim(this), instanceId = instanceId_, taskExecutor]() {
492             taskExecutor->PostTask([weak, instanceId]() {
493                 ContainerScope scope(instanceId);
494                 LOGI("UIExtension OnRemoteReady called");
495                 auto pattern = weak.Upgrade();
496                 if (pattern && pattern->onRemoteReadyCallback_) {
497                     pattern->onRemoteReadyCallback_(MakeRefPtr<UIExtensionProxy>(pattern->session_));
498                 }
499             }, TaskExecutor::TaskType::UI);
500         };
501 }
502 
SetOnReleaseCallback(const std::function<void (int32_t)> && callback)503 void UIExtensionPattern::SetOnReleaseCallback(const std::function<void(int32_t)>&& callback)
504 {
505     onReleaseCallback_ = std::move(callback);
506 }
507 
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)508 void UIExtensionPattern::SetOnErrorCallback(
509     const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
510 {
511     onErrorCallback_ = std::move(callback);
512     if (lastError_.code != 0) {
513         ErrorMsg error;
514         std::swap(lastError_, error);
515         onErrorCallback_(error.code, error.name, error.message);
516     }
517 }
518 
SetOnResultCallback(const std::function<void (int32_t,const AAFwk::Want &)> && callback)519 void UIExtensionPattern::SetOnResultCallback(const std::function<void(int32_t, const AAFwk::Want&)>&& callback)
520 {
521     onResultCallback_ = std::move(callback);
522 
523     auto pipeline = PipelineBase::GetCurrentContext();
524     CHECK_NULL_VOID_NOLOG(pipeline);
525     auto taskExecutor = pipeline->GetTaskExecutor();
526     CHECK_NULL_VOID_NOLOG(taskExecutor);
527     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
528     auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback();
529     extSessionEventCallback->transferAbilityResultFunc_ =
530         [weak = WeakClaim(this), instanceId = instanceId_, taskExecutor](int32_t code, const AAFwk::Want& want) {
531             taskExecutor->PostTask([weak, instanceId, code, want]() {
532                 ContainerScope scope(instanceId);
533                 LOGI("UIExtension OnResult called");
534                 auto pattern = weak.Upgrade();
535                 if (pattern && pattern->onResultCallback_) {
536                     pattern->onResultCallback_(code, want);
537                 }
538             }, TaskExecutor::TaskType::UI);
539         };
540 }
541 
SetOnReceiveCallback(const std::function<void (const AAFwk::WantParams &)> && callback)542 void UIExtensionPattern::SetOnReceiveCallback(const std::function<void(const AAFwk::WantParams&)>&& callback)
543 {
544     onReceiveCallback_ = std::move(callback);
545 
546     auto pipeline = PipelineBase::GetCurrentContext();
547     CHECK_NULL_VOID_NOLOG(pipeline);
548     auto taskExecutor = pipeline->GetTaskExecutor();
549     CHECK_NULL_VOID_NOLOG(taskExecutor);
550     sptr<Rosen::ExtensionSession> extensionSession(static_cast<Rosen::ExtensionSession*>(session_.GetRefPtr()));
551     auto extSessionEventCallback = extensionSession->GetExtensionSessionEventCallback();
552     extSessionEventCallback->transferExtensionDataFunc_ =
553         [weak = WeakClaim(this), instanceId = instanceId_, taskExecutor](const AAFwk::WantParams& params) {
554             taskExecutor->PostTask([weak, instanceId, params]() {
555                 ContainerScope scope(instanceId);
556                 LOGI("UIExtension OnReceive called");
557                 auto pattern = weak.Upgrade();
558                 if (pattern && pattern->onReceiveCallback_) {
559                     pattern->onReceiveCallback_(params);
560                 }
561             }, TaskExecutor::TaskType::UI);
562         };
563 }
564 
OnVisibleChange(bool visible)565 void UIExtensionPattern::OnVisibleChange(bool visible)
566 {
567     if (visible) {
568         RequestExtensionSessionActivation();
569     } else {
570         RequestExtensionSessionBackground();
571     }
572 }
573 
RegisterVisibleAreaChange()574 void UIExtensionPattern::RegisterVisibleAreaChange()
575 {
576     auto pipeline = PipelineContext::GetCurrentContext();
577     CHECK_NULL_VOID_NOLOG(pipeline);
578     auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
579         auto uiExtension = weak.Upgrade();
580         CHECK_NULL_VOID_NOLOG(uiExtension);
581         uiExtension->OnVisibleChange(visible);
582     };
583     auto host = GetHost();
584     CHECK_NULL_VOID_NOLOG(host);
585     pipeline->AddVisibleAreaChangeNode(host, 0.0f, callback, false);
586 }
587 
UpdateTextFieldManager(const Offset & offset,float height)588 void UIExtensionPattern::UpdateTextFieldManager(const Offset& offset, float height)
589 {
590     if (!IsCurrentFocus()) {
591         return;
592     }
593     auto context = GetHost()->GetContext();
594     CHECK_NULL_VOID(context);
595     auto textFieldManager = DynamicCast<TextFieldManagerNG>(context->GetTextFieldManager());
596     CHECK_NULL_VOID(textFieldManager);
597     textFieldManager->SetClickPosition(offset);
598     textFieldManager->SetHeight(height);
599     textFieldManager->SetOnFocusTextField(WeakClaim(this));
600 }
601 
IsCurrentFocus() const602 bool UIExtensionPattern::IsCurrentFocus() const
603 {
604     auto host = GetHost();
605     CHECK_NULL_RETURN_NOLOG(host, false);
606     auto focusHub = host->GetFocusHub();
607     CHECK_NULL_RETURN_NOLOG(focusHub, false);
608     return focusHub->IsCurrentFocus();
609 }
610 
GetSessionId()611 int32_t UIExtensionPattern::GetSessionId()
612 {
613     CHECK_NULL_RETURN(session_, 0);
614     return session_->GetPersistentId();
615 }
616 } // namespace OHOS::Ace::NG
617