1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/pattern/ui_extension/ui_extension_component/session_wrapper_impl.h"
17
18 #include <cmath>
19 #include <memory>
20
21 #include "accessibility_event_info.h"
22 #include "extension/extension_business_info.h"
23 #include "interfaces/include/ws_common.h"
24 #include "refbase.h"
25 #include "session_manager/include/extension_session_manager.h"
26 #include "transaction/rs_sync_transaction_controller.h"
27 #include "transaction/rs_transaction.h"
28 #include "ui/rs_surface_node.h"
29 #include "want_params.h"
30 #include "want_params_wrapper.h"
31 #include "wm/wm_common.h"
32 #include "wm/data_handler_interface.h"
33
34 #include "adapter/ohos/entrance/ace_container.h"
35 #include "adapter/ohos/osal/want_wrap_ohos.h"
36 #include "base/error/error_code.h"
37 #include "base/utils/utils.h"
38 #include "core/common/container.h"
39 #include "core/common/container_scope.h"
40 #include "core/components_ng/pattern/ui_extension/session_wrapper.h"
41 #include "core/components_ng/pattern/ui_extension/ui_extension_container_handler.h"
42 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
43 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45 #include "pointer_event.h"
46 #include "string_wrapper.h"
47 #include "render_service_client/core/ui/rs_ui_director.h"
48 #include "render_service_client/core/ui/rs_ui_context.h"
49
50 namespace OHOS::Ace::NG {
51 namespace {
52 // Defines all error names and messages.
53 constexpr char START_FAIL_NAME[] = "start_ability_fail";
54 constexpr char START_FAIL_MESSAGE[] = "Start ui extension ability failed, please check the want of UIextensionAbility.";
55 constexpr char BACKGROUND_FAIL_NAME[] = "background_fail";
56 constexpr char BACKGROUND_FAIL_MESSAGE[] = "background ui extension ability failed, please check AMS log.";
57 constexpr char TERMINATE_FAIL_NAME[] = "terminate_fail";
58 constexpr char TERMINATE_FAIL_MESSAGE[] = "terminate ui extension ability failed, please check AMS log.";
59 constexpr char PULL_FAIL_NAME[] = "extension_pulling_up_fail";
60 constexpr char PULL_FAIL_MESSAGE[] = "pulling another embedded component failed, not allowed to cascade.";
61 constexpr char EXIT_ABNORMALLY_NAME[] = "extension_exit_abnormally";
62 constexpr char EXIT_ABNORMALLY_MESSAGE[] = "the extension ability exited abnormally, please check AMS log.";
63 constexpr char EXTENSION_TRANSPARENT_NAME[] = "extension_node_transparent";
64 constexpr char EXTENSION_TRANSPARENT_MESSAGE[] = "the extension ability has transparent node.";
65 constexpr char LIFECYCLE_TIMEOUT_NAME[] = "extension_lifecycle_timeout";
66 constexpr char LIFECYCLE_TIMEOUT_MESSAGE[] = "the lifecycle of extension ability is timeout, please check AMS log.";
67 constexpr char EVENT_TIMEOUT_NAME[] = "handle_event_timeout";
68 constexpr char EVENT_TIMEOUT_MESSAGE[] = "the extension ability has timed out processing the key event.";
69 constexpr char UIEXTENSION_HOST_UICONTENT_TYPE[] = "ohos.ace.uiextension.hostUicontentType";
70 // Defines the want parameter to control the soft-keyboard area change of the provider.
71 constexpr char OCCUPIED_AREA_CHANGE_KEY[] = "ability.want.params.IsNotifyOccupiedAreaChange";
72 // Set the UIExtension type of the EmbeddedComponent.
73 constexpr char UI_EXTENSION_TYPE_KEY[] = "ability.want.params.uiExtensionType";
74 constexpr const char* const UIEXTENSION_CONFIG_FIELD = "ohos.system.window.uiextension.params";
75 const std::string EMBEDDED_UI("embeddedUI");
76 constexpr int32_t AVOID_DELAY_TIME = 30;
77 constexpr int32_t INVALID_WINDOW_ID = -1;
78 } // namespace
79
IsDispatchExtensionDataToHostWindow(uint32_t customId)80 static bool IsDispatchExtensionDataToHostWindow(uint32_t customId)
81 {
82 auto businessCode = static_cast<UIContentBusinessCode>(customId);
83 return (businessCode >= UIContentBusinessCode::WINDOW_CODE_BEGIN &&
84 businessCode <= UIContentBusinessCode::WINDOW_CODE_END);
85 }
86
87 class UIExtensionLifecycleListener : public Rosen::ILifecycleListener {
88 public:
UIExtensionLifecycleListener(const WeakPtr<SessionWrapper> & sessionWrapper)89 explicit UIExtensionLifecycleListener(const WeakPtr<SessionWrapper>& sessionWrapper)
90 : sessionWrapper_(sessionWrapper)
91 {}
92 virtual ~UIExtensionLifecycleListener() = default;
93
OnActivation()94 void OnActivation() override {}
OnForeground()95 void OnForeground() override {}
OnBackground()96 void OnBackground() override {}
97
OnConnect()98 void OnConnect() override
99 {
100 auto sessionWrapper = sessionWrapper_.Upgrade();
101 CHECK_NULL_VOID(sessionWrapper);
102 sessionWrapper->OnConnect();
103 }
104
OnDisconnect()105 void OnDisconnect() override
106 {
107 auto sessionWrapper = sessionWrapper_.Upgrade();
108 CHECK_NULL_VOID(sessionWrapper);
109 sessionWrapper->OnDisconnect(false);
110 }
111
OnExtensionDied()112 void OnExtensionDied() override
113 {
114 auto sessionWrapper = sessionWrapper_.Upgrade();
115 CHECK_NULL_VOID(sessionWrapper);
116 sessionWrapper->OnDisconnect(true);
117 }
118
OnExtensionTimeout(int32_t errorCode)119 void OnExtensionTimeout(int32_t errorCode) override
120 {
121 auto sessionWrapper = sessionWrapper_.Upgrade();
122 CHECK_NULL_VOID(sessionWrapper);
123 sessionWrapper->OnExtensionTimeout(errorCode);
124 }
125
OnExtensionDetachToDisplay()126 void OnExtensionDetachToDisplay() override
127 {
128 auto sessionWrapper = sessionWrapper_.Upgrade();
129 CHECK_NULL_VOID(sessionWrapper);
130 sessionWrapper->OnExtensionDetachToDisplay();
131 }
132
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)133 void OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset) override
134 {
135 auto sessionWrapper = sessionWrapper_.Upgrade();
136 CHECK_NULL_VOID(sessionWrapper);
137 sessionWrapper->OnAccessibilityEvent(info, uiExtensionOffset);
138 }
139
140 private:
141 WeakPtr<SessionWrapper> sessionWrapper_;
142 };
143
144 /************************************************ Begin: Initialization ***********************************************/
SessionWrapperImpl(const WeakPtr<UIExtensionPattern> & hostPattern,int32_t instanceId,bool isTransferringCaller,SessionType sessionType)145 SessionWrapperImpl::SessionWrapperImpl(const WeakPtr<UIExtensionPattern>& hostPattern, int32_t instanceId,
146 bool isTransferringCaller, SessionType sessionType)
147 : hostPattern_(hostPattern), instanceId_(instanceId), isTransferringCaller_(isTransferringCaller),
148 sessionType_(sessionType)
149 {
150 auto pattern = hostPattern.Upgrade();
151 uiExtensionId_ = pattern ? pattern->GetUiExtensionId() : 0;
152 taskExecutor_ = Container::CurrentTaskExecutor();
153 }
154
~SessionWrapperImpl()155 SessionWrapperImpl::~SessionWrapperImpl() {}
156
InitForegroundCallback()157 void SessionWrapperImpl::InitForegroundCallback()
158 {
159 CHECK_NULL_VOID(session_);
160 CHECK_NULL_VOID(taskExecutor_);
161 int32_t callSessionId = GetSessionId();
162 foregroundCallback_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
163 weak = hostPattern_, callSessionId] (OHOS::Rosen::WSError errcode) {
164 if (errcode == OHOS::Rosen::WSError::WS_OK) {
165 return;
166 }
167
168 auto taskExecutor = weakTaskExecutor.Upgrade();
169 if (taskExecutor == nullptr) {
170 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
171 "InitForegroundCallback: taskExecutor is nullptr");
172 return;
173 }
174
175 taskExecutor->PostTask(
176 [weak, errcode, callSessionId] {
177 auto pattern = weak.Upgrade();
178 CHECK_NULL_VOID(pattern);
179 if (callSessionId != pattern->GetSessionId()) {
180 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
181 "foregroundCallback_: The callSessionId(%{public}d)"
182 " is inconsistent with the curSession(%{public}d)",
183 callSessionId, pattern->GetSessionId());
184 return;
185 }
186
187 int32_t code = pattern->IsCompatibleOldVersion()
188 ? static_cast<int32_t>(errcode) : ERROR_CODE_UIEXTENSION_FOREGROUND_FAILED;
189 pattern->FireOnErrorCallback(code, START_FAIL_NAME, START_FAIL_MESSAGE);
190 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionForegroundError");
191 };
192 }
193
InitBackgroundCallback()194 void SessionWrapperImpl::InitBackgroundCallback()
195 {
196 CHECK_NULL_VOID(session_);
197 CHECK_NULL_VOID(taskExecutor_);
198 int32_t callSessionId = GetSessionId();
199 backgroundCallback_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
200 weak = hostPattern_, callSessionId] (OHOS::Rosen::WSError errcode) {
201 if (errcode == OHOS::Rosen::WSError::WS_OK) {
202 return;
203 }
204
205 auto taskExecutor = weakTaskExecutor.Upgrade();
206 if (taskExecutor == nullptr) {
207 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
208 "InitBackgroundCallback: taskExecutor is nullptr");
209 return;
210 }
211
212 taskExecutor->PostTask(
213 [weak, errcode, callSessionId] {
214 auto pattern = weak.Upgrade();
215 CHECK_NULL_VOID(pattern);
216 if (callSessionId != pattern->GetSessionId()) {
217 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
218 "backgroundCallback_: The callSessionId(%{public}d)"
219 " is inconsistent with the curSession(%{public}d)",
220 callSessionId, pattern->GetSessionId());
221 return;
222 }
223
224 int32_t code = pattern->IsCompatibleOldVersion()
225 ? static_cast<int32_t>(errcode) : ERROR_CODE_UIEXTENSION_BACKGROUND_FAILED;
226 pattern->FireOnErrorCallback(
227 code, BACKGROUND_FAIL_NAME, BACKGROUND_FAIL_MESSAGE);
228 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionBackgroundError");
229 };
230 }
231
InitDestructionCallback()232 void SessionWrapperImpl::InitDestructionCallback()
233 {
234 CHECK_NULL_VOID(session_);
235 CHECK_NULL_VOID(taskExecutor_);
236 int32_t callSessionId = GetSessionId();
237 destructionCallback_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
238 weak = hostPattern_, callSessionId] (OHOS::Rosen::WSError errcode) {
239 if (errcode == OHOS::Rosen::WSError::WS_OK) {
240 return;
241 }
242
243 auto taskExecutor = weakTaskExecutor.Upgrade();
244 if (taskExecutor == nullptr) {
245 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
246 "InitDestructionCallback: taskExecutor is nullptr");
247 return;
248 }
249
250 taskExecutor->PostTask(
251 [weak, errcode, callSessionId] {
252 auto pattern = weak.Upgrade();
253 CHECK_NULL_VOID(pattern);
254 if (callSessionId != pattern->GetSessionId()) {
255 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
256 "destructionCallback_: The callSessionId(%{public}d)"
257 " is inconsistent with the curSession(%{public}d)",
258 callSessionId, pattern->GetSessionId());
259 return;
260 }
261
262 int32_t code = pattern->IsCompatibleOldVersion()
263 ? static_cast<int32_t>(errcode) : ERROR_CODE_UIEXTENSION_DESTRUCTION_FAILED;
264 pattern->FireOnErrorCallback(
265 code, TERMINATE_FAIL_NAME, TERMINATE_FAIL_MESSAGE);
266 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionDestructionError");
267 };
268 }
269
InitTransferAbilityResultFunc()270 void SessionWrapperImpl::InitTransferAbilityResultFunc()
271 {
272 CHECK_NULL_VOID(session_);
273 CHECK_NULL_VOID(taskExecutor_);
274 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
275 if (sessionCallbacks == nullptr) {
276 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
277 "InitTransferAbilityResultFunc: sessionCallbacks is nullptr");
278 return;
279 }
280
281 int32_t callSessionId = GetSessionId();
282 sessionCallbacks->transferAbilityResultFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
283 weak = hostPattern_, sessionType = sessionType_, callSessionId] (
284 int32_t code, const AAFwk::Want& want) {
285 auto taskExecutor = weakTaskExecutor.Upgrade();
286 if (taskExecutor == nullptr) {
287 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
288 "InitTransferAbilityResultFunc: taskExecutor is nullptr");
289 return;
290 }
291
292 taskExecutor->PostTask(
293 [weak, code, want, sessionType, callSessionId] () {
294 auto pattern = weak.Upgrade();
295 CHECK_NULL_VOID(pattern);
296 if (callSessionId != pattern->GetSessionId()) {
297 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
298 "transferAbilityResultFunc_: The callSessionId(%{public}d)"
299 " is inconsistent with the curSession(%{public}d)",
300 callSessionId, pattern->GetSessionId());
301 return;
302 }
303
304 if (sessionType == SessionType::UI_EXTENSION_ABILITY
305 && pattern->IsCompatibleOldVersion()) {
306 pattern->FireOnResultCallback(code, want);
307 } else {
308 pattern->FireOnTerminatedCallback(code, MakeRefPtr<WantWrapOhos>(want));
309 }
310 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionTransferAbilityResult");
311 };
312 }
313
InitTransferExtensionDataFunc()314 void SessionWrapperImpl::InitTransferExtensionDataFunc()
315 {
316 CHECK_NULL_VOID(session_);
317 CHECK_NULL_VOID(taskExecutor_);
318 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
319 if (sessionCallbacks == nullptr) {
320 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
321 "InitTransferExtensionDataFunc: sessionCallbacks is nullptr");
322 return;
323 }
324
325 int32_t callSessionId = GetSessionId();
326 sessionCallbacks->transferExtensionDataFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
327 weak = hostPattern_, callSessionId] (const AAFwk::WantParams& params) {
328 auto taskExecutor = weakTaskExecutor.Upgrade();
329 if (taskExecutor == nullptr) {
330 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
331 "InitTransferExtensionDataFunc: taskExecutor is nullptr");
332 return;
333 }
334
335 taskExecutor->PostTask(
336 [weak, params, callSessionId] () {
337 auto pattern = weak.Upgrade();
338 CHECK_NULL_VOID(pattern);
339 if (callSessionId != pattern->GetSessionId()) {
340 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
341 "transferExtensionDataFunc_: The callSessionId(%{public}d)"
342 " is inconsistent with the curSession(%{public}d)",
343 callSessionId, pattern->GetSessionId());
344 return;
345 }
346
347 pattern->FireOnReceiveCallback(params);
348 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionReceiveCallback");
349 };
350 }
351
InitNotifyRemoteReadyFunc()352 void SessionWrapperImpl::InitNotifyRemoteReadyFunc()
353 {
354 CHECK_NULL_VOID(session_);
355 CHECK_NULL_VOID(taskExecutor_);
356 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
357 if (sessionCallbacks == nullptr) {
358 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
359 "InitNotifyRemoteReadyFunc: sessionCallbacks is nullptr");
360 return;
361 }
362
363 int32_t callSessionId = GetSessionId();
364 sessionCallbacks->notifyRemoteReadyFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
365 weak = hostPattern_, callSessionId] () {
366 auto taskExecutor = weakTaskExecutor.Upgrade();
367 if (taskExecutor == nullptr) {
368 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
369 "InitNotifyRemoteReadyFunc: taskExecutor is nullptr");
370 return;
371 }
372
373 taskExecutor->PostTask(
374 [weak, callSessionId] () {
375 auto pattern = weak.Upgrade();
376 CHECK_NULL_VOID(pattern);
377 if (callSessionId != pattern->GetSessionId()) {
378 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
379 "notifyRemoteReadyFunc_: The callSessionId(%{public}d)"
380 " is inconsistent with the curSession(%{public}d)",
381 callSessionId, pattern->GetSessionId());
382 return;
383 }
384
385 pattern->FireOnRemoteReadyCallback();
386 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionRemoteReadyCallback");
387 };
388 }
389
InitNotifySyncOnFunc()390 void SessionWrapperImpl::InitNotifySyncOnFunc()
391 {
392 CHECK_NULL_VOID(session_);
393 CHECK_NULL_VOID(taskExecutor_);
394 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
395 if (sessionCallbacks == nullptr) {
396 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
397 "InitNotifySyncOnFunc: sessionCallbacks is nullptr");
398 return;
399 }
400
401 int32_t callSessionId = GetSessionId();
402 sessionCallbacks->notifySyncOnFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
403 weak = hostPattern_, callSessionId] () {
404 auto taskExecutor = weakTaskExecutor.Upgrade();
405 if (taskExecutor == nullptr) {
406 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
407 "InitNotifySyncOnFunc: taskExecutor is nullptr");
408 return;
409 }
410
411 taskExecutor->PostTask(
412 [weak, callSessionId] () {
413 auto pattern = weak.Upgrade();
414 CHECK_NULL_VOID(pattern);
415 if (callSessionId != pattern->GetSessionId()) {
416 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
417 "notifySyncOnFunc_: The callSessionId(%{public}d)"
418 " is inconsistent with the curSession(%{public}d)",
419 callSessionId, pattern->GetSessionId());
420 return;
421 }
422
423 pattern->FireSyncCallbacks();
424 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionSyncCallbacks");
425 };
426 }
427
InitNotifyAsyncOnFunc()428 void SessionWrapperImpl::InitNotifyAsyncOnFunc()
429 {
430 CHECK_NULL_VOID(session_);
431 CHECK_NULL_VOID(taskExecutor_);
432 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
433 if (sessionCallbacks == nullptr) {
434 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
435 "InitNotifyAsyncOnFunc: sessionCallbacks is nullptr");
436 return;
437 }
438
439 int32_t callSessionId = GetSessionId();
440 sessionCallbacks->notifyAsyncOnFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
441 weak = hostPattern_, callSessionId] () {
442 auto taskExecutor = weakTaskExecutor.Upgrade();
443 if (taskExecutor == nullptr) {
444 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
445 "InitNotifyAsyncOnFunc: taskExecutor is nullptr");
446 return;
447 }
448
449 taskExecutor->PostTask(
450 [weak, callSessionId] () {
451 auto pattern = weak.Upgrade();
452 CHECK_NULL_VOID(pattern);
453 if (callSessionId != pattern->GetSessionId()) {
454 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
455 "notifyAsyncOnFunc_: The callSessionId(%{public}d)"
456 " is inconsistent with the curSession(%{public}d)",
457 callSessionId, pattern->GetSessionId());
458 return;
459 }
460 pattern->FireAsyncCallbacks();
461 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionAsyncCallbacks");
462 };
463 }
464
InitNotifyBindModalFunc()465 void SessionWrapperImpl::InitNotifyBindModalFunc()
466 {
467 CHECK_NULL_VOID(session_);
468 CHECK_NULL_VOID(taskExecutor_);
469 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
470 if (sessionCallbacks == nullptr) {
471 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
472 "InitNotifyBindModalFunc: sessionCallbacks is nullptr");
473 return;
474 }
475
476 int32_t callSessionId = GetSessionId();
477 sessionCallbacks->notifyBindModalFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
478 weak = hostPattern_, callSessionId] () {
479 auto taskExecutor = weakTaskExecutor.Upgrade();
480 if (taskExecutor == nullptr) {
481 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
482 "InitNotifyBindModalFunc: taskExecutor is nullptr");
483 return;
484 }
485
486 taskExecutor->PostSyncTask(
487 [weak, callSessionId] () {
488 auto pattern = weak.Upgrade();
489 CHECK_NULL_VOID(pattern);
490 if (callSessionId != pattern->GetSessionId()) {
491 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
492 "notifyBindModalFunc_: The callSessionId(%{public}d)"
493 " is inconsistent with the curSession(%{public}d)",
494 callSessionId, pattern->GetSessionId());
495 return;
496 }
497
498 pattern->FireBindModalCallback();
499 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionBindModalCallback");
500 };
501 }
502
InitNotifyGetAvoidAreaByTypeFunc()503 void SessionWrapperImpl::InitNotifyGetAvoidAreaByTypeFunc()
504 {
505 CHECK_NULL_VOID(session_);
506 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
507 if (sessionCallbacks == nullptr) {
508 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
509 "InitNotifyGetAvoidAreaByTypeFunc: sessionCallbacks is nullptr");
510 return;
511 }
512
513 sessionCallbacks->notifyGetAvoidAreaByTypeFunc_ =
514 [instanceId = instanceId_] (Rosen::AvoidAreaType type, int32_t apiVersion) -> Rosen::AvoidArea {
515 Rosen::AvoidArea avoidArea;
516 auto container = Platform::AceContainer::GetContainer(instanceId);
517 CHECK_NULL_RETURN(container, avoidArea);
518 avoidArea = container->GetAvoidAreaByType(type, apiVersion);
519 return avoidArea;
520 };
521 }
522
InitNotifyExtensionEventFunc()523 void SessionWrapperImpl::InitNotifyExtensionEventFunc()
524 {
525 CHECK_NULL_VOID(session_);
526 CHECK_NULL_VOID(taskExecutor_);
527 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
528 if (sessionCallbacks == nullptr) {
529 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
530 "InitNotifyExtensionEventFunc: sessionCallbacks is nullptr");
531 return;
532 }
533
534 int32_t callSessionId = GetSessionId();
535 sessionCallbacks->notifyExtensionEventFunc_ = [weakTaskExecutor = WeakClaim(RawPtr(taskExecutor_)),
536 weak = hostPattern_, callSessionId] (uint32_t eventId) {
537 auto taskExecutor = weakTaskExecutor.Upgrade();
538 if (taskExecutor == nullptr) {
539 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
540 "InitNotifyExtensionEventFunc: taskExecutor is nullptr");
541 return;
542 }
543
544 taskExecutor->PostTask(
545 [weak, callSessionId, eventId] () {
546 auto pattern = weak.Upgrade();
547 CHECK_NULL_VOID(pattern);
548 if (callSessionId != pattern->GetSessionId()) {
549 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
550 "notifyBindModalFunc_: The callSessionId(%{public}d)"
551 " is inconsistent with the curSession(%{public}d)",
552 callSessionId, pattern->GetSessionId());
553 return;
554 }
555
556 pattern->OnExtensionEvent(static_cast<UIExtCallbackEventId>(eventId));
557 }, TaskExecutor::TaskType::UI, "ArkUIUIExtensionEventCallback");
558 };
559 }
560
InitGetStatusBarHeightFunc()561 void SessionWrapperImpl::InitGetStatusBarHeightFunc()
562 {
563 CHECK_NULL_VOID(session_);
564 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
565 if (sessionCallbacks == nullptr) {
566 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
567 "InitGetStatusBarHeightFunc: sessionCallbacks is nullptr");
568 return;
569 }
570
571 sessionCallbacks->getStatusBarHeightFunc_ = [instanceId = instanceId_]() -> uint32_t {
572 auto container = Platform::AceContainer::GetContainer(instanceId);
573 CHECK_NULL_RETURN(container, 0);
574 return container->GetStatusBarHeight();
575 };
576 }
577
InitAllCallback()578 void SessionWrapperImpl::InitAllCallback()
579 {
580 CHECK_NULL_VOID(session_);
581 int32_t callSessionId = GetSessionId();
582 if (!taskExecutor_) {
583 LOGE("taskExecutor_ is nullptr, the sessionid = %{public}d", callSessionId);
584 return;
585 }
586
587 InitForegroundCallback();
588 InitBackgroundCallback();
589 InitDestructionCallback();
590
591 // Init SessionEventCallback
592 auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
593 if (sessionCallbacks == nullptr) {
594 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
595 "InitAllCallback: sessionCallbacks is nullptr");
596 return;
597 }
598
599 InitTransferAbilityResultFunc();
600 InitTransferExtensionDataFunc();
601 InitNotifyRemoteReadyFunc();
602 InitNotifySyncOnFunc();
603 InitNotifyAsyncOnFunc();
604 InitNotifyBindModalFunc();
605 InitNotifyGetAvoidAreaByTypeFunc();
606 InitNotifyExtensionEventFunc();
607 InitGetStatusBarHeightFunc();
608 }
609
UpdateInstanceId(int32_t instanceId)610 void SessionWrapperImpl::UpdateInstanceId(int32_t instanceId)
611 {
612 if (instanceId_ == instanceId) {
613 UIEXT_LOGW("InstanceId(%{public}d) has not changed when UpdateInstanceId.", instanceId);
614 return;
615 }
616
617 UIEXT_LOGI("Update instanceId %{public}d to %{public}d.", instanceId_, instanceId);
618 auto container = Container::GetContainer(instanceId);
619 CHECK_NULL_VOID(container);
620 auto taskExecutor = container->GetTaskExecutor();
621 CHECK_NULL_VOID(taskExecutor);
622 instanceId_ = instanceId;
623 taskExecutor_ = taskExecutor;
624 InitAllCallback();
625 UIEXT_LOGI("Update instanceId success.");
626 }
627 /************************************************ End: Initialization *************************************************/
628
629 /************************************************ Begin: About session ************************************************/
ConvertToRosenSessionViewportConfig(const SessionViewportConfig & config)630 Rosen::SessionViewportConfig ConvertToRosenSessionViewportConfig(const SessionViewportConfig& config)
631 {
632 Rosen::SessionViewportConfig config_ = {
633 .isDensityFollowHost_ = config.isDensityFollowHost_,
634 .density_ = config.density_,
635 .displayId_ = config.displayId_,
636 .orientation_ = config.orientation_,
637 .transform_ = config.transform_,
638 };
639 return config_;
640 }
641
CreateSession(const AAFwk::Want & want,const SessionConfig & config)642 void SessionWrapperImpl::CreateSession(const AAFwk::Want& want, const SessionConfig& config)
643 {
644 ContainerScope scope(instanceId_);
645 UIEXT_LOGI("The session is created with bundle=%{public}s, ability=%{public}s, componentId=%{public}d.",
646 want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str(), GetFrameNodeId());
647 auto container = Platform::AceContainer::GetContainer(instanceId_);
648 CHECK_NULL_VOID(container);
649 auto pipeline = container->GetPipelineContext();
650 CHECK_NULL_VOID(pipeline);
651 auto realHostWindowId = pipeline->GetRealHostWindowId();
652 customWant_ = std::make_shared<Want>(want);
653 auto wantPtr = std::make_shared<Want>(want);
654 UpdateWantPtr(wantPtr);
655 if (sessionType_ == SessionType::UI_EXTENSION_ABILITY) {
656 if (wantPtr->GetStringParam(UI_EXTENSION_TYPE_KEY) == EMBEDDED_UI) {
657 UIEXT_LOGE("The UIExtensionComponent is not allowed to start the EmbeddedUIExtensionAbility.");
658 return;
659 }
660 if ((container->IsUIExtensionAbilityHost() && container->IsUIExtensionSubWindow())) {
661 UIEXT_LOGE("The UIExtensionComponent does not allow nested pulling of another.");
662 auto pattern = hostPattern_.Upgrade();
663 CHECK_NULL_VOID(pattern);
664 pattern->FireOnErrorCallback(ERROR_CODE_UIEXTENSION_FORBID_CASCADE, PULL_FAIL_NAME, PULL_FAIL_MESSAGE);
665 return;
666 }
667 }
668 if (sessionType_ == SessionType::EMBEDDED_UI_EXTENSION) {
669 if ((container->IsUIExtensionWindow()) ||
670 (container->IsUIExtensionAbilityProcess() && container->IsUIExtensionSubWindow())) {
671 UIEXT_LOGE("The EmbeddedComponent does not allow nested pulling of another.");
672 auto pattern = hostPattern_.Upgrade();
673 CHECK_NULL_VOID(pattern);
674 pattern->FireOnErrorCallback(ERROR_CODE_UIEXTENSION_FORBID_CASCADE, PULL_FAIL_NAME, PULL_FAIL_MESSAGE);
675 return;
676 }
677 WantParams wantParams;
678 wantPtr->SetParam(UI_EXTENSION_TYPE_KEY, EMBEDDED_UI);
679 }
680 isNotifyOccupiedAreaChange_ = want.GetBoolParam(OCCUPIED_AREA_CHANGE_KEY, true);
681 uint32_t parentWindowType = 0;
682 if (container->IsUIExtensionWindow()) {
683 parentWindowType = container->GetParentWindowType();
684 } else {
685 parentWindowType = container->GetWindowType();
686 }
687 UIEXT_LOGI("Want param isNotifyOccupiedAreaChange is %{public}d, realHostWindowId: %{public}u,"
688 " parentWindowType: %{public}u",
689 isNotifyOccupiedAreaChange_, realHostWindowId, parentWindowType);
690 auto callerToken = container->GetToken();
691 auto parentToken = container->GetParentToken();
692 auto context = PipelineContext::GetCurrentContext();
693 CHECK_NULL_VOID(context);
694 auto pattern = hostPattern_.Upgrade();
695 CHECK_NULL_VOID(pattern);
696 SessionViewportConfig sessionViewportConfig;
697 sessionViewportConfig.isDensityFollowHost_ = pattern->GetDensityDpi();
698 sessionViewportConfig.density_ = context->GetCurrentDensity();
699 sessionViewportConfig.displayId_ = container->GetCurrentDisplayId();
700 sessionViewportConfig.orientation_ = static_cast<int32_t>(SystemProperties::GetDeviceOrientation());
701 sessionViewportConfig.transform_ = context->GetTransformHint();
702 pattern->SetSessionViewportConfig(sessionViewportConfig);
703 Rosen::SessionInfo extensionSessionInfo;
704 extensionSessionInfo.bundleName_ = want.GetElement().GetBundleName();
705 extensionSessionInfo.abilityName_ = want.GetElement().GetAbilityName();
706 extensionSessionInfo.callerToken_ = callerToken;
707 extensionSessionInfo.rootToken_ = (isTransferringCaller_ && parentToken) ? parentToken : callerToken;
708 extensionSessionInfo.want = wantPtr;
709 extensionSessionInfo.parentWindowType_ = parentWindowType;
710 extensionSessionInfo.realParentId_ = static_cast<int32_t>(realHostWindowId);
711 extensionSessionInfo.uiExtensionUsage_ = static_cast<uint32_t>(config.uiExtensionUsage);
712 extensionSessionInfo.isAsyncModalBinding_ = config.isAsyncModalBinding;
713 extensionSessionInfo.config_ = ConvertToRosenSessionViewportConfig(sessionViewportConfig);
714 session_ = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSession(extensionSessionInfo);
715 CHECK_NULL_VOID(session_);
716 UpdateSessionConfig();
717 lifecycleListener_ = std::make_shared<UIExtensionLifecycleListener>(AceType::WeakClaim(this));
718 session_->RegisterLifecycleListener(lifecycleListener_);
719 InitAllCallback();
720 RegisterDataConsumer();
721 }
722
UpdateSessionConfig()723 void SessionWrapperImpl::UpdateSessionConfig()
724 {
725 auto extConfig = session_->GetSystemConfig();
726 auto pipeline = PipelineBase::GetCurrentContext();
727 CHECK_NULL_VOID(pipeline);
728 auto hostConfig = pipeline->GetKeyboardAnimationConfig();
729 extConfig.animationIn_ = {
730 hostConfig.curveIn_.curveType_, hostConfig.curveIn_.curveParams_, hostConfig.curveIn_.duration_};
731 extConfig.animationOut_ = {
732 hostConfig.curveOut_.curveType_, hostConfig.curveOut_.curveParams_, hostConfig.curveOut_.duration_};
733 session_->SetSystemConfig(extConfig);
734 }
735
DestroySession()736 void SessionWrapperImpl::DestroySession()
737 {
738 CHECK_NULL_VOID(session_);
739 UIEXT_LOGI("DestroySession, persistentid=%{public}d, componentId=%{public}d.",
740 session_->GetPersistentId(), GetFrameNodeId());
741 session_->UnregisterLifecycleListener(lifecycleListener_);
742 auto dataHandler = session_->GetExtensionDataHandler();
743 if (dataHandler) {
744 dataHandler->UnregisterDataConsumer(subSystemId_);
745 }
746 customWant_ = nullptr;
747 session_ = nullptr;
748 }
749
UpdateWantPtr(std::shared_ptr<AAFwk::Want> & wantPtr)750 void SessionWrapperImpl::UpdateWantPtr(std::shared_ptr<AAFwk::Want>& wantPtr)
751 {
752 CHECK_NULL_VOID(wantPtr);
753 AAFwk::WantParams configParam;
754 auto container = Platform::AceContainer::GetContainer(GetInstanceId());
755 CHECK_NULL_VOID(container);
756 container->GetExtensionConfig(configParam);
757 auto str = UIExtensionContainerHandler::FromUIContentTypeToStr(container->GetUIContentType());
758 configParam.SetParam(UIEXTENSION_HOST_UICONTENT_TYPE, AAFwk::String::Box(str));
759 AAFwk::WantParams wantParam(wantPtr->GetParams());
760 wantParam.SetParam(UIEXTENSION_CONFIG_FIELD, AAFwk::WantParamWrapper::Box(configParam));
761 wantPtr->SetParams(wantParam);
762 }
763
ReDispatchWantParams()764 void SessionWrapperImpl::ReDispatchWantParams()
765 {
766 CHECK_NULL_VOID(session_);
767 auto dataHandler = session_->GetExtensionDataHandler();
768 CHECK_NULL_VOID(dataHandler);
769 AAFwk::WantParams configParam;
770 auto container = Platform::AceContainer::GetContainer(GetInstanceId());
771 CHECK_NULL_VOID(container);
772 container->GetExtensionConfig(configParam);
773 AAFwk::WantParams wantParam(customWant_->GetParams());
774 wantParam.SetParam(UIEXTENSION_CONFIG_FIELD, AAFwk::WantParamWrapper::Box(configParam));
775 AAFwk::Want dataToSend;
776 dataToSend.SetParams(wantParam);
777 dataHandler->SendDataAsync(Rosen::SubSystemId::WM_UIEXT,
778 static_cast<uint32_t>(OHOS::Rosen::Extension::Businesscode::SYNC_WANT_PARAMS), dataToSend);
779 }
780
IsSessionValid()781 bool SessionWrapperImpl::IsSessionValid()
782 {
783 return session_ != nullptr;
784 }
785
GetSessionId() const786 int32_t SessionWrapperImpl::GetSessionId() const
787 {
788 return session_ ? session_->GetPersistentId() : 0;
789 }
790
GetInstanceId() const791 int32_t SessionWrapperImpl::GetInstanceId() const
792 {
793 return instanceId_;
794 }
795
GetWant()796 const std::shared_ptr<AAFwk::Want> SessionWrapperImpl::GetWant()
797 {
798 return session_ ? customWant_ : nullptr;
799 }
800 /************************************************ End: About session **************************************************/
801
802 /************************************************ Begin: Synchronous interface for event notify ***********************/
NotifyFocusEventSync(bool isFocus)803 bool SessionWrapperImpl::NotifyFocusEventSync(bool isFocus)
804 {
805 return false;
806 }
NotifyFocusStateSync(bool focusState)807 bool SessionWrapperImpl::NotifyFocusStateSync(bool focusState)
808 {
809 return false;
810 }
811
NotifyBackPressedSync()812 bool SessionWrapperImpl::NotifyBackPressedSync()
813 {
814 CHECK_NULL_RETURN(session_, false);
815 bool isConsumed = false;
816 session_->TransferBackPressedEventForConsumed(isConsumed);
817 UIEXT_LOGI("Back event notified to uiextension, persistentid=%{public}d and %{public}s consumed,"
818 " componentId=%{public}d.", GetSessionId(), isConsumed ? "is" : "is not", GetFrameNodeId());
819 return isConsumed;
820 }
821
NotifyPointerEventSync(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)822 bool SessionWrapperImpl::NotifyPointerEventSync(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
823 {
824 return false;
825 }
826
NotifyKeyEventSync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)827 bool SessionWrapperImpl::NotifyKeyEventSync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
828 {
829 CHECK_NULL_RETURN(session_, false);
830 bool isConsumed = false;
831 bool isTimeout = false;
832 session_->TransferKeyEventForConsumed(keyEvent, isConsumed, isTimeout, isPreIme);
833 auto pattern = hostPattern_.Upgrade();
834 if (isTimeout && pattern) {
835 pattern->FireOnErrorCallback(ERROR_CODE_UIEXTENSION_EVENT_TIMEOUT, EVENT_TIMEOUT_NAME, EVENT_TIMEOUT_MESSAGE);
836 return false;
837 }
838 UIEXT_LOGI("Key event notified to uiextension, persistentid = %{public}d and %{public}s consumed,"
839 " componentId=%{public}d.", GetSessionId(), isConsumed ? "is" : "is not", GetFrameNodeId());
840 return isConsumed;
841 }
842
NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)843 bool SessionWrapperImpl::NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
844 {
845 CHECK_NULL_RETURN(session_, false);
846 session_->TransferKeyEventAsync(keyEvent, isPreIme);
847 return true;
848 }
849
NotifyAxisEventSync(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)850 bool SessionWrapperImpl::NotifyAxisEventSync(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
851 {
852 return false;
853 }
854 /************************************************ End: Synchronous interface for event notify *************************/
855
856 /************************************************ Begin: Asynchronous interface for event notify **********************/
NotifyFocusEventAsync(bool isFocus)857 bool SessionWrapperImpl::NotifyFocusEventAsync(bool isFocus)
858 {
859 CHECK_NULL_RETURN(session_, false);
860 UIEXT_LOGI("Notify uiextension, persistentid = %{public}d to %{public}s the focus state,"
861 " componentId=%{public}d.", GetSessionId(), isFocus ? "paint" : "clear", GetFrameNodeId());
862 session_->TransferFocusActiveEvent(isFocus);
863 return true;
864 }
865
NotifyFocusStateAsync(bool focusState)866 bool SessionWrapperImpl::NotifyFocusStateAsync(bool focusState)
867 {
868 CHECK_NULL_RETURN(session_, false);
869 UIEXT_LOGI("%{public}s state notified to uiextension, persistentid = %{public}d,"
870 " componentId=%{public}d.", focusState ? "focused" : "unfocused", GetSessionId(), GetFrameNodeId());
871 session_->TransferFocusStateEvent(focusState);
872 return true;
873 }
874
NotifyBackPressedAsync()875 bool SessionWrapperImpl::NotifyBackPressedAsync()
876 {
877 return false;
878 }
NotifyPointerEventAsync(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)879 bool SessionWrapperImpl::NotifyPointerEventAsync(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
880 {
881 if (!pointerEvent) {
882 UIEXT_LOGE("Transfer pointer event to uiextension fail with null pointerEvent,"
883 " componentId=%{public}d.", GetFrameNodeId());
884 return false;
885 }
886
887 if (!session_) {
888 UIEXT_LOGE("Transfer pointer event to uiextension fail with null session, 'id = %{public}d',"
889 " componentId=%{public}d.", pointerEvent->GetId(), GetFrameNodeId());
890 return false;
891 }
892
893 session_->TransferPointerEvent(pointerEvent);
894 return false;
895 }
NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent)896 bool SessionWrapperImpl::NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent)
897 {
898 if (session_ && keyEvent) {
899 UIEXT_LOGI("Transfer key event with 'id = %{public}d' to uiextension, persistentid = %{public}d,"
900 " componentId=%{public}d.", keyEvent->GetId(), GetSessionId(), GetFrameNodeId());
901 session_->TransferKeyEvent(keyEvent);
902 }
903 return false;
904 }
NotifyAxisEventAsync(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)905 bool SessionWrapperImpl::NotifyAxisEventAsync(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
906 {
907 return false;
908 }
909 /************************************************ End: Asynchronous interface for event notify ************************/
910
911 /************************************************ Begin: The lifecycle interface **************************************/
NotifyCreate()912 void SessionWrapperImpl::NotifyCreate() {}
913
GetWindowScene()914 RefPtr<SystemWindowScene> SessionWrapperImpl::GetWindowScene()
915 {
916 RefPtr<SystemWindowScene> hostPattern = nullptr;
917 auto pattern = hostPattern_.Upgrade();
918 CHECK_NULL_RETURN(pattern, hostPattern);
919 auto hostWindowNode = WindowSceneHelper::FindWindowScene(pattern->GetHost());
920 CHECK_NULL_RETURN(hostWindowNode, hostPattern);
921 auto hostNode = AceType::DynamicCast<FrameNode>(hostWindowNode);
922 CHECK_NULL_RETURN(hostNode, hostPattern);
923 hostPattern = hostNode->GetPattern<SystemWindowScene>();
924 return hostPattern;
925 }
926
GetWindowSceneId()927 int32_t SessionWrapperImpl::GetWindowSceneId()
928 {
929 auto pattern = hostPattern_.Upgrade();
930 CHECK_NULL_RETURN(pattern, INVALID_WINDOW_ID);
931 auto hostPattern = GetWindowScene();
932 CHECK_NULL_RETURN(hostPattern, INVALID_WINDOW_ID);
933 auto hostSession = hostPattern->GetSession();
934 CHECK_NULL_RETURN(hostSession, INVALID_WINDOW_ID);
935 int32_t windowSceneId = hostSession->GetPersistentId();
936 if (windowSceneId != INVALID_WINDOW_ID) {
937 pattern->RegisterWindowSceneVisibleChangeCallback(hostPattern);
938 }
939 return windowSceneId;
940 }
941
GetWindowSceneRect()942 Rosen::WSRect SessionWrapperImpl::GetWindowSceneRect()
943 {
944 Rosen::WSRect rect = {0, 0, 0, 0};
945 auto hostPattern = GetWindowScene();
946 CHECK_NULL_RETURN(hostPattern, rect);
947 auto hostSession = hostPattern->GetSession();
948 CHECK_NULL_RETURN(hostSession, rect);
949 return hostSession->GetSessionRect();
950 }
951
GetDisplayAreaWithWindowScene()952 RectF SessionWrapperImpl::GetDisplayAreaWithWindowScene()
953 {
954 RectF displayArea = displayArea_;
955 ContainerScope scope(instanceId_);
956 auto pipeline = PipelineBase::GetCurrentContext();
957 CHECK_NULL_RETURN(pipeline, displayArea);
958 auto curWindow = pipeline->GetCurrentWindowRect();
959 auto pattern = hostPattern_.Upgrade();
960 CHECK_NULL_RETURN(pattern, displayArea);
961 auto host = pattern->GetHost();
962 CHECK_NULL_RETURN(host, displayArea);
963 auto [displayOffset, err] = host->GetPaintRectGlobalOffsetWithTranslate(false, true);
964 displayArea.SetOffset(displayOffset);
965 displayArea = displayArea + OffsetF(curWindow.Left(), curWindow.Top());
966 return displayArea;
967 }
968
NotifyForeground()969 void SessionWrapperImpl::NotifyForeground()
970 {
971 ContainerScope scope(instanceId_);
972 CHECK_NULL_VOID(session_);
973 auto container = Platform::AceContainer::GetContainer(instanceId_);
974 CHECK_NULL_VOID(container);
975 auto pipeline = PipelineBase::GetCurrentContext();
976 CHECK_NULL_VOID(pipeline);
977 auto hostWindowId = pipeline->GetFocusWindowId();
978 int32_t windowSceneId = GetWindowSceneId();
979 UIEXT_LOGI("NotifyForeground, persistentid = %{public}d, hostWindowId = %{public}u,"
980 " windowSceneId = %{public}d, IsSceneBoardWindow: %{public}d, componentId=%{public}d.",
981 session_->GetPersistentId(), hostWindowId, windowSceneId, container->IsSceneBoardWindow(), GetFrameNodeId());
982 if (container->IsSceneBoardWindow() && windowSceneId != INVALID_WINDOW_ID) {
983 hostWindowId = static_cast<uint32_t>(windowSceneId);
984 }
985 auto pattern = hostPattern_.Upgrade();
986 CHECK_NULL_VOID(pattern);
987 if (pattern->IsViewportConfigChanged()) {
988 pattern->SetViewportConfigChanged(false);
989 UpdateSessionViewportConfig();
990 }
991 auto wantPtr = session_->EditSessionInfo().want;
992 UpdateWantPtr(wantPtr);
993 if (foregroundCallback_ == nullptr) {
994 InitForegroundCallback();
995 }
996 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionActivation(
997 session_, hostWindowId, std::move(foregroundCallback_));
998 }
999
NotifyBackground(bool isHandleError)1000 void SessionWrapperImpl::NotifyBackground(bool isHandleError)
1001 {
1002 CHECK_NULL_VOID(session_);
1003 UIEXT_LOGI("NotifyBackground, persistentid = %{public}d, isHandleError = %{public}d, componentId=%{public}d.",
1004 session_->GetPersistentId(), isHandleError, GetFrameNodeId());
1005 if (isHandleError) {
1006 if (backgroundCallback_ == nullptr) {
1007 InitBackgroundCallback();
1008 }
1009
1010 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionBackground(
1011 session_, std::move(backgroundCallback_));
1012 } else {
1013 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionBackground(
1014 session_, nullptr);
1015 }
1016 }
1017
OnReleaseDone()1018 void SessionWrapperImpl::OnReleaseDone()
1019 {
1020 CHECK_NULL_VOID(session_);
1021 UIEXT_LOGI("OnReleaseDone, persistentid = %{public}d, componentId=%{public}d.",
1022 session_->GetPersistentId(), GetFrameNodeId());
1023 session_->UnregisterLifecycleListener(lifecycleListener_);
1024 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestructionDone(session_);
1025 session_ = nullptr;
1026 }
1027
NotifyDestroy(bool isHandleError)1028 void SessionWrapperImpl::NotifyDestroy(bool isHandleError)
1029 {
1030 CHECK_NULL_VOID(session_);
1031 UIEXT_LOGI("NotifyDestroy, isHandleError = %{public}d, persistentid = %{public}d, componentId=%{public}d.",
1032 isHandleError, session_->GetPersistentId(), GetFrameNodeId());
1033 if (isHandleError) {
1034 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestruction(
1035 session_, std::move(destructionCallback_));
1036 } else {
1037 Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestruction(
1038 session_, nullptr);
1039 }
1040 }
1041
NotifyConfigurationUpdate()1042 void SessionWrapperImpl::NotifyConfigurationUpdate() {}
1043 /************************************************ End: The lifecycle interface ****************************************/
1044
1045 /************************************************ Begin: The interface for responsing provider ************************/
OnConnect()1046 void SessionWrapperImpl::OnConnect()
1047 {
1048 int32_t callSessionId = GetSessionId();
1049 taskExecutor_->PostTask(
1050 [weak = hostPattern_, wrapperWeak = WeakClaim(this), callSessionId]() {
1051 auto pattern = weak.Upgrade();
1052 CHECK_NULL_VOID(pattern);
1053 if (callSessionId != pattern->GetSessionId()) {
1054 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnConnect: The callSessionId(%{public}d)"
1055 " is inconsistent with the curSession(%{public}d)",
1056 callSessionId, pattern->GetSessionId());
1057 }
1058 pattern->OnConnect();
1059 auto wrapper = wrapperWeak.Upgrade();
1060 CHECK_NULL_VOID(wrapper && wrapper->session_);
1061 ContainerScope scope(wrapper->instanceId_);
1062 if (auto hostWindowNode = WindowSceneHelper::FindWindowScene(pattern->GetHost())) {
1063 auto hostNode = AceType::DynamicCast<FrameNode>(hostWindowNode);
1064 CHECK_NULL_VOID(hostNode);
1065 auto hostPattern = hostNode->GetPattern<SystemWindowScene>();
1066 CHECK_NULL_VOID(hostPattern);
1067 wrapper->session_->SetParentSession(hostPattern->GetSession());
1068 }
1069 },
1070 TaskExecutor::TaskType::UI, "ArkUIUIExtensionSessionConnect");
1071 }
1072
OnDisconnect(bool isAbnormal)1073 void SessionWrapperImpl::OnDisconnect(bool isAbnormal)
1074 {
1075 int32_t callSessionId = GetSessionId();
1076 taskExecutor_->PostTask(
1077 [weak = hostPattern_, sessionType = sessionType_, isAbnormal, callSessionId]() {
1078 auto pattern = weak.Upgrade();
1079 CHECK_NULL_VOID(pattern);
1080 if (callSessionId != pattern->GetSessionId()) {
1081 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnDisconnect: The callSessionId(%{public}d)"
1082 " is inconsistent with the curSession(%{public}d)",
1083 callSessionId, pattern->GetSessionId());
1084 return;
1085 }
1086 pattern->OnDisconnect(isAbnormal);
1087 if (sessionType == SessionType::UI_EXTENSION_ABILITY && pattern->IsCompatibleOldVersion()) {
1088 pattern->FireOnReleaseCallback(static_cast<int32_t>(isAbnormal));
1089 return;
1090 }
1091 if (isAbnormal) {
1092 pattern->FireOnErrorCallback(
1093 ERROR_CODE_UIEXTENSION_EXITED_ABNORMALLY, EXIT_ABNORMALLY_NAME, EXIT_ABNORMALLY_MESSAGE);
1094 } else {
1095 pattern->FireOnTerminatedCallback(0, nullptr);
1096 }
1097 },
1098 TaskExecutor::TaskType::UI, "ArkUIUIExtensionSessionDisconnect");
1099 }
1100
OnExtensionTimeout(int32_t errorCode)1101 void SessionWrapperImpl::OnExtensionTimeout(int32_t errorCode)
1102 {
1103 int32_t callSessionId = GetSessionId();
1104 taskExecutor_->PostTask(
1105 [weak = hostPattern_, callSessionId, errorCode]() {
1106 auto pattern = weak.Upgrade();
1107 CHECK_NULL_VOID(pattern);
1108 if (callSessionId != pattern->GetSessionId()) {
1109 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnExtensionTimeout: The callSessionId(%{public}d)"
1110 " is inconsistent with the curSession(%{public}d)",
1111 callSessionId, pattern->GetSessionId());
1112 }
1113 bool isTransparent = errorCode == ERROR_CODE_UIEXTENSION_TRANSPARENT;
1114 pattern->FireOnErrorCallback(
1115 isTransparent ? errorCode : ERROR_CODE_UIEXTENSION_LIFECYCLE_TIMEOUT,
1116 isTransparent ? EXTENSION_TRANSPARENT_NAME : LIFECYCLE_TIMEOUT_NAME,
1117 isTransparent ? EXTENSION_TRANSPARENT_MESSAGE : LIFECYCLE_TIMEOUT_MESSAGE);
1118 },
1119 TaskExecutor::TaskType::UI, "ArkUIUIExtensionTimeout");
1120 }
1121
OnExtensionDetachToDisplay()1122 void SessionWrapperImpl::OnExtensionDetachToDisplay()
1123 {
1124 UIEXT_LOGI("OnExtensionDetachToDisplay");
1125 int32_t callSessionId = GetSessionId();
1126 taskExecutor_->PostTask(
1127 [weak = hostPattern_, callSessionId]() {
1128 auto pattern = weak.Upgrade();
1129 CHECK_NULL_VOID(pattern);
1130 if (callSessionId != pattern->GetSessionId()) {
1131 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1132 "OnExtensionDetachToDisplay: The callSessionId(%{public}d)"
1133 " is inconsistent with the curSession(%{public}d)",
1134 callSessionId, pattern->GetSessionId());
1135 return;
1136 }
1137
1138 pattern->OnExtensionDetachToDisplay();
1139 },
1140 TaskExecutor::TaskType::UI, "ArkUIUIExtensionOnExtensionDetachToDisplay");
1141 }
1142
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t offset)1143 void SessionWrapperImpl::OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info, int64_t offset)
1144 {
1145 int32_t callSessionId = GetSessionId();
1146 taskExecutor_->PostTask(
1147 [weak = hostPattern_, info, offset, callSessionId]() {
1148 auto pattern = weak.Upgrade();
1149 CHECK_NULL_VOID(pattern);
1150 if (callSessionId != pattern->GetSessionId()) {
1151 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "OnAccessibilityEvent: The callSessionId(%{public}d)"
1152 " is inconsistent with the curSession(%{public}d)",
1153 callSessionId, pattern->GetSessionId());
1154 }
1155 pattern->OnAccessibilityEvent(info, offset);
1156 },
1157 TaskExecutor::TaskType::UI, "ArkUIUIExtensionAccessibilityEvent");
1158 }
1159 /************************************************** End: The interface for responsing provider ************************/
1160
1161 /************************************************ Begin: The interface about the accessibility ************************/
TransferAccessibilityHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)1162 void SessionWrapperImpl::TransferAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
1163 int32_t eventType, int64_t timeMs)
1164 {
1165 CHECK_NULL_VOID(session_);
1166 session_->TransferAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
1167 }
1168
TransferAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)1169 void SessionWrapperImpl::TransferAccessibilityChildTreeRegister(
1170 uint32_t windowId, int32_t treeId, int64_t accessibilityId)
1171 {
1172 CHECK_NULL_VOID(session_);
1173 session_->TransferAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
1174 }
1175
TransferAccessibilityChildTreeDeregister()1176 void SessionWrapperImpl::TransferAccessibilityChildTreeDeregister()
1177 {
1178 CHECK_NULL_VOID(session_);
1179 session_->TransferAccessibilityChildTreeUnregister();
1180 }
1181
TransferAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)1182 void SessionWrapperImpl::TransferAccessibilityDumpChildInfo(
1183 const std::vector<std::string>& params, std::vector<std::string>& info)
1184 {
1185 CHECK_NULL_VOID(session_);
1186 session_->TransferAccessibilityDumpChildInfo(params, info);
1187 }
1188 /************************************************ End: The interface about the accessibility **************************/
1189
1190 /***************************** Begin: The interface to control the display area and the avoid area ********************/
GetSurfaceNode() const1191 std::shared_ptr<Rosen::RSSurfaceNode> SessionWrapperImpl::GetSurfaceNode() const
1192 {
1193 return session_ ? session_->GetSurfaceNode() : nullptr;
1194 }
1195
NotifyDisplayArea(const RectF & displayArea)1196 void SessionWrapperImpl::NotifyDisplayArea(const RectF& displayArea)
1197 {
1198 CHECK_NULL_VOID(session_);
1199 auto instanceId = GetInstanceId();
1200 ContainerScope scope(instanceId);
1201 auto pipeline = PipelineBase::GetCurrentContext();
1202 CHECK_NULL_VOID(pipeline);
1203 displayAreaWindow_ = pipeline->GetCurrentWindowRect();
1204 displayArea_ = displayArea + OffsetF(displayAreaWindow_.Left(), displayAreaWindow_.Top());
1205 std::shared_ptr<Rosen::RSTransaction> transaction;
1206 auto parentSession = session_->GetParentSession();
1207 auto reason = parentSession ? parentSession->GetSizeChangeReason() : session_->GetSizeChangeReason();
1208 reason_ = (uint32_t)reason;
1209 auto persistentId = parentSession ? parentSession->GetPersistentId() : session_->GetPersistentId();
1210 int32_t duration = 0;
1211 std::shared_ptr<Rosen::RSUIDirector> rsUIDirector;
1212 auto window = pipeline->GetWindow();
1213 if (window) {
1214 rsUIDirector = window->GetRSUIDirector();
1215 }
1216 bool isNeedSyncTransaction = reason == Rosen::SizeChangeReason::ROTATION ||
1217 reason == Rosen::SizeChangeReason::SNAPSHOT_ROTATION;
1218 if (!rsUIDirector) {
1219 if (isNeedSyncTransaction) {
1220 if (transaction_.lock()) {
1221 transaction = transaction_.lock();
1222 transaction_.reset();
1223 } else if (auto transactionController = Rosen::RSSyncTransactionController::GetInstance()) {
1224 transaction = transactionController->GetRSTransaction();
1225 }
1226 if (transaction && parentSession) {
1227 duration = pipeline->GetSyncAnimationOption().GetDuration();
1228 transaction->SetDuration(duration);
1229 }
1230 }
1231 } else {
1232 auto rsUIContext = rsUIDirector->GetRSUIContext();
1233 if (isNeedSyncTransaction) {
1234 if (transaction_.lock()) {
1235 transaction = transaction_.lock();
1236 transaction_.reset();
1237 } else if (pipeline && rsUIContext) {
1238 auto transactionController = rsUIContext->GetSyncTransactionHandler();
1239 if (transactionController) {
1240 transaction = transactionController->GetRSTransaction();
1241 }
1242 } else {
1243 auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
1244 if (transactionController) {
1245 transaction = transactionController->GetRSTransaction();
1246 }
1247 }
1248 if (transaction && parentSession) {
1249 duration = pipeline->GetSyncAnimationOption().GetDuration();
1250 transaction->SetDuration(duration);
1251 }
1252 }
1253 }
1254 ACE_SCOPED_TRACE("NotifyDisplayArea displayArea[%s], curWindow[%s], reason[%d], duration[%d], componentId[%d]",
1255 displayArea_.ToString().c_str(), displayAreaWindow_.ToString().c_str(), reason, duration, GetFrameNodeId());
1256 UIEXT_LOGD("NotifyDisplayArea displayArea=%{public}s, curWindow=%{public}s, "
1257 "reason=%{public}d, duration=%{public}d, persistentId=%{public}d, componentId=%{public}d.",
1258 displayArea_.ToString().c_str(), displayAreaWindow_.ToString().c_str(),
1259 reason, duration, persistentId, GetFrameNodeId());
1260 session_->UpdateRect({ std::round(displayArea_.Left()), std::round(displayArea_.Top()),
1261 std::round(displayArea_.Width()), std::round(displayArea_.Height()) }, reason, "NotifyDisplayArea",
1262 transaction);
1263 }
1264
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1265 void SessionWrapperImpl::NotifySizeChangeReason(
1266 WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1267 {
1268 CHECK_NULL_VOID(session_);
1269 auto reason = static_cast<Rosen::SizeChangeReason>(type);
1270 session_->UpdateSizeChangeReason(reason);
1271 if (rsTransaction && (type == WindowSizeChangeReason::ROTATION ||
1272 type == WindowSizeChangeReason::SNAPSHOT_ROTATION)) {
1273 transaction_ = rsTransaction;
1274 }
1275 }
1276
NotifyOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type) const1277 void SessionWrapperImpl::NotifyOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type) const
1278 {
1279 CHECK_NULL_VOID(session_);
1280 UIEXT_LOGD("NotifyAvoidArea, type: %{public}d, topRect=(%{public}d, %{public}d)-[%{public}d, %{public}d], "
1281 "bottomRect=(%{public}d,%{public}d)-[%{public}d,%{public}d],persistentId=%{public}d,componentId=%{public}d.",
1282 type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
1283 (int32_t)avoidArea.topRect_.height_, avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
1284 (int32_t)avoidArea.bottomRect_.width_, (int32_t)avoidArea.bottomRect_.height_, GetSessionId(),
1285 GetFrameNodeId());
1286 ACE_SCOPED_TRACE("NotifyAvoidArea, type: %d, topRect: (%d, %d) - [%d, %d], bottomRect: (%d, %d) - [%d, %d]",
1287 type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
1288 (int32_t)avoidArea.topRect_.height_, avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
1289 (int32_t)avoidArea.bottomRect_.width_, (int32_t)avoidArea.bottomRect_.height_);
1290 session_->UpdateAvoidArea(sptr<Rosen::AvoidArea>::MakeSptr(avoidArea), static_cast<Rosen::AvoidAreaType>(type));
1291 }
1292
NotifyOccupiedAreaChangeInfo(sptr<Rosen::OccupiedAreaChangeInfo> info,bool needWaitLayout)1293 bool SessionWrapperImpl::NotifyOccupiedAreaChangeInfo(
1294 sptr<Rosen::OccupiedAreaChangeInfo> info, bool needWaitLayout)
1295 {
1296 CHECK_NULL_RETURN(session_, false);
1297 CHECK_NULL_RETURN(info, false);
1298 CHECK_NULL_RETURN(isNotifyOccupiedAreaChange_, false);
1299 CHECK_NULL_RETURN(taskExecutor_, false);
1300 ContainerScope scope(instanceId_);
1301 auto pipeline = PipelineBase::GetCurrentContext();
1302 CHECK_NULL_RETURN(pipeline, false);
1303 auto curWindow = pipeline->GetCurrentWindowRect();
1304 int64_t curTime = GetCurrentTimestamp();
1305 if (displayAreaWindow_ != curWindow && needWaitLayout) {
1306 UIEXT_LOGI("OccupiedArea wait layout, displayAreaWindow: %{public}s,"
1307 " curWindow=%{public}s, componentId=%{public}d.",
1308 displayAreaWindow_.ToString().c_str(), curWindow.ToString().c_str(), GetFrameNodeId());
1309 taskExecutor_->PostDelayedTask(
1310 [info, weak = AceType::WeakClaim(this), curTime] {
1311 auto session = weak.Upgrade();
1312 if (session) {
1313 session->InnerNotifyOccupiedAreaChangeInfo(info, true, curTime);
1314 }
1315 },
1316 TaskExecutor::TaskType::UI, AVOID_DELAY_TIME, "ArkUIVirtualKeyboardAreaChangeDelay");
1317 }
1318
1319 taskExecutor_->PostTask(
1320 [info, weak = AceType::WeakClaim(this), curTime] {
1321 auto session = weak.Upgrade();
1322 if (session) {
1323 session->InnerNotifyOccupiedAreaChangeInfo(info, false, curTime);
1324 }
1325 },
1326 TaskExecutor::TaskType::UI, "ArkUIUecAreaChange",
1327 TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
1328 return true;
1329 }
1330
InnerNotifyOccupiedAreaChangeInfo(sptr<Rosen::OccupiedAreaChangeInfo> info,bool isWaitTask,int64_t occupiedAreaTime)1331 bool SessionWrapperImpl::InnerNotifyOccupiedAreaChangeInfo(
1332 sptr<Rosen::OccupiedAreaChangeInfo> info, bool isWaitTask, int64_t occupiedAreaTime)
1333 {
1334 if (isWaitTask && occupiedAreaTime < lastOccupiedAreaTime_) {
1335 UIEXT_LOGW("OccupiedArea has been executed last time, persistentid = %{public}d.",
1336 GetSessionId());
1337 return false;
1338 }
1339
1340 lastOccupiedAreaTime_ = occupiedAreaTime;
1341 CHECK_NULL_RETURN(session_, false);
1342 CHECK_NULL_RETURN(info, false);
1343 CHECK_NULL_RETURN(isNotifyOccupiedAreaChange_, false);
1344 int32_t keyboardHeight = static_cast<int32_t>(info->rect_.height_);
1345 ContainerScope scope(instanceId_);
1346 auto pipeline = PipelineBase::GetCurrentContext();
1347 CHECK_NULL_RETURN(pipeline, false);
1348 auto curWindow = pipeline->GetCurrentWindowRect();
1349 auto container = Platform::AceContainer::GetContainer(GetInstanceId());
1350 CHECK_NULL_RETURN(container, false);
1351 auto displayArea = displayArea_;
1352 if (container->IsSceneBoardWindow()) {
1353 Rosen::WSRect rect = GetWindowSceneRect();
1354 curWindow.SetRect(rect.posX_, rect.posY_, rect.width_, rect.height_);
1355 displayArea = GetDisplayAreaWithWindowScene();
1356 }
1357 if (keyboardHeight > 0) {
1358 if (curWindow.Bottom() >= displayArea.Bottom()) {
1359 int32_t spaceWindow = std::max(curWindow.Bottom() - displayArea.Bottom(), 0.0);
1360 keyboardHeight = static_cast<int32_t>(std::max(keyboardHeight - spaceWindow, 0));
1361 } else {
1362 keyboardHeight = keyboardHeight + (displayArea.Bottom() - curWindow.Bottom());
1363 }
1364 }
1365 sptr<Rosen::OccupiedAreaChangeInfo> newInfo = new Rosen::OccupiedAreaChangeInfo(
1366 info->type_, info->rect_, info->safeHeight_, info->textFieldPositionY_, info->textFieldHeight_);
1367 newInfo->rect_.height_ = static_cast<uint32_t>(keyboardHeight);
1368 UIEXT_LOGI("OccupiedArea keyboardHeight = %{public}d, displayOffset = %{public}s, displayArea = %{public}s, "
1369 "curWindow = %{public}s, persistentid = %{public}d, componentId=%{public}d.",
1370 keyboardHeight, displayArea.GetOffset().ToString().c_str(), displayArea_.ToString().c_str(),
1371 curWindow.ToString().c_str(), GetSessionId(), GetFrameNodeId());
1372 session_->NotifyOccupiedAreaChangeInfo(newInfo);
1373 return true;
1374 }
1375
UpdateSessionViewportConfig()1376 void SessionWrapperImpl::UpdateSessionViewportConfig()
1377 {
1378 CHECK_NULL_VOID(session_);
1379 auto pattern = hostPattern_.Upgrade();
1380 CHECK_NULL_VOID(pattern);
1381 auto config = pattern->GetSessionViewportConfig();
1382 UIEXT_LOGI("SessionViewportConfig: isDensityFollowHost=%{public}d, density=%{public}f, "
1383 "displayId=%{public}" PRIu64", orientation=%{public}d, transform=%{public}d, componentId=%{public}d.",
1384 config.isDensityFollowHost_, config.density_, config.displayId_, config.orientation_, config.transform_,
1385 GetFrameNodeId());
1386 session_->UpdateSessionViewportConfig(ConvertToRosenSessionViewportConfig(config));
1387 }
1388
1389 /***************************** End: The interface to control the display area and the avoid area **********************/
1390
1391 /************************************************ Begin: The interface to send the data for ArkTS *********************/
SendDataAsync(const AAFwk::WantParams & params) const1392 void SessionWrapperImpl::SendDataAsync(const AAFwk::WantParams& params) const
1393 {
1394 if (!session_) {
1395 UIEXT_LOGE(
1396 "The data is synchronously send and the session is invalid, componentId=%{public}d.", GetFrameNodeId());
1397 return;
1398 }
1399 session_->TransferComponentData(params);
1400 }
1401
SendDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams) const1402 int32_t SessionWrapperImpl::SendDataSync(const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams) const
1403 {
1404 Rosen::WSErrorCode transferCode = Rosen::WSErrorCode::WS_ERROR_TRANSFER_DATA_FAILED;
1405 UIEXT_LOGI("The data is synchronously send and the session is %{public}s, componentId=%{public}d.",
1406 session_ ? "valid" : "invalid", GetFrameNodeId());
1407 if (session_) {
1408 transferCode = session_->TransferComponentDataSync(wantParams, reWantParams);
1409 }
1410 return static_cast<int32_t>(transferCode);
1411 }
1412 /************************************************ End: The interface to send the data for ArkTS ***********************/
1413
1414 /************************************************ Begin: The interface for UEC dump **********************************/
GetReasonDump() const1415 uint32_t SessionWrapperImpl::GetReasonDump() const
1416 {
1417 return reason_;
1418 }
1419
NotifyUieDump(const std::vector<std::string> & params,std::vector<std::string> & info)1420 void SessionWrapperImpl::NotifyUieDump(const std::vector<std::string>& params, std::vector<std::string>& info)
1421 {
1422 CHECK_NULL_VOID(session_);
1423 session_->NotifyDumpInfo(params, info);
1424 }
1425
GetFrameNodeId() const1426 int32_t SessionWrapperImpl::GetFrameNodeId() const
1427 {
1428 auto pattern = hostPattern_.Upgrade();
1429 CHECK_NULL_RETURN(pattern, -1);
1430 auto frameNode = pattern->GetHost();
1431 CHECK_NULL_RETURN(frameNode, -1);
1432 return frameNode->GetId();
1433 }
1434
SendBusinessDataSyncReply(UIContentBusinessCode code,const AAFwk::Want & data,AAFwk::Want & reply,RSSubsystemId subSystemId)1435 bool SessionWrapperImpl::SendBusinessDataSyncReply(
1436 UIContentBusinessCode code, const AAFwk::Want& data, AAFwk::Want& reply, RSSubsystemId subSystemId)
1437 {
1438 if (code == UIContentBusinessCode::UNDEFINED) {
1439 return false;
1440 }
1441 CHECK_NULL_RETURN(session_, false);
1442 auto dataHandler = session_->GetExtensionDataHandler();
1443 CHECK_NULL_RETURN(dataHandler, false);
1444 auto result = dataHandler->SendDataSync(static_cast<OHOS::Rosen::SubSystemId>(subSystemId),
1445 static_cast<uint32_t>(code), data, reply);
1446 if (result != Rosen::DataHandlerErr::OK) {
1447 UIEXT_LOGW("SendBusinessDataSyncReply Fail, businesCode=%{public}u, result=%{public}u, compontId=%{public}d.",
1448 code, result, GetFrameNodeId());
1449 return false;
1450 }
1451 UIEXT_LOGI("SendBusinessDataSyncReply Success, businessCode=%{public}u, compontId=%{public}d.",
1452 code, GetFrameNodeId());
1453 return true;
1454 }
1455
SendBusinessData(UIContentBusinessCode code,const AAFwk::Want & data,BusinessDataSendType type,RSSubsystemId subSystemId)1456 bool SessionWrapperImpl::SendBusinessData(
1457 UIContentBusinessCode code, const AAFwk::Want& data, BusinessDataSendType type, RSSubsystemId subSystemId)
1458 {
1459 if (code == UIContentBusinessCode::UNDEFINED) {
1460 return false;
1461 }
1462 CHECK_NULL_RETURN(session_, false);
1463 auto dataHandler = session_->GetExtensionDataHandler();
1464 CHECK_NULL_RETURN(dataHandler, false);
1465 if (type == BusinessDataSendType::ASYNC) {
1466 dataHandler->SendDataAsync(static_cast<OHOS::Rosen::SubSystemId>(subSystemId),
1467 static_cast<uint32_t>(code), data);
1468 UIEXT_LOGD("SendBusinessData ASYNC Success, businessCode=%{public}u, compontId=%{public}d.",
1469 code, GetFrameNodeId());
1470 return true;
1471 }
1472 auto result = dataHandler->SendDataSync(static_cast<OHOS::Rosen::SubSystemId>(subSystemId),
1473 static_cast<uint32_t>(code), data);
1474 if (result != Rosen::DataHandlerErr::OK) {
1475 UIEXT_LOGD("SendBusinessData Sync Fail, businesCode=%{public}u, result=%{public}u, compontId=%{public}d.",
1476 code, result, GetFrameNodeId());
1477 return false;
1478 }
1479 UIEXT_LOGD("SendBusinessData SYNC Success, businessCode=%{public}u, componentId=%{public}d.",
1480 code, GetFrameNodeId());
1481 return true;
1482 }
1483
DispatchExtensionDataToHostWindow(uint32_t customId,const AAFwk::Want & data)1484 void SessionWrapperImpl::DispatchExtensionDataToHostWindow(uint32_t customId, const AAFwk::Want& data)
1485 {
1486 int32_t callSessionId = GetSessionId();
1487 CHECK_NULL_VOID(taskExecutor_);
1488 auto instanceId = GetInstanceId();
1489 taskExecutor_->PostTask(
1490 [instanceId, weak = hostPattern_, customId, data, callSessionId]() {
1491 ContainerScope scope(instanceId);
1492 auto pattern = weak.Upgrade();
1493 CHECK_NULL_VOID(pattern);
1494 if (callSessionId != pattern->GetSessionId()) {
1495 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1496 "DispatchExtensionDataToHostWindow: The callSessionId(%{public}d)"
1497 " is inconsistent with the curSession(%{public}d)",
1498 callSessionId, pattern->GetSessionId());
1499 return;
1500 }
1501 auto container = Platform::AceContainer::GetContainer(instanceId);
1502 CHECK_NULL_VOID(container);
1503 container->DispatchExtensionDataToHostWindow(customId, data, callSessionId);
1504 },
1505 TaskExecutor::TaskType::UI, "ArkUIDispatchExtensionDataToHostWindow");
1506 }
1507
PostBusinessDataConsumeAsync(uint32_t customId,const AAFwk::Want & data)1508 void SessionWrapperImpl::PostBusinessDataConsumeAsync(uint32_t customId, const AAFwk::Want& data)
1509 {
1510 UIEXT_LOGI("PostBusinessDataConsumeAsync, businessCode=%{public}u.", customId);
1511 int32_t callSessionId = GetSessionId();
1512 CHECK_NULL_VOID(taskExecutor_);
1513 auto instanceId = GetInstanceId();
1514 taskExecutor_->PostTask(
1515 [instanceId, weak = hostPattern_, customId, data, callSessionId]() {
1516 ContainerScope scope(instanceId);
1517 auto pattern = weak.Upgrade();
1518 CHECK_NULL_VOID(pattern);
1519 if (callSessionId != pattern->GetSessionId()) {
1520 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1521 "BusinessDataConsumeAsync: The callSessionId(%{public}d)"
1522 " is inconsistent with the curSession(%{public}d)",
1523 callSessionId, pattern->GetSessionId());
1524 return;
1525 }
1526 pattern->OnUIExtBusinessReceive(static_cast<UIContentBusinessCode>(customId), data);
1527 },
1528 TaskExecutor::TaskType::UI, "ArkUIUIExtensionBusinessDataConsumeAsync");
1529 }
PostBusinessDataConsumeSyncReply(uint32_t customId,const AAFwk::Want & data,std::optional<AAFwk::Want> & reply)1530 void SessionWrapperImpl::PostBusinessDataConsumeSyncReply(
1531 uint32_t customId, const AAFwk::Want& data, std::optional<AAFwk::Want>& reply)
1532 {
1533 UIEXT_LOGI("PostBusinessDataConsumeSyncReply, businessCode=%{public}u.", customId);
1534 int32_t callSessionId = GetSessionId();
1535 CHECK_NULL_VOID(taskExecutor_);
1536 auto instanceId = GetInstanceId();
1537 taskExecutor_->PostSyncTask(
1538 [instanceId, weak = hostPattern_, customId, data, &reply, callSessionId]() {
1539 ContainerScope scope(instanceId);
1540 auto pattern = weak.Upgrade();
1541 CHECK_NULL_VOID(pattern);
1542 if (callSessionId != pattern->GetSessionId()) {
1543 TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
1544 "BusinessDataConsumeSyncReply: The callSessionId(%{public}d)"
1545 " is inconsistent with the curSession(%{public}d)",
1546 callSessionId, pattern->GetSessionId());
1547 return;
1548 }
1549 pattern->OnUIExtBusinessReceiveReply(
1550 static_cast<UIContentBusinessCode>(customId), data, reply);
1551 },
1552 TaskExecutor::TaskType::UI, "ArkUIUIExtensionBusinessDataConsumeSyncReply");
1553 }
1554
RegisterDataConsumer()1555 bool SessionWrapperImpl::RegisterDataConsumer()
1556 {
1557 CHECK_NULL_RETURN(session_, false);
1558 auto dataHandler = session_->GetExtensionDataHandler();
1559 CHECK_NULL_RETURN(dataHandler, false);
1560 auto subSystemId = subSystemId_;
1561 auto callback = [wrapperWeak = WeakClaim(this), subSystemId]
1562 (Rosen::SubSystemId id, uint32_t customId, AAFwk::Want&& data, std::optional<AAFwk::Want>& reply) ->int32_t {
1563 auto sessionWrapper = wrapperWeak.Upgrade();
1564 CHECK_NULL_RETURN(sessionWrapper, false);
1565 auto instanceId = sessionWrapper->GetInstanceId();
1566 ContainerScope scope(instanceId);
1567 if (id != subSystemId) {
1568 return false;
1569 }
1570 if (IsDispatchExtensionDataToHostWindow(customId)) {
1571 sessionWrapper->DispatchExtensionDataToHostWindow(customId, data);
1572 return true;
1573 }
1574 if (reply.has_value()) {
1575 sessionWrapper->PostBusinessDataConsumeSyncReply(customId, data, reply);
1576 } else {
1577 sessionWrapper->PostBusinessDataConsumeAsync(customId, data);
1578 }
1579 return false;
1580 };
1581 auto result = dataHandler->RegisterDataConsumer(subSystemId, std::move(callback));
1582 if (result != Rosen::DataHandlerErr::OK) {
1583 UIEXT_LOGW("RegisterDataConsumer Fail, result=%{public}u", result);
1584 return false;
1585 }
1586 return true;
1587 }
1588 /************************************************ End: The interface for UEC dump **********************************/
1589
NotifyHostWindowMode(int32_t mode)1590 void SessionWrapperImpl::NotifyHostWindowMode(int32_t mode)
1591 {
1592 UIEXT_LOGI("SendWindowModeToProvider: mode = %{public}d", mode);
1593 CHECK_NULL_VOID(session_);
1594 auto dataHandler = session_->GetExtensionDataHandler();
1595 CHECK_NULL_VOID(dataHandler);
1596 AAFwk::Want dataToSend;
1597 dataToSend.SetParam(OHOS::Rosen::Extension::WINDOW_MODE_FIELD, mode);
1598 dataHandler->SendDataAsync(Rosen::SubSystemId::WM_UIEXT,
1599 static_cast<uint32_t>(OHOS::Rosen::Extension::Businesscode::SYNC_HOST_WINDOW_MODE), dataToSend);
1600 }
1601 } // namespace OHOS::Ace::NG
1602