• 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/session_wrapper_impl.h"
17 
18 #include <cmath>
19 #include <memory>
20 
21 #include "accessibility_event_info.h"
22 #include "refbase.h"
23 #include "session_manager/include/extension_session_manager.h"
24 #include "ui/rs_surface_node.h"
25 #include "wm/wm_common.h"
26 
27 #include "adapter/ohos/entrance/ace_container.h"
28 #include "adapter/ohos/osal/want_wrap_ohos.h"
29 #include "base/utils/utils.h"
30 #include "core/common/container.h"
31 #include "core/common/container_scope.h"
32 #include "core/pipeline_ng/pipeline_context.h"
33 
34 namespace OHOS::Ace::NG {
35 
36 class UIExtensionLifecycleListener : public Rosen::ILifecycleListener {
37 public:
UIExtensionLifecycleListener(int32_t instanceId,const WeakPtr<UIExtensionPattern> & hostPattern)38     UIExtensionLifecycleListener(int32_t instanceId, const WeakPtr<UIExtensionPattern>& hostPattern)
39         : instanceId_(instanceId), hostPattern_(hostPattern)
40     {}
41     virtual ~UIExtensionLifecycleListener() = default;
42 
OnActivation()43     void OnActivation() override {}
OnForeground()44     void OnForeground() override {}
OnBackground()45     void OnBackground() override {}
46 
OnConnect()47     void OnConnect() override
48     {
49         ContainerScope scope(instanceId_);
50         auto pipeline = PipelineBase::GetCurrentContext();
51         CHECK_NULL_VOID(pipeline);
52         auto taskExecutor = pipeline->GetTaskExecutor();
53         CHECK_NULL_VOID(taskExecutor);
54         taskExecutor->PostTask(
55             [weak = hostPattern_]() {
56                 auto pattern = weak.Upgrade();
57                 CHECK_NULL_VOID(pattern);
58                 pattern->OnConnect();
59             },
60             TaskExecutor::TaskType::UI);
61     }
62 
OnDisconnect()63     void OnDisconnect() override
64     {
65         ContainerScope scope(instanceId_);
66         auto pipeline = PipelineBase::GetCurrentContext();
67         CHECK_NULL_VOID(pipeline);
68         auto taskExecutor = pipeline->GetTaskExecutor();
69         CHECK_NULL_VOID(taskExecutor);
70         taskExecutor->PostTask(
71             [weak = hostPattern_]() {
72                 auto pattern = weak.Upgrade();
73                 CHECK_NULL_VOID(pattern);
74                 pattern->OnDisconnect();
75             },
76             TaskExecutor::TaskType::UI);
77     }
78 
OnExtensionDied()79     void OnExtensionDied() override
80     {
81         ContainerScope scope(instanceId_);
82         auto pipeline = PipelineBase::GetCurrentContext();
83         CHECK_NULL_VOID(pipeline);
84         auto taskExecutor = pipeline->GetTaskExecutor();
85         CHECK_NULL_VOID(taskExecutor);
86         taskExecutor->PostTask(
87             [weak = hostPattern_]() {
88                 auto pattern = weak.Upgrade();
89                 CHECK_NULL_VOID(pattern);
90                 pattern->OnExtensionDied();
91             },
92             TaskExecutor::TaskType::UI);
93     }
94 
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionOffset)95     void OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info, int64_t uiExtensionOffset) override
96     {
97         ContainerScope scope(instanceId_);
98         auto pipeline = PipelineBase::GetCurrentContext();
99         CHECK_NULL_VOID(pipeline);
100         auto taskExecutor = pipeline->GetTaskExecutor();
101         CHECK_NULL_VOID(taskExecutor);
102         taskExecutor->PostTask(
103             [weak = hostPattern_, info, uiExtensionOffset]() {
104                 auto pattern = weak.Upgrade();
105                 CHECK_NULL_VOID(pattern);
106                 pattern->OnAccessibilityEvent(info, uiExtensionOffset);
107             },
108             TaskExecutor::TaskType::UI);
109     }
110 
111 private:
112     int32_t instanceId_;
113     WeakPtr<UIExtensionPattern> hostPattern_;
114 };
115 
116 /************************************************ Begin: Initialization ***********************************************/
SessionWrapperImpl(const WeakPtr<UIExtensionPattern> & hostPattern,int32_t instanceId,bool isTransferringCaller)117 SessionWrapperImpl::SessionWrapperImpl(
118     const WeakPtr<UIExtensionPattern>& hostPattern, int32_t instanceId, bool isTransferringCaller)
119     : hostPattern_(hostPattern), instanceId_(instanceId), isTransferringCaller_(isTransferringCaller)
120 {}
121 
~SessionWrapperImpl()122 SessionWrapperImpl::~SessionWrapperImpl() {}
123 
InitAllCallback()124 void SessionWrapperImpl::InitAllCallback()
125 {
126     CHECK_NULL_VOID(session_);
127     auto pipeline = PipelineBase::GetCurrentContext();
128     CHECK_NULL_VOID(pipeline);
129     auto taskExecutor = pipeline->GetTaskExecutor();
130     CHECK_NULL_VOID(taskExecutor);
131     auto sessionCallbacks = session_->GetExtensionSessionEventCallback();
132 
133     foregroundCallback_ = [weak = hostPattern_, taskExecutor](OHOS::Rosen::WSError errcode) {
134         if (errcode != OHOS::Rosen::WSError::WS_OK) {
135             taskExecutor->PostTask(
136                 [weak, errcode] {
137                     auto pattern = weak.Upgrade();
138                     CHECK_NULL_VOID(pattern);
139                     std::string name = "start_ability_fail";
140                     std::string message =
141                         "Start ui extension ability failed, please check the want of UIextensionAbility.";
142                     pattern->FireOnErrorCallback(static_cast<int32_t>(errcode), name, message);
143                 },
144                 TaskExecutor::TaskType::UI);
145         }
146     };
147     backgroundCallback_ = [weak = hostPattern_, taskExecutor](OHOS::Rosen::WSError errcode) {
148         if (errcode != OHOS::Rosen::WSError::WS_OK) {
149             taskExecutor->PostTask(
150                 [weak, errcode] {
151                     auto pattern = weak.Upgrade();
152                     CHECK_NULL_VOID(pattern);
153                     std::string name = "background_fail";
154                     std::string message = "background ui extension ability failed, please check AMS log.";
155                     pattern->FireOnErrorCallback(static_cast<int32_t>(errcode), name, message);
156                 },
157                 TaskExecutor::TaskType::UI);
158         }
159     };
160     destructionCallback_ = [weak = hostPattern_, taskExecutor](OHOS::Rosen::WSError errcode) {
161         if (errcode != OHOS::Rosen::WSError::WS_OK) {
162             taskExecutor->PostTask(
163                 [weak, errcode] {
164                     auto pattern = weak.Upgrade();
165                     CHECK_NULL_VOID(pattern);
166                     std::string name = "terminate_fail";
167                     std::string message = "terminate ui extension ability failed, please check AMS log.";
168                     pattern->FireOnErrorCallback(static_cast<int32_t>(errcode), name, message);
169                 },
170                 TaskExecutor::TaskType::UI);
171         }
172     };
173     sessionCallbacks->transferAbilityResultFunc_ = [weak = hostPattern_, taskExecutor](
174                                                        int32_t code, const AAFwk::Want& want) {
175         taskExecutor->PostTask(
176             [weak, code, want]() {
177                 auto pattern = weak.Upgrade();
178                 CHECK_NULL_VOID(pattern);
179                 pattern->FireOnResultCallback(code, want);
180             },
181             TaskExecutor::TaskType::UI);
182     };
183     sessionCallbacks->transferExtensionDataFunc_ = [weak = hostPattern_, taskExecutor](
184                                                        const AAFwk::WantParams& params) {
185         taskExecutor->PostTask(
186             [weak, params]() {
187                 auto pattern = weak.Upgrade();
188                 CHECK_NULL_VOID(pattern);
189                 pattern->FireOnReceiveCallback(params);
190             },
191             TaskExecutor::TaskType::UI);
192     };
193     sessionCallbacks->notifyRemoteReadyFunc_ = [weak = hostPattern_, taskExecutor]() {
194         taskExecutor->PostTask(
195             [weak]() {
196                 auto pattern = weak.Upgrade();
197                 CHECK_NULL_VOID(pattern);
198                 pattern->FireOnRemoteReadyCallback();
199             },
200             TaskExecutor::TaskType::UI);
201     };
202     sessionCallbacks->notifySyncOnFunc_ = [weak = hostPattern_, taskExecutor]() {
203         taskExecutor->PostTask(
204             [weak]() {
205                 auto pattern = weak.Upgrade();
206                 CHECK_NULL_VOID(pattern);
207                 pattern->FireSyncCallbacks();
208             },
209             TaskExecutor::TaskType::UI);
210     };
211     sessionCallbacks->notifyAsyncOnFunc_ = [weak = hostPattern_, taskExecutor]() {
212         taskExecutor->PostTask(
213             [weak]() {
214                 auto pattern = weak.Upgrade();
215                 CHECK_NULL_VOID(pattern);
216                 pattern->FireAsyncCallbacks();
217             },
218             TaskExecutor::TaskType::UI);
219     };
220     sessionCallbacks->notifyBindModalFunc_ = [weak = hostPattern_, taskExecutor]() {
221         taskExecutor->PostSyncTask(
222             [weak]() {
223                 auto pattern = weak.Upgrade();
224                 CHECK_NULL_VOID(pattern);
225                 pattern->FireBindModalCallback();
226             },
227             TaskExecutor::TaskType::UI);
228     };
229     sessionCallbacks->notifyGetAvoidAreaByTypeFunc_ = [instanceId = instanceId_](
230                                                           Rosen::AvoidAreaType type) -> Rosen::AvoidArea {
231         Rosen::AvoidArea avoidArea;
232         auto container = Platform::AceContainer::GetContainer(instanceId);
233         CHECK_NULL_RETURN(container, avoidArea);
234         avoidArea = container->GetAvoidAreaByType(type);
235         return avoidArea;
236     };
237 }
238 /************************************************ End: Initialization *************************************************/
239 
240 /************************************************ Begin: About session ************************************************/
CreateSession(const AAFwk::Want & want,bool isAsyncModalBinding)241 void SessionWrapperImpl::CreateSession(const AAFwk::Want& want, bool isAsyncModalBinding)
242 {
243     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Create session: %{private}s", want.ToString().c_str());
244     const std::string occupiedAreaChangeKey("ability.want.params.IsNotifyOccupiedAreaChange");
245     isNotifyOccupiedAreaChange_ = want.GetBoolParam(occupiedAreaChangeKey, false);
246     auto container = AceType::DynamicCast<Platform::AceContainer>(Container::Current());
247     CHECK_NULL_VOID(container);
248     auto callerToken = container->GetToken();
249     auto parentToken = container->GetParentToken();
250     Rosen::SessionInfo extensionSessionInfo = {
251         .bundleName_ = want.GetElement().GetBundleName(),
252         .abilityName_ = want.GetElement().GetAbilityName(),
253         .callerToken_ = callerToken,
254         .rootToken_ = (isTransferringCaller_ && parentToken) ? parentToken : callerToken,
255         .want = std::make_shared<Want>(want),
256         .isAsyncModalBinding_ = isAsyncModalBinding,
257     };
258     session_ = Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSession(extensionSessionInfo);
259     CHECK_NULL_VOID(session_);
260     lifecycleListener_ = std::make_shared<UIExtensionLifecycleListener>(instanceId_, hostPattern_);
261     session_->RegisterLifecycleListener(lifecycleListener_);
262     InitAllCallback();
263 }
264 
DestroySession()265 void SessionWrapperImpl::DestroySession()
266 {
267     CHECK_NULL_VOID(session_);
268     session_->UnregisterLifecycleListener(lifecycleListener_);
269     session_ = nullptr;
270 }
271 
IsSessionValid()272 bool SessionWrapperImpl::IsSessionValid()
273 {
274     return session_ != nullptr;
275 }
276 
GetSessionId()277 int32_t SessionWrapperImpl::GetSessionId()
278 {
279     return session_ ? session_->GetPersistentId() : 0;
280 }
281 
GetWant()282 const std::shared_ptr<AAFwk::Want> SessionWrapperImpl::GetWant()
283 {
284     return session_ ? session_->GetSessionInfo().want : nullptr;
285 }
286 /************************************************ End: About session **************************************************/
287 
288 /************************************************ Begin: Synchronous interface for event notify ***********************/
NotifyFocusEventSync(bool isFocus)289 bool SessionWrapperImpl::NotifyFocusEventSync(bool isFocus)
290 {
291     return false;
292 }
NotifyFocusStateSync(bool focusState)293 bool SessionWrapperImpl::NotifyFocusStateSync(bool focusState)
294 {
295     return false;
296 }
297 
NotifyBackPressedSync()298 bool SessionWrapperImpl::NotifyBackPressedSync()
299 {
300     CHECK_NULL_RETURN(session_, false);
301     bool isConsumed = false;
302     session_->TransferBackPressedEventForConsumed(isConsumed);
303     return isConsumed;
304 }
305 
NotifyPointerEventSync(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)306 bool SessionWrapperImpl::NotifyPointerEventSync(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
307 {
308     return false;
309 }
310 
NotifyKeyEventSync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent)311 bool SessionWrapperImpl::NotifyKeyEventSync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent)
312 {
313     CHECK_NULL_RETURN(session_, false);
314     bool isConsumed = false;
315     session_->TransferKeyEventForConsumed(keyEvent, isConsumed);
316     return isConsumed;
317 }
318 
NotifyAxisEventSync(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)319 bool SessionWrapperImpl::NotifyAxisEventSync(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
320 {
321     return false;
322 }
323 /************************************************ End: Synchronous interface for event notify *************************/
324 
325 /************************************************ Begin: Asynchronous interface for event notify **********************/
NotifyFocusEventAsync(bool isFocus)326 bool SessionWrapperImpl::NotifyFocusEventAsync(bool isFocus)
327 {
328     CHECK_NULL_RETURN(session_, false);
329     session_->TransferFocusActiveEvent(isFocus);
330     return true;
331 }
332 
NotifyFocusStateAsync(bool focusState)333 bool SessionWrapperImpl::NotifyFocusStateAsync(bool focusState)
334 {
335     CHECK_NULL_RETURN(session_, false);
336     session_->TransferFocusStateEvent(focusState);
337     return true;
338 }
339 
NotifyBackPressedAsync()340 bool SessionWrapperImpl::NotifyBackPressedAsync()
341 {
342     return false;
343 }
NotifyPointerEventAsync(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)344 bool SessionWrapperImpl::NotifyPointerEventAsync(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
345 {
346     if (session_ && pointerEvent) {
347         session_->TransferPointerEvent(pointerEvent);
348     }
349     return false;
350 }
NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent)351 bool SessionWrapperImpl::NotifyKeyEventAsync(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent)
352 {
353     if (session_ && keyEvent) {
354         session_->TransferKeyEvent(keyEvent);
355     }
356     return false;
357 }
NotifyAxisEventAsync(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)358 bool SessionWrapperImpl::NotifyAxisEventAsync(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
359 {
360     return false;
361 }
362 /************************************************ End: Asynchronous interface for event notify ************************/
363 
364 /************************************************ Begin: The lifecycle interface **************************************/
NotifyCreate()365 void SessionWrapperImpl::NotifyCreate() {}
366 
NotifyForeground()367 void SessionWrapperImpl::NotifyForeground()
368 {
369     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Foreground: session is %{public}s", session_ ? "valid" : "invalid");
370     CHECK_NULL_VOID(session_);
371     auto pipeline = PipelineBase::GetCurrentContext();
372     CHECK_NULL_VOID(pipeline);
373     auto hostWindowId = pipeline->GetFocusWindowId();
374     Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionActivation(
375         session_, hostWindowId, std::move(foregroundCallback_));
376 }
377 
NotifyBackground()378 void SessionWrapperImpl::NotifyBackground()
379 {
380     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Background: session is %{public}s", session_ ? "valid" : "invalid");
381     CHECK_NULL_VOID(session_);
382     Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionBackground(
383         session_, std::move(backgroundCallback_));
384 }
NotifyDestroy()385 void SessionWrapperImpl::NotifyDestroy()
386 {
387     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Destroy: session is %{public}s", session_ ? "valid" : "invalid");
388     CHECK_NULL_VOID(session_);
389     Rosen::ExtensionSessionManager::GetInstance().RequestExtensionSessionDestruction(
390         session_, std::move(destructionCallback_));
391 }
392 
NotifyConfigurationUpdate()393 void SessionWrapperImpl::NotifyConfigurationUpdate() {}
394 /************************************************ End: The lifecycle interface ****************************************/
395 
396 /************************************************ Begin: The interface about the accessibility ************************/
TransferExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)397 bool SessionWrapperImpl::TransferExecuteAction(
398     int64_t elementId, const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)
399 {
400     CHECK_NULL_RETURN(session_, false);
401     return OHOS::Rosen::WSError::WS_OK == session_->TransferExecuteAction(elementId, actionArguments, action, offset);
402 }
403 
SearchExtensionElementInfoByAccessibilityId(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)404 void SessionWrapperImpl::SearchExtensionElementInfoByAccessibilityId(
405     int64_t elementId, int32_t mode, int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output)
406 {
407     CHECK_NULL_VOID(session_);
408     session_->TransferSearchElementInfo(elementId, mode, baseParent, output);
409 }
410 
SearchElementInfosByText(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)411 void SessionWrapperImpl::SearchElementInfosByText(int64_t elementId, const std::string& text, int64_t baseParent,
412     std::list<Accessibility::AccessibilityElementInfo>& output)
413 {
414     CHECK_NULL_VOID(session_);
415     session_->TransferSearchElementInfosByText(elementId, text, baseParent, output);
416 }
417 
FindFocusedElementInfo(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)418 void SessionWrapperImpl::FindFocusedElementInfo(
419     int64_t elementId, int32_t focusType, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)
420 {
421     CHECK_NULL_VOID(session_);
422     session_->TransferFindFocusedElementInfo(elementId, focusType, baseParent, output);
423 }
424 
FocusMoveSearch(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)425 void SessionWrapperImpl::FocusMoveSearch(
426     int64_t elementId, int32_t direction, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)
427 {
428     CHECK_NULL_VOID(session_);
429     session_->TransferFocusMoveSearch(elementId, direction, baseParent, output);
430 }
431 /************************************************ Begin: The interface about the accessibility ************************/
432 
433 /************************************************ Begin: The interface to control the display area ********************/
GetSurfaceNode() const434 std::shared_ptr<Rosen::RSSurfaceNode> SessionWrapperImpl::GetSurfaceNode() const
435 {
436     return session_ ? session_->GetSurfaceNode() : nullptr;
437 }
438 
RefreshDisplayArea(const RectF & displayArea)439 void SessionWrapperImpl::RefreshDisplayArea(const RectF& displayArea)
440 {
441     CHECK_NULL_VOID(session_);
442     ContainerScope scope(instanceId_);
443     auto pipeline = PipelineBase::GetCurrentContext();
444     CHECK_NULL_VOID(pipeline);
445     auto curWindow = pipeline->GetCurrentWindowRect();
446     displayArea_ = displayArea + OffsetF(curWindow.Left(), curWindow.Top());
447     session_->UpdateRect({ std::round(displayArea_.Left()), std::round(displayArea_.Top()),
448                                 std::round(displayArea_.Width()), std::round(displayArea_.Height()) },
449         Rosen::SizeChangeReason::UNDEFINED);
450 }
451 /************************************************ End: The interface to control the display area **********************/
452 
453 /************************************************ Begin: The interface to send the data for ArkTS *********************/
SendDataAsync(const AAFwk::WantParams & params) const454 void SessionWrapperImpl::SendDataAsync(const AAFwk::WantParams& params) const
455 {
456     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Async: session is %{public}s", session_ ? "valid" : "invalid");
457     CHECK_NULL_VOID(session_);
458     session_->TransferComponentData(params);
459 }
460 
SendDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams) const461 int32_t SessionWrapperImpl::SendDataSync(const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams) const
462 {
463     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "Sync: session is %{public}s", session_ ? "valid" : "invalid");
464     Rosen::WSErrorCode transferCode = Rosen::WSErrorCode::WS_ERROR_TRANSFER_DATA_FAILED;
465     if (session_) {
466         transferCode = session_->TransferComponentDataSync(wantParams, reWantParams);
467     }
468     return static_cast<int32_t>(transferCode);
469 }
470 /************************************************ End: The interface to send the data for ArkTS ***********************/
471 
472 /************************************************ Begin: The interface to control the avoid area **********************/
NotifyOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type) const473 void SessionWrapperImpl::NotifyOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type) const
474 {
475     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "AvoidArea: session is %{public}s", session_ ? "valid" : "invalid");
476     CHECK_NULL_VOID(session_);
477     session_->UpdateAvoidArea(sptr<Rosen::AvoidArea>::MakeSptr(avoidArea), static_cast<Rosen::AvoidAreaType>(type));
478 }
479 
NotifyOccupiedAreaChangeInfo(sptr<Rosen::OccupiedAreaChangeInfo> info) const480 bool SessionWrapperImpl::NotifyOccupiedAreaChangeInfo(sptr<Rosen::OccupiedAreaChangeInfo> info) const
481 {
482     CHECK_NULL_RETURN(session_, false);
483     CHECK_NULL_RETURN(info, false);
484     CHECK_NULL_RETURN(isNotifyOccupiedAreaChange_, false);
485     int32_t keyboardHeight = static_cast<int32_t>(info->rect_.height_);
486     if (keyboardHeight > 0) {
487         ContainerScope scope(instanceId_);
488         auto pipeline = PipelineBase::GetCurrentContext();
489         CHECK_NULL_RETURN(pipeline, false);
490         auto curWindow = pipeline->GetCurrentWindowRect();
491         int32_t spaceWindow = std::max(curWindow.Bottom() - displayArea_.Bottom(), .0);
492         keyboardHeight = static_cast<int32_t>(std::max(keyboardHeight - spaceWindow, 0));
493     }
494     info->rect_.height_ = static_cast<uint32_t>(keyboardHeight);
495     session_->NotifyOccupiedAreaChangeInfo(info);
496     return true;
497 }
498 /************************************************ End: The interface to control the avoid area ************************/
499 } // namespace OHOS::Ace::NG
500