• 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 "session/host/include/session.h"
17 
18 #include <application_context.h>
19 #include <regex>
20 #include <string>
21 
22 #include "ability_info.h"
23 #include "input_manager.h"
24 #include "key_event.h"
25 #include "pointer_event.h"
26 #include <transaction/rs_interfaces.h>
27 #include <transaction/rs_transaction.h>
28 #include <ui/rs_surface_node.h>
29 #include "proxy/include/window_info.h"
30 
31 #include "common/include/session_permission.h"
32 #include "rs_adapter.h"
33 #include "session_coordinate_helper.h"
34 #include "session_helper.h"
35 #include "surface_capture_future.h"
36 #include "window_helper.h"
37 #include "window_manager_hilog.h"
38 #include "parameters.h"
39 #include <hisysevent.h>
40 #include "hitrace_meter.h"
41 #include "screen_session_manager_client/include/screen_session_manager_client.h"
42 #include "session/host/include/pc_fold_screen_manager.h"
43 #include "perform_reporter.h"
44 #include "session/host/include/scene_persistent_storage.h"
45 
46 namespace OHOS::Rosen {
47 namespace {
48 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "Session" };
49 std::atomic<int32_t> g_persistentId = INVALID_SESSION_ID;
50 std::set<int32_t> g_persistentIdSet;
51 std::mutex g_persistentIdSetMutex;
52 constexpr float INNER_BORDER_VP = 5.0f;
53 constexpr float OUTSIDE_BORDER_VP = 4.0f;
54 constexpr float INNER_ANGLE_VP = 16.0f;
55 constexpr uint32_t MAX_LIFE_CYCLE_TASK_IN_QUEUE = 15;
56 constexpr uint32_t COLOR_WHITE = 0xffffffff;
57 constexpr uint32_t COLOR_BLACK = 0xff000000;
58 constexpr int64_t LIFE_CYCLE_TASK_EXPIRED_TIME_LIMIT = 350;
59 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
60 constexpr int64_t STATE_DETECT_DELAYTIME = 3 * 1000;
61 constexpr DisplayId VIRTUAL_DISPLAY_ID = 999;
62 constexpr int32_t TIMES_TO_WAIT_FOR_VSYNC_ONECE = 1;
63 constexpr int32_t TIMES_TO_WAIT_FOR_VSYNC_TWICE = 2;
64 const std::map<SessionState, bool> ATTACH_MAP = {
65     { SessionState::STATE_DISCONNECT, false },
66     { SessionState::STATE_CONNECT, false },
67     { SessionState::STATE_FOREGROUND, true },
68     { SessionState::STATE_ACTIVE, true },
69     { SessionState::STATE_INACTIVE, false },
70     { SessionState::STATE_BACKGROUND, false },
71 };
72 const std::map<SessionState, bool> DETACH_MAP = {
73     { SessionState::STATE_DISCONNECT, true },
74     { SessionState::STATE_CONNECT, false },
75     { SessionState::STATE_FOREGROUND, false },
76     { SessionState::STATE_ACTIVE, false },
77     { SessionState::STATE_INACTIVE, true },
78     { SessionState::STATE_BACKGROUND, true },
79 };
80 } // namespace
81 
82 std::shared_ptr<AppExecFwk::EventHandler> Session::mainHandler_;
83 bool Session::isScbCoreEnabled_ = false;
84 bool Session::isBackgroundUpdateRectNotifyEnabled_ = false;
85 
Session(const SessionInfo & info)86 Session::Session(const SessionInfo& info) : sessionInfo_(info)
87 {
88     property_ = sptr<WindowSessionProperty>::MakeSptr();
89     property_->SetWindowType(static_cast<WindowType>(info.windowType_));
90     layoutController_ = sptr<LayoutController>::MakeSptr(property_);
91     layoutController_->SetSystemConfigFunc([this]() {
92         return this->GetSystemConfig();
93     });
94 
95     if (!mainHandler_) {
96         auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
97         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
98     }
99 
100     using type = std::underlying_type_t<MMI::WindowArea>;
101     for (type area = static_cast<type>(MMI::WindowArea::FOCUS_ON_TOP);
102         area <= static_cast<type>(MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT); ++area) {
103         auto ret = windowAreas_.insert(
104             std::pair<MMI::WindowArea, WSRectF>(static_cast<MMI::WindowArea>(area), WSRectF()));
105         if (!ret.second) {
106             WLOGFE("Failed to insert area:%{public}d", area);
107         }
108     }
109 
110     if (info.want != nullptr) {
111         auto focusedOnShow = info.want->GetBoolParam(AAFwk::Want::PARAM_RESV_WINDOW_FOCUSED, true);
112         TLOGD(WmsLogTag::WMS_FOCUS, "focusedOnShow:%{public}d", focusedOnShow);
113         SetFocusedOnShow(focusedOnShow);
114     }
115 
116     static const std::regex pattern(R"(^SCBScreenLock[0-9]+$)");
117     if (std::regex_match(info.bundleName_, pattern)) {
118         TLOGD(WmsLogTag::WMS_LIFE, "bundleName: %{public}s", info.bundleName_.c_str());
119         isScreenLockWindow_ = true;
120     }
121 }
122 
~Session()123 Session::~Session()
124 {
125     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d", GetPersistentId());
126     DeletePersistentImageFit();
127     DeleteHasSnapshot();
128     if (mainHandler_) {
129         mainHandler_->PostTask([surfaceNode = std::move(surfaceNode_)]() {
130             // do nothing
131         });
132     }
133 }
134 
SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> & handler,const std::shared_ptr<AppExecFwk::EventHandler> & exportHandler)135 void Session::SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler>& handler,
136     const std::shared_ptr<AppExecFwk::EventHandler>& exportHandler)
137 {
138     handler_ = handler;
139     exportHandler_ = exportHandler;
140 }
141 
PostTask(Task && task,const std::string & name,int64_t delayTime)142 void Session::PostTask(Task&& task, const std::string& name, int64_t delayTime)
143 {
144     if (!handler_ || handler_->GetEventRunner()->IsCurrentRunnerThread()) {
145         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
146         return task();
147     }
148     auto localTask = [task = std::move(task), name] {
149         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
150         task();
151     };
152     handler_->PostTask(std::move(localTask), "wms:" + name, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
153 }
154 
PostExportTask(Task && task,const std::string & name,int64_t delayTime)155 void Session::PostExportTask(Task&& task, const std::string& name, int64_t delayTime)
156 {
157     if (!exportHandler_ || exportHandler_->GetEventRunner()->IsCurrentRunnerThread()) {
158         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
159         return task();
160     }
161     auto localTask = [task = std::move(task), name] {
162         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
163         task();
164     };
165     exportHandler_->PostTask(std::move(localTask), "wms:" + name, delayTime,
166         AppExecFwk::EventQueue::Priority::IMMEDIATE);
167 }
168 
GetPersistentId() const169 int32_t Session::GetPersistentId() const
170 {
171     return persistentId_;
172 }
173 
SetSurfaceNode(const std::shared_ptr<RSSurfaceNode> & surfaceNode)174 void Session::SetSurfaceNode(const std::shared_ptr<RSSurfaceNode>& surfaceNode)
175 {
176     RSAdapterUtil::SetRSUIContext(surfaceNode, GetRSUIContext(), true);
177     std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
178     surfaceNode_ = surfaceNode;
179 }
180 
GetSurfaceNode() const181 std::shared_ptr<RSSurfaceNode> Session::GetSurfaceNode() const
182 {
183     std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
184     return surfaceNode_;
185 }
186 
GetSurfaceNodeId() const187 std::optional<NodeId> Session::GetSurfaceNodeId() const
188 {
189     std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
190     if (surfaceNode_ != nullptr) {
191         return surfaceNode_->GetId();
192     }
193     return std::nullopt;
194 }
195 
SetLeashWinSurfaceNode(std::shared_ptr<RSSurfaceNode> leashWinSurfaceNode)196 void Session::SetLeashWinSurfaceNode(std::shared_ptr<RSSurfaceNode> leashWinSurfaceNode)
197 {
198     auto rsUIContext = GetRSUIContext();
199     RSAdapterUtil::SetRSUIContext(leashWinSurfaceNode, rsUIContext, true);
200     if (g_enableForceUIFirst) {
201         AutoRSTransaction trans(rsUIContext);
202         if (!leashWinSurfaceNode && leashWinSurfaceNode_) {
203             leashWinSurfaceNode_->SetForceUIFirst(false);
204         }
205     }
206     std::lock_guard<std::mutex> lock(leashWinSurfaceNodeMutex_);
207     leashWinSurfaceNode_ = leashWinSurfaceNode;
208 }
209 
SetFrameLayoutFinishListener(const NotifyFrameLayoutFinishFunc & func)210 void Session::SetFrameLayoutFinishListener(const NotifyFrameLayoutFinishFunc& func)
211 {
212     frameLayoutFinishFunc_ = func;
213 }
214 
GetLeashWinSurfaceNode() const215 std::shared_ptr<RSSurfaceNode> Session::GetLeashWinSurfaceNode() const
216 {
217     std::lock_guard<std::mutex> lock(leashWinSurfaceNodeMutex_);
218     return leashWinSurfaceNode_;
219 }
220 
GetSurfaceNodeForMoveDrag() const221 std::shared_ptr<RSSurfaceNode> Session::GetSurfaceNodeForMoveDrag() const
222 {
223     auto movedSurfaceNode = GetLeashWinSurfaceNode();
224     if (!movedSurfaceNode) {
225         movedSurfaceNode = GetSurfaceNode();
226     }
227     return movedSurfaceNode;
228 }
229 
GetSnapshot() const230 std::shared_ptr<Media::PixelMap> Session::GetSnapshot() const
231 {
232     std::lock_guard<std::mutex> lock(snapshotMutex_);
233     return snapshot_;
234 }
235 
SetSessionInfoAncoSceneState(int32_t ancoSceneState)236 void Session::SetSessionInfoAncoSceneState(int32_t ancoSceneState)
237 {
238     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
239     sessionInfo_.ancoSceneState = ancoSceneState;
240 }
241 
SetSessionInfoTime(const std::string & time)242 void Session::SetSessionInfoTime(const std::string& time)
243 {
244     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
245     sessionInfo_.time = time;
246 }
247 
SetSessionInfoAbilityInfo(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)248 void Session::SetSessionInfoAbilityInfo(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
249 {
250     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
251     sessionInfo_.abilityInfo = abilityInfo;
252 }
253 
SetSessionInfoSupportedWindowModes(const std::vector<AppExecFwk::SupportWindowMode> & updatedWindowModes)254 void Session::SetSessionInfoSupportedWindowModes(const std::vector<AppExecFwk::SupportWindowMode>& updatedWindowModes)
255 {
256     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
257     sessionInfo_.supportedWindowModes = updatedWindowModes;
258 }
259 
SetSessionInfoWant(const std::shared_ptr<AAFwk::Want> & want)260 void Session::SetSessionInfoWant(const std::shared_ptr<AAFwk::Want>& want)
261 {
262     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
263     sessionInfo_.want = want;
264 }
265 
ResetSessionInfoResultCode()266 void Session::ResetSessionInfoResultCode()
267 {
268     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
269     sessionInfo_.resultCode = -1; // -1: initial result code
270 }
271 
SetSessionInfoPersistentId(int32_t persistentId)272 void Session::SetSessionInfoPersistentId(int32_t persistentId)
273 {
274     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
275     sessionInfo_.persistentId_ = persistentId;
276 }
277 
SetSessionInfoCallerPersistentId(int32_t callerPersistentId)278 void Session::SetSessionInfoCallerPersistentId(int32_t callerPersistentId)
279 {
280     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
281     sessionInfo_.callerPersistentId_ = callerPersistentId;
282 }
283 
SetSessionInfoContinueState(ContinueState state)284 void Session::SetSessionInfoContinueState(ContinueState state)
285 {
286     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
287     sessionInfo_.continueState = state;
288 }
289 
SetSessionInfoLockedState(bool lockedState)290 void Session::SetSessionInfoLockedState(bool lockedState)
291 {
292     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
293     sessionInfo_.lockedState = lockedState;
294     NotifySessionInfoLockedStateChange(lockedState);
295 }
296 
SetSessionInfoIsClearSession(bool isClearSession)297 void Session::SetSessionInfoIsClearSession(bool isClearSession)
298 {
299     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
300     sessionInfo_.isClearSession = isClearSession;
301 }
302 
SetSessionInfoAffinity(std::string affinity)303 void Session::SetSessionInfoAffinity(std::string affinity)
304 {
305     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
306     sessionInfo_.sessionAffinity = affinity;
307 }
308 
GetCloseAbilityWantAndClean(AAFwk::Want & outWant)309 void Session::GetCloseAbilityWantAndClean(AAFwk::Want& outWant)
310 {
311     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
312     if (sessionInfo_.closeAbilityWant != nullptr) {
313         outWant = *sessionInfo_.closeAbilityWant;
314         sessionInfo_.closeAbilityWant = nullptr;
315     }
316 }
317 
SetSessionInfo(const SessionInfo & info)318 void Session::SetSessionInfo(const SessionInfo& info)
319 {
320     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
321     sessionInfo_.want = info.want;
322     sessionInfo_.callerToken_ = info.callerToken_;
323     sessionInfo_.requestCode = info.requestCode;
324     sessionInfo_.scenarios = info.scenarios;
325     sessionInfo_.callerPersistentId_ = info.callerPersistentId_;
326     sessionInfo_.callingTokenId_ = info.callingTokenId_;
327     sessionInfo_.uiAbilityId_ = info.uiAbilityId_;
328     sessionInfo_.requestId = info.requestId;
329     sessionInfo_.startSetting = info.startSetting;
330     if (!info.continueSessionId_.empty()) {
331         sessionInfo_.continueSessionId_ = info.continueSessionId_;
332     }
333     sessionInfo_.isAtomicService_ = info.isAtomicService_;
334     sessionInfo_.callState_ = info.callState_;
335     sessionInfo_.processOptions = info.processOptions;
336     sessionInfo_.disableDelegator = info.disableDelegator;
337     sessionInfo_.reuseDelegatorWindow = info.reuseDelegatorWindow;
338 }
339 
SetSessionInfoWindowInputType(uint32_t windowInputType)340 void Session::SetSessionInfoWindowInputType(uint32_t windowInputType)
341 {
342     TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, type:%{public}u", GetPersistentId(), windowInputType);
343     {
344         std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
345         sessionInfo_.windowInputType_ = windowInputType;
346     }
347     NotifySessionInfoChange();
348 }
349 
GetScreenId() const350 DisplayId Session::GetScreenId() const
351 {
352     return sessionInfo_.screenId_;
353 }
354 
SetScreenId(uint64_t screenId)355 void Session::SetScreenId(uint64_t screenId)
356 {
357     sessionInfo_.screenId_ = screenId;
358     if (sessionStage_) {
359         sessionStage_->UpdateDisplayId(screenId);
360     }
361     RSAdapterUtil::SetRSUIContext(GetSurfaceNode(), GetRSUIContext(), true);
362 }
363 
SetAppInstanceKey(const std::string & appInstanceKey)364 void Session::SetAppInstanceKey(const std::string& appInstanceKey)
365 {
366     sessionInfo_.appInstanceKey_ = appInstanceKey;
367 }
368 
GetAppInstanceKey() const369 std::string Session::GetAppInstanceKey() const
370 {
371     return sessionInfo_.appInstanceKey_;
372 }
373 
GetSessionInfo() const374 const SessionInfo& Session::GetSessionInfo() const
375 {
376     return sessionInfo_;
377 }
378 
EditSessionInfo()379 SessionInfo& Session::EditSessionInfo()
380 {
381     return sessionInfo_;
382 }
383 
RegisterLifecycleListener(const std::shared_ptr<ILifecycleListener> & listener)384 bool Session::RegisterLifecycleListener(const std::shared_ptr<ILifecycleListener>& listener)
385 {
386     return RegisterListenerLocked(lifecycleListeners_, listener);
387 }
388 
UnregisterLifecycleListener(const std::shared_ptr<ILifecycleListener> & listener)389 bool Session::UnregisterLifecycleListener(const std::shared_ptr<ILifecycleListener>& listener)
390 {
391     return UnregisterListenerLocked(lifecycleListeners_, listener);
392 }
393 
394 template<typename T>
RegisterListenerLocked(std::vector<std::shared_ptr<T>> & holder,const std::shared_ptr<T> & listener)395 bool Session::RegisterListenerLocked(std::vector<std::shared_ptr<T>>& holder, const std::shared_ptr<T>& listener)
396 {
397     if (listener == nullptr) {
398         WLOGFE("listener is nullptr");
399         return false;
400     }
401     std::lock_guard<std::recursive_mutex> lock(lifecycleListenersMutex_);
402     if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
403         WLOGFE("Listener already registered");
404         return false;
405     }
406     holder.emplace_back(listener);
407     return true;
408 }
409 
410 template<typename T>
UnregisterListenerLocked(std::vector<std::shared_ptr<T>> & holder,const std::shared_ptr<T> & listener)411 bool Session::UnregisterListenerLocked(std::vector<std::shared_ptr<T>>& holder, const std::shared_ptr<T>& listener)
412 {
413     if (listener == nullptr) {
414         WLOGFE("listener could not be null");
415         return false;
416     }
417     std::lock_guard<std::recursive_mutex> lock(lifecycleListenersMutex_);
418     holder.erase(std::remove_if(holder.begin(), holder.end(),
419         [listener](std::shared_ptr<T> registeredListener) { return registeredListener == listener; }),
420         holder.end());
421     return true;
422 }
423 
NotifyActivation()424 void Session::NotifyActivation()
425 {
426     auto lifecycleListeners = GetListeners<ILifecycleListener>();
427     for (auto& listener : lifecycleListeners) {
428         if (auto listenerPtr = listener.lock()) {
429             listenerPtr->OnActivation();
430         }
431     }
432 }
433 
NotifyConnect()434 void Session::NotifyConnect()
435 {
436     auto lifecycleListeners = GetListeners<ILifecycleListener>();
437     for (auto& listener : lifecycleListeners) {
438         if (auto listenerPtr = listener.lock()) {
439             listenerPtr->OnConnect();
440         }
441     }
442 }
443 
NotifyForeground()444 void Session::NotifyForeground()
445 {
446     auto lifecycleListeners = GetListeners<ILifecycleListener>();
447     for (auto& listener : lifecycleListeners) {
448         if (auto listenerPtr = listener.lock()) {
449             listenerPtr->OnForeground();
450         }
451     }
452 }
453 
NotifyBackground()454 void Session::NotifyBackground()
455 {
456     auto lifecycleListeners = GetListeners<ILifecycleListener>();
457     for (auto& listener : lifecycleListeners) {
458         if (auto listenerPtr = listener.lock()) {
459             listenerPtr->OnBackground();
460         }
461     }
462 }
463 
NotifyDisconnect()464 void Session::NotifyDisconnect()
465 {
466     auto lifecycleListeners = GetListeners<ILifecycleListener>();
467     for (auto& listener : lifecycleListeners) {
468         if (auto listenerPtr = listener.lock()) {
469             listenerPtr->OnDisconnect();
470         }
471     }
472 }
473 
NotifyLayoutFinished()474 void Session::NotifyLayoutFinished()
475 {
476     auto lifecycleListeners = GetListeners<ILifecycleListener>();
477     for (auto& listener : lifecycleListeners) {
478         if (auto listenerPtr = listener.lock()) {
479             listenerPtr->OnLayoutFinished();
480         }
481     }
482 }
483 
NotifyRemoveBlank()484 void Session::NotifyRemoveBlank()
485 {
486     auto lifecycleListeners = GetListeners<ILifecycleListener>();
487     for (auto& listener : lifecycleListeners) {
488         if (auto listenerPtr = listener.lock()) {
489             listenerPtr->OnRemoveBlank();
490         }
491     }
492 }
493 
NotifyPreLoadStartingWindowFinished()494 void Session::NotifyPreLoadStartingWindowFinished()
495 {
496     auto lifecycleListeners = GetListeners<ILifecycleListener>();
497     for (auto& listener : lifecycleListeners) {
498         if (auto listenerPtr = listener.lock()) {
499             listenerPtr->OnPreLoadStartingWindowFinished();
500         }
501     }
502 }
503 
NotifyAddSnapshot(bool useFfrt,bool needPersist,bool needSaveSnapshot)504 void Session::NotifyAddSnapshot(bool useFfrt, bool needPersist, bool needSaveSnapshot)
505 {
506     /*
507      * for blankness prolems, persist snapshot could conflict with background process,
508      * thus no need to persist snapshot here
509      */
510     if (needSaveSnapshot) {
511         SaveSnapshot(useFfrt, needPersist);
512     }
513     auto task = [weakThis = wptr(this), where = __func__]() {
514         auto session = weakThis.promote();
515         if (session == nullptr) {
516             TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s session is null", where);
517             return;
518         }
519         auto lifecycleListeners = session->GetListeners<ILifecycleListener>();
520         for (auto& listener : lifecycleListeners) {
521             if (auto listenerPtr = listener.lock()) {
522                 listenerPtr->OnAddSnapshot();
523             }
524         }
525     };
526 
527     if (useFfrt) {
528         SetAddSnapshotCallback(task);
529     } else {
530         task();
531     }
532 }
533 
NotifyRemoveSnapshot()534 void Session::NotifyRemoveSnapshot()
535 {
536     auto lifecycleListeners = GetListeners<ILifecycleListener>();
537     for (auto& listener : lifecycleListeners) {
538         if (auto listenerPtr = listener.lock()) {
539             listenerPtr->OnRemoveSnapshot();
540         }
541     }
542 }
543 
NotifyUpdateSnapshotWindow()544 void Session::NotifyUpdateSnapshotWindow()
545 {
546     auto lifecycleListeners = GetListeners<ILifecycleListener>();
547     for (auto& listener : lifecycleListeners) {
548         if (auto listenerPtr = listener.lock()) {
549             listenerPtr->OnUpdateSnapshotWindow();
550         }
551     }
552 }
553 
NotifyExtensionDied()554 void Session::NotifyExtensionDied()
555 {
556     if (!SessionPermission::IsSystemCalling()) {
557         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
558         return;
559     }
560     TLOGI(WmsLogTag::WMS_UIEXT, "NotifyExtensionDied called in session(persistentId:%{public}d).", persistentId_);
561     auto lifecycleListeners = GetListeners<ILifecycleListener>();
562     for (auto& listener : lifecycleListeners) {
563         if (auto listenerPtr = listener.lock()) {
564             listenerPtr->OnExtensionDied();
565         }
566     }
567 }
568 
NotifyExtensionTimeout(int32_t errorCode)569 void Session::NotifyExtensionTimeout(int32_t errorCode)
570 {
571     if (!SessionPermission::IsSystemCalling()) {
572         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
573         return;
574     }
575     TLOGI(WmsLogTag::WMS_UIEXT, "NotifyExtensionTimeout(errorCode:%{public}d) in session(persistentId:%{public}d).",
576         errorCode, persistentId_);
577     auto lifecycleListeners = GetListeners<ILifecycleListener>();
578     for (auto& listener : lifecycleListeners) {
579         if (auto listenerPtr = listener.lock()) {
580             listenerPtr->OnExtensionTimeout(errorCode);
581         }
582     }
583 }
584 
NotifyTransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionIdLevel)585 void Session::NotifyTransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
586     int64_t uiExtensionIdLevel)
587 {
588     auto lifecycleListeners = GetListeners<ILifecycleListener>();
589     for (auto& listener : lifecycleListeners) {
590         if (auto listenerPtr = listener.lock()) {
591             listenerPtr->OnAccessibilityEvent(info, uiExtensionIdLevel);
592         }
593     }
594 }
595 
NotifyExtensionDetachToDisplay()596 void Session::NotifyExtensionDetachToDisplay()
597 {
598     TLOGI(WmsLogTag::WMS_UIEXT, "called");
599     if (!SessionPermission::IsSystemCalling()) {
600         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
601         return;
602     }
603 
604     auto lifecycleListeners = GetListeners<ILifecycleListener>();
605     for (auto& listener : lifecycleListeners) {
606         if (auto listenerPtr = listener.lock()) {
607             listenerPtr->OnExtensionDetachToDisplay();
608         }
609     }
610 }
611 
GetAspectRatio() const612 float Session::GetAspectRatio() const
613 {
614     return layoutController_->GetAspectRatio();
615 }
616 
SetAspectRatio(float ratio)617 WSError Session::SetAspectRatio(float ratio)
618 {
619     layoutController_->SetAspectRatio(ratio);
620     return WSError::WS_OK;
621 }
622 
GetSessionState() const623 SessionState Session::GetSessionState() const
624 {
625     return state_;
626 }
627 
SetSessionState(SessionState state)628 void Session::SetSessionState(SessionState state)
629 {
630     if (state < SessionState::STATE_DISCONNECT || state > SessionState::STATE_END) {
631         WLOGFD("Invalid session state: %{public}u", state);
632         return;
633     }
634     state_ = state;
635     SetMainSessionUIStateDirty(true);
636 }
637 
UpdateSessionState(SessionState state)638 void Session::UpdateSessionState(SessionState state)
639 {
640     // Remove unexecuted detection tasks when the window state changes to background or destroyed.
641     if (state == SessionState::STATE_DISCONNECT ||
642         state == SessionState::STATE_INACTIVE ||
643         state == SessionState::STATE_BACKGROUND) {
644         RemoveWindowDetectTask();
645     }
646     state_ = state;
647     SetMainSessionUIStateDirty(true);
648     NotifySessionStateChange(state);
649 }
650 
UpdateSessionTouchable(bool touchable)651 void Session::UpdateSessionTouchable(bool touchable)
652 {
653     GetSessionProperty()->SetTouchable(touchable);
654     NotifySessionTouchableChange(touchable);
655 }
656 
SetFocusable(bool isFocusable)657 WSError Session::SetFocusable(bool isFocusable)
658 {
659     WLOGFI("SetFocusable id: %{public}d, focusable: %{public}d", GetPersistentId(), isFocusable);
660     GetSessionProperty()->SetFocusable(isFocusable);
661     if (isFocused_ && !GetFocusable()) {
662         FocusChangeReason reason = FocusChangeReason::FOCUSABLE;
663         NotifyRequestFocusStatusNotifyManager(false, true, reason);
664     }
665     return WSError::WS_OK;
666 }
667 
SetSystemFocusable(bool systemFocusable)668 void Session::SetSystemFocusable(bool systemFocusable)
669 {
670     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, systemFocusable: %{public}d", GetPersistentId(), systemFocusable);
671     systemFocusable_ = systemFocusable;
672     if (isFocused_ && !systemFocusable) {
673         FocusChangeReason reason = FocusChangeReason::FOCUSABLE;
674         NotifyRequestFocusStatusNotifyManager(false, true, reason);
675     }
676 }
677 
SetFocusableOnShow(bool isFocusableOnShow)678 WSError Session::SetFocusableOnShow(bool isFocusableOnShow)
679 {
680     PostTask([weakThis = wptr(this), isFocusableOnShow]() {
681         auto session = weakThis.promote();
682         if (session == nullptr) {
683             TLOGNE(WmsLogTag::WMS_FOCUS, "session is null");
684             return;
685         }
686         TLOGND(WmsLogTag::WMS_FOCUS, "id: %{public}d, focusableOnShow: %{public}d",
687             session->GetPersistentId(), isFocusableOnShow);
688         session->focusableOnShow_ = isFocusableOnShow;
689     }, __func__);
690     return WSError::WS_OK;
691 }
692 
GetFocusable() const693 bool Session::GetFocusable() const
694 {
695     return GetSessionProperty()->GetFocusable();
696 }
697 
GetSystemFocusable() const698 bool Session::GetSystemFocusable() const
699 {
700     if (parentSession_) {
701         return systemFocusable_ && parentSession_->GetSystemFocusable();
702     }
703     return systemFocusable_;
704 }
705 
CheckFocusable() const706 bool Session::CheckFocusable() const
707 {
708     return GetFocusable() && GetSystemFocusable();
709 }
710 
IsFocusableOnShow() const711 bool Session::IsFocusableOnShow() const
712 {
713     return focusableOnShow_;
714 }
715 
IsFocused() const716 bool Session::IsFocused() const
717 {
718     return isFocused_;
719 }
720 
SetNeedNotify(bool needNotify)721 void Session::SetNeedNotify(bool needNotify)
722 {
723     needNotify_ = needNotify;
724 }
725 
NeedNotify() const726 bool Session::NeedNotify() const
727 {
728     return needNotify_;
729 }
730 
SetFocusedOnShow(bool focusedOnShow)731 void Session::SetFocusedOnShow(bool focusedOnShow)
732 {
733     if (focusedOnShow == focusedOnShow_) {
734         return;
735     }
736     TLOGI(WmsLogTag::WMS_FOCUS, "[%{public}d, %{public}d]", focusedOnShow, GetPersistentId());
737     focusedOnShow_ = focusedOnShow;
738 }
739 
IsFocusedOnShow() const740 bool Session::IsFocusedOnShow() const
741 {
742     TLOGD(WmsLogTag::WMS_FOCUS, "IsFocusedOnShow:%{public}d, id: %{public}d", focusedOnShow_, GetPersistentId());
743     return focusedOnShow_;
744 }
745 
SetStartingBeforeVisible(bool isStartingBeforeVisible)746 void Session::SetStartingBeforeVisible(bool isStartingBeforeVisible)
747 {
748     isStartingBeforeVisible_ = isStartingBeforeVisible;
749 }
750 
GetStartingBeforeVisible() const751 bool Session::GetStartingBeforeVisible() const
752 {
753     return isStartingBeforeVisible_;
754 }
755 
SetTouchable(bool touchable)756 WSError Session::SetTouchable(bool touchable)
757 {
758     SetSystemTouchable(touchable);
759     if (!IsSessionValid()) {
760         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
761             GetPersistentId(), GetSessionState());
762         return WSError::WS_ERROR_INVALID_SESSION;
763     }
764     if (touchable != GetSessionProperty()->GetTouchable()) {
765         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, %{public}d", GetPersistentId(), touchable);
766     }
767     UpdateSessionTouchable(touchable);
768     return WSError::WS_OK;
769 }
770 
GetTouchable() const771 bool Session::GetTouchable() const
772 {
773     return GetSessionProperty()->GetTouchable();
774 }
775 
SetForceTouchable(bool forceTouchable)776 void Session::SetForceTouchable(bool forceTouchable)
777 {
778     if (forceTouchable != forceTouchable_) {
779         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, %{public}d", GetPersistentId(), forceTouchable);
780     }
781     forceTouchable_ = forceTouchable;
782 }
783 
SetSystemTouchable(bool touchable)784 void Session::SetSystemTouchable(bool touchable)
785 {
786     if (touchable != systemTouchable_) {
787         TLOGNI(WmsLogTag::WMS_EVENT, "sysTouch:%{public}d, %{public}d", GetPersistentId(), touchable);
788     }
789     systemTouchable_ = touchable;
790     NotifySessionInfoChange();
791 }
792 
GetSystemTouchable() const793 bool Session::GetSystemTouchable() const
794 {
795     return forceTouchable_ && systemTouchable_ && GetTouchable();
796 }
797 
IsSystemActive() const798 bool Session::IsSystemActive() const
799 {
800     return isSystemActive_;
801 }
802 
SetSystemActive(bool systemActive)803 void Session::SetSystemActive(bool systemActive)
804 {
805     isSystemActive_ = systemActive;
806     NotifySessionInfoChange();
807 }
808 
SetRSVisible(bool isVisible)809 WSError Session::SetRSVisible(bool isVisible)
810 {
811     isRSVisible_ = isVisible;
812     return WSError::WS_OK;
813 }
814 
GetRSVisible() const815 bool Session::GetRSVisible() const
816 {
817     return isRSVisible_;
818 }
819 
GetFocused() const820 bool Session::GetFocused() const
821 {
822     return isFocused_;
823 }
824 
SetVisibilityState(WindowVisibilityState state)825 WSError Session::SetVisibilityState(WindowVisibilityState state)
826 {
827     visibilityState_ = state;
828     return WSError::WS_OK;
829 }
830 
GetVisibilityState() const831 WindowVisibilityState Session::GetVisibilityState() const
832 {
833     return visibilityState_;
834 }
835 
SetDrawingContentState(bool isRSDrawing)836 WSError Session::SetDrawingContentState(bool isRSDrawing)
837 {
838     isRSDrawing_ = isRSDrawing;
839     return WSError::WS_OK;
840 }
841 
GetDrawingContentState() const842 bool Session::GetDrawingContentState() const
843 {
844     return isRSDrawing_;
845 }
846 
GetWindowId() const847 int32_t Session::GetWindowId() const
848 {
849     return GetPersistentId();
850 }
851 
SetCallingPid(int32_t id)852 void Session::SetCallingPid(int32_t id)
853 {
854     TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, %{public}d", persistentId_, id);
855     callingPid_ = id;
856     if (visibilityChangedDetectFunc_ && isVisible_) {
857         visibilityChangedDetectFunc_(callingPid_, false, isVisible_);
858     }
859 }
860 
SetCallingUid(int32_t id)861 void Session::SetCallingUid(int32_t id)
862 {
863     callingUid_ = id;
864 }
865 
GetCallingPid() const866 int32_t Session::GetCallingPid() const
867 {
868     return callingPid_;
869 }
870 
GetCallingUid() const871 int32_t Session::GetCallingUid() const
872 {
873     return callingUid_;
874 }
875 
SetAbilityToken(sptr<IRemoteObject> token)876 void Session::SetAbilityToken(sptr<IRemoteObject> token)
877 {
878     abilityToken_ = token;
879 }
880 
GetAbilityToken() const881 sptr<IRemoteObject> Session::GetAbilityToken() const
882 {
883     return abilityToken_;
884 }
885 
SetBrightness(float brightness)886 WSError Session::SetBrightness(float brightness)
887 {
888     GetSessionProperty()->SetBrightness(brightness);
889     return WSError::WS_OK;
890 }
891 
GetBrightness() const892 float Session::GetBrightness() const
893 {
894     return GetSessionProperty()->GetBrightness();
895 }
896 
IsSessionValid() const897 bool Session::IsSessionValid() const
898 {
899     if (sessionInfo_.isSystem_) {
900         WLOGFD("session is system, id: %{public}d, name: %{public}s, state: %{public}u",
901             GetPersistentId(), sessionInfo_.bundleName_.c_str(), GetSessionState());
902         return false;
903     }
904     bool res = state_ > SessionState::STATE_DISCONNECT && state_ < SessionState::STATE_END;
905     return res;
906 }
907 
IsActive() const908 bool Session::IsActive() const
909 {
910     return isActive_;
911 }
912 
IsSystemSession() const913 bool Session::IsSystemSession() const
914 {
915     return sessionInfo_.isSystem_;
916 }
917 
IsTerminated() const918 bool Session::IsTerminated() const
919 {
920     return (GetSessionState() == SessionState::STATE_DISCONNECT || isTerminating_);
921 }
922 
IsSessionForeground() const923 bool Session::IsSessionForeground() const
924 {
925     return state_ == SessionState::STATE_FOREGROUND || state_ == SessionState::STATE_ACTIVE;
926 }
927 
IsSessionNotBackground() const928 bool Session::IsSessionNotBackground() const
929 {
930     return state_ >= SessionState::STATE_DISCONNECT && state_ <= SessionState::STATE_ACTIVE;
931 }
932 
UpdateTopBottomArea(const WSRectF & rect,MMI::WindowArea area)933 WSRectF Session::UpdateTopBottomArea(const WSRectF& rect, MMI::WindowArea area)
934 {
935     const float innerBorder = INNER_BORDER_VP * vpr_;
936     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
937     const float innerAngle = INNER_ANGLE_VP * vpr_;
938     const float horizontalBorderLength = outsideBorder + innerAngle;
939     const float verticalBorderLength = outsideBorder + innerBorder;
940     const size_t innerAngleCount = 2;
941     WSRectF tbRect;
942     tbRect.posX_ = rect.posX_ + horizontalBorderLength;
943     tbRect.width_ = rect.width_ - horizontalBorderLength * innerAngleCount;
944     tbRect.height_ = verticalBorderLength;
945     if (area == MMI::WindowArea::FOCUS_ON_TOP) {
946         tbRect.posY_ = rect.posY_;
947     } else if (area == MMI::WindowArea::FOCUS_ON_BOTTOM) {
948         tbRect.posY_ = rect.posY_ + rect.height_ - verticalBorderLength;
949     } else {
950         return WSRectF();
951     }
952     return tbRect;
953 }
954 
UpdateLeftRightArea(const WSRectF & rect,MMI::WindowArea area)955 WSRectF Session::UpdateLeftRightArea(const WSRectF& rect, MMI::WindowArea area)
956 {
957     const float innerBorder = INNER_BORDER_VP * vpr_;
958     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
959     const float innerAngle = INNER_ANGLE_VP * vpr_;
960     const float verticalBorderLength = outsideBorder + innerAngle;
961     const float horizontalBorderLength = outsideBorder + innerBorder;
962     const size_t innerAngleCount = 2;
963     WSRectF lrRect;
964     lrRect.posY_ = rect.posY_ + verticalBorderLength;
965     lrRect.width_ = horizontalBorderLength;
966     lrRect.height_ = rect.height_ - verticalBorderLength * innerAngleCount;
967     if (area == MMI::WindowArea::FOCUS_ON_LEFT) {
968         lrRect.posX_ = rect.posX_;
969     } else if (area == MMI::WindowArea::FOCUS_ON_RIGHT) {
970         lrRect.posX_ = rect.posX_ + rect.width_ - horizontalBorderLength;
971     } else {
972         return WSRectF();
973     }
974     return lrRect;
975 }
976 
UpdateInnerAngleArea(const WSRectF & rect,MMI::WindowArea area)977 WSRectF Session::UpdateInnerAngleArea(const WSRectF& rect, MMI::WindowArea area)
978 {
979     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
980     const float innerAngle = INNER_ANGLE_VP * vpr_;
981     WSRectF iaRect;
982     iaRect.width_ = outsideBorder + innerAngle;
983     iaRect.height_ = outsideBorder + innerAngle;
984     if (area == MMI::WindowArea::FOCUS_ON_TOP_LEFT) {
985         iaRect.posX_ = rect.posX_;
986         iaRect.posY_ = rect.posY_;
987     } else if (area == MMI::WindowArea::FOCUS_ON_TOP_RIGHT) {
988         iaRect.posX_ = rect.posX_ + rect.width_ - iaRect.width_;
989         iaRect.posY_ = rect.posY_;
990     } else if (area == MMI::WindowArea::FOCUS_ON_BOTTOM_LEFT) {
991         iaRect.posX_ = rect.posX_;
992         iaRect.posY_ = rect.posY_ + rect.height_ - iaRect.height_;
993     } else if (area == MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT) {
994         iaRect.posX_ = rect.posX_ + rect.width_ - iaRect.width_;
995         iaRect.posY_ = rect.posY_ + rect.height_ - iaRect.height_;
996     } else {
997         return WSRectF();
998     }
999     return iaRect;
1000 }
1001 
UpdateHotRect(const WSRect & rect)1002 WSRectF Session::UpdateHotRect(const WSRect& rect)
1003 {
1004     WSRectF newRect;
1005     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
1006     const size_t outsideBorderCount = 2;
1007     newRect.posX_ = rect.posX_ - outsideBorder;
1008     newRect.posY_ = rect.posY_ - outsideBorder;
1009     newRect.width_ = rect.width_ + outsideBorder * outsideBorderCount;
1010     newRect.height_ = rect.height_ + outsideBorder * outsideBorderCount;
1011     return newRect;
1012 }
1013 
UpdatePointerArea(const WSRect & rect)1014 void Session::UpdatePointerArea(const WSRect& rect)
1015 {
1016     if (preRect_ == rect) {
1017         WLOGFD("The window area does not change");
1018         return;
1019     }
1020     WSRectF hotRect = UpdateHotRect(rect);
1021     for (const auto &[area, _] : windowAreas_) {
1022         if (area == MMI::WindowArea::FOCUS_ON_TOP || area == MMI::WindowArea::FOCUS_ON_BOTTOM) {
1023             windowAreas_[area] = UpdateTopBottomArea(hotRect, area);
1024         } else if (area == MMI::WindowArea::FOCUS_ON_RIGHT || area == MMI::WindowArea::FOCUS_ON_LEFT) {
1025             windowAreas_[area] = UpdateLeftRightArea(hotRect, area);
1026         } else if (area == MMI::WindowArea::FOCUS_ON_TOP_LEFT || area == MMI::WindowArea::FOCUS_ON_TOP_RIGHT ||
1027             area == MMI::WindowArea::FOCUS_ON_BOTTOM_LEFT || area == MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT) {
1028             windowAreas_[area] = UpdateInnerAngleArea(hotRect, area);
1029         }
1030     }
1031     preRect_ = rect;
1032 }
1033 
UpdateSizeChangeReason(SizeChangeReason reason)1034 WSError Session::UpdateSizeChangeReason(SizeChangeReason reason)
1035 {
1036     if (GetSizeChangeReason() == reason) {
1037         return WSError::WS_DO_NOTHING;
1038     }
1039     GetLayoutController()->UpdateSizeChangeReason(reason);
1040     return WSError::WS_OK;
1041 }
1042 
IsDraggingReason(SizeChangeReason reason) const1043 bool Session::IsDraggingReason(SizeChangeReason reason) const
1044 {
1045     return reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_MOVE ||
1046            reason == SizeChangeReason::DRAG_START;
1047 }
1048 
UpdateClientDisplayId(DisplayId displayId)1049 WSError Session::UpdateClientDisplayId(DisplayId displayId)
1050 {
1051     if (sessionStage_ == nullptr) {
1052         TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage_ is nullptr");
1053         return WSError::WS_ERROR_NULLPTR;
1054     }
1055     TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d move display %{public}" PRIu64 " from %{public}" PRIu64,
1056           GetPersistentId(), displayId, clientDisplayId_);
1057     sessionStage_->UpdateDisplayId(displayId);
1058     if (displayId != clientDisplayId_) {
1059         AddPropertyDirtyFlags(static_cast<uint32_t>(SessionPropertyFlag::DISPLAY_ID));
1060         NotifyDisplayIdChanged(GetPersistentId(), displayId);
1061     }
1062     clientDisplayId_ = displayId;
1063     return WSError::WS_OK;
1064 }
1065 
TransformGlobalRectToRelativeRect(WSRect & rect) const1066 DisplayId Session::TransformGlobalRectToRelativeRect(WSRect& rect) const
1067 {
1068     const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
1069         PcFoldScreenManager::GetInstance().GetDisplayRects();
1070     int32_t lowerScreenPosY = defaultDisplayRect.height_ + foldCreaseRect.height_;
1071     TLOGI(WmsLogTag::WMS_LAYOUT, "lowerScreenPosY: %{public}d", lowerScreenPosY);
1072     auto screenHeight = defaultDisplayRect.height_ + foldCreaseRect.height_ + virtualDisplayRect.height_;
1073     if (rect.posY_ > screenHeight) {
1074         rect.posY_ -= lowerScreenPosY;
1075         return clientDisplayId_;
1076     }
1077     DisplayId updatedDisplayId = DEFAULT_DISPLAY_ID;
1078     if (rect.posY_ >= lowerScreenPosY) {
1079         updatedDisplayId = VIRTUAL_DISPLAY_ID;
1080         rect.posY_ -= lowerScreenPosY;
1081     }
1082     return updatedDisplayId;
1083 }
1084 
TransformRelativeRectToGlobalRect(WSRect & rect) const1085 void Session::TransformRelativeRectToGlobalRect(WSRect& rect) const
1086 {
1087     auto currScreenFoldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
1088     auto needTransRect = currScreenFoldStatus != SuperFoldStatus::UNKNOWN &&
1089         currScreenFoldStatus != SuperFoldStatus::FOLDED && currScreenFoldStatus != SuperFoldStatus::EXPANDED;
1090     auto isSystemKeyboard = GetSessionProperty() != nullptr && GetSessionProperty()->IsSystemKeyboard();
1091     if (isSystemKeyboard || !needTransRect) {
1092         return;
1093     }
1094     const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
1095         PcFoldScreenManager::GetInstance().GetDisplayRects();
1096     int32_t lowerScreenPosY = defaultDisplayRect.height_ + foldCreaseRect.height_;
1097     if (GetSessionGlobalRect().posY_ >= lowerScreenPosY) {
1098         WSRect relativeRect = rect;
1099         rect.posY_ += lowerScreenPosY;
1100         TLOGI(WmsLogTag::WMS_LAYOUT, "Transform relativeRect: %{public}s to globalRect: %{public}s",
1101             relativeRect.ToString().c_str(), rect.ToString().c_str());
1102     }
1103 }
1104 
UpdateClientRectPosYAndDisplayId(WSRect & rect)1105 void Session::UpdateClientRectPosYAndDisplayId(WSRect& rect)
1106 {
1107     if (GetSessionProperty()->IsSystemKeyboard()) {
1108         TLOGI(WmsLogTag::WMS_LAYOUT, "skip update SystemKeyboard: %{public}d", GetPersistentId());
1109         return;
1110     }
1111     if (WindowHelper::IsUIExtensionWindow(GetWindowType())) {
1112         TLOGD(WmsLogTag::WMS_LAYOUT, "skip update UIExtension: %{public}d, rect: %{public}s",
1113             GetPersistentId(), rect.ToString().c_str());
1114         return;
1115     }
1116     if (rect.IsInvalid()) {
1117         TLOGI(WmsLogTag::WMS_LAYOUT, "skip window: %{public}d invalid rect: %{public}s",
1118             GetPersistentId(), rect.ToString().c_str());
1119         return;
1120     }
1121     auto currScreenFoldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
1122     if (currScreenFoldStatus == SuperFoldStatus::UNKNOWN || currScreenFoldStatus == SuperFoldStatus::FOLDED) {
1123         TLOGD(WmsLogTag::WMS_LAYOUT, "Error status");
1124         return;
1125     }
1126     if (GetScreenId() != DISPLAY_ID_INVALID &&
1127         !PcFoldScreenManager::GetInstance().IsPcFoldScreen(GetScreenId())) {
1128         TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, displayId: %{public}" PRIu64 " not need",
1129             GetPersistentId(), GetScreenId());
1130         return;
1131     }
1132     TLOGI(WmsLogTag::WMS_LAYOUT, "lastStatus: %{public}d, curStatus: %{public}d",
1133         lastScreenFoldStatus_, currScreenFoldStatus);
1134     if (currScreenFoldStatus == SuperFoldStatus::EXPANDED || currScreenFoldStatus == SuperFoldStatus::KEYBOARD) {
1135         lastScreenFoldStatus_ = currScreenFoldStatus;
1136         auto ret = UpdateClientDisplayId(DEFAULT_DISPLAY_ID);
1137         TLOGI(WmsLogTag::WMS_LAYOUT, "JustUpdateId: winId: %{public}d, result: %{public}d",
1138             GetPersistentId(), ret);
1139         return;
1140     }
1141     WSRect lastRect = rect;
1142     auto updatedDisplayId = TransformGlobalRectToRelativeRect(rect);
1143     auto ret = UpdateClientDisplayId(updatedDisplayId);
1144     lastScreenFoldStatus_ = currScreenFoldStatus;
1145     configDisplayId_ = DISPLAY_ID_INVALID;
1146     TLOGI(WmsLogTag::WMS_LAYOUT, "CalculatedRect: winId: %{public}d, input: %{public}s, output: %{public}s,"
1147         " result: %{public}d, clientDisplayId: %{public}" PRIu64, GetPersistentId(), lastRect.ToString().c_str(),
1148         rect.ToString().c_str(), ret, updatedDisplayId);
1149 }
1150 
SetSingleHandTransform(const SingleHandTransform & transform)1151 void Session::SetSingleHandTransform(const SingleHandTransform& transform)
1152 {
1153     singleHandTransform_ = transform;
1154 }
1155 
GetSingleHandTransform() const1156 SingleHandTransform Session::GetSingleHandTransform() const
1157 {
1158     return singleHandTransform_;
1159 }
1160 
SetSingleHandModeFlag(bool flag)1161 void Session::SetSingleHandModeFlag(bool flag)
1162 {
1163     singleHandModeFlag_ = flag;
1164 }
1165 
SessionIsSingleHandMode()1166 bool Session::SessionIsSingleHandMode()
1167 {
1168     return singleHandModeFlag_;
1169 }
1170 
1171 
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::string & updateReason,const std::shared_ptr<RSTransaction> & rsTransaction)1172 WSError Session::UpdateRect(const WSRect& rect, SizeChangeReason reason,
1173     const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)
1174 {
1175     return UpdateRectWithLayoutInfo(rect, reason, updateReason, rsTransaction, {});
1176 }
1177 
UpdateRectWithLayoutInfo(const WSRect & rect,SizeChangeReason reason,const std::string & updateReason,const std::shared_ptr<RSTransaction> & rsTransaction,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)1178 WSError Session::UpdateRectWithLayoutInfo(const WSRect& rect, SizeChangeReason reason,
1179     const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction,
1180     const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
1181 {
1182     TLOGD(WmsLogTag::WMS_LAYOUT, "session update rect: id: %{public}d, rect:%{public}s, "
1183         "reason:%{public}u %{public}s", GetPersistentId(), rect.ToString().c_str(), reason, updateReason.c_str());
1184     if (!IsSessionValid()) {
1185         GetLayoutController()->SetSessionRect(rect);
1186         TLOGD(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
1187             GetPersistentId(), GetSessionState());
1188         return WSError::WS_ERROR_INVALID_SESSION;
1189     }
1190     GetLayoutController()->SetSessionRect(rect);
1191     WSRect updateRect = IsNeedConvertToRelativeRect(reason) ?
1192         GetLayoutController()->ConvertGlobalRectToRelative(rect, GetDisplayId()) : rect;
1193 
1194     // Window Layout Global Coordinate System
1195     auto globalDisplayRect = SessionCoordinateHelper::RelativeToGlobalDisplayRect(GetScreenId(), updateRect);
1196     UpdateGlobalDisplayRect(globalDisplayRect, reason);
1197 
1198     if (!Session::IsBackgroundUpdateRectNotifyEnabled() && !IsSessionForeground()) {
1199         return WSError::WS_DO_NOTHING;
1200     }
1201     if (sessionStage_ != nullptr) {
1202         int32_t rotateAnimationDuration = GetRotateAnimationDuration();
1203         SceneAnimationConfig config { .rsTransaction_ = rsTransaction, .animationDuration_ = rotateAnimationDuration };
1204         UpdateClientRectPosYAndDisplayId(updateRect);
1205         sessionStage_->UpdateRect(updateRect, reason, config, avoidAreas);
1206         SetClientRect(rect);
1207         RectCheckProcess();
1208     } else {
1209         WLOGFE("sessionStage_ is nullptr");
1210     }
1211     UpdatePointerArea(GetSessionRect());
1212     return WSError::WS_OK;
1213 }
1214 
UpdateDensity()1215 WSError Session::UpdateDensity()
1216 {
1217     WLOGFI("session update density: id: %{public}d.", GetPersistentId());
1218     if (!IsSessionValid()) {
1219         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
1220             GetPersistentId(), GetSessionState());
1221         return WSError::WS_ERROR_INVALID_SESSION;
1222     }
1223     if (sessionStage_ != nullptr) {
1224         sessionStage_->UpdateDensity();
1225     } else {
1226         WLOGFE("Session::UpdateDensity sessionStage_ is nullptr");
1227         return WSError::WS_ERROR_NULLPTR;
1228     }
1229     return WSError::WS_OK;
1230 }
1231 
UpdateOrientation()1232 WSError Session::UpdateOrientation()
1233 {
1234     TLOGD(WmsLogTag::DMS, "id: %{public}d.", GetPersistentId());
1235     if (!IsSessionValid()) {
1236         TLOGE(WmsLogTag::DMS, "session is invalid, id=%{public}d.",
1237             GetPersistentId());
1238         return WSError::WS_ERROR_INVALID_SESSION;
1239     }
1240     if (sessionStage_ == nullptr) {
1241         TLOGE(WmsLogTag::DMS, "sessionStage_ is nullptr, id=%{public}d.",
1242             GetPersistentId());
1243         return WSError::WS_ERROR_NULLPTR;
1244     }
1245     return sessionStage_->UpdateOrientation();
1246 }
1247 
ConnectInner(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,SystemSessionConfig & systemConfig,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,int32_t pid,int32_t uid,const std::string & identityToken)1248 __attribute__((no_sanitize("cfi"))) WSError Session::ConnectInner(const sptr<ISessionStage>& sessionStage,
1249     const sptr<IWindowEventChannel>& eventChannel,
1250     const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1251     SystemSessionConfig& systemConfig, sptr<WindowSessionProperty> property,
1252     sptr<IRemoteObject> token, int32_t pid, int32_t uid, const std::string& identityToken)
1253 {
1254     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] ConnectInner session, state: %{public}u,"
1255         "isTerminating:%{public}d, callingPid:%{public}d, disableDelegator:%{public}d", GetPersistentId(),
1256         static_cast<uint32_t>(GetSessionState()), isTerminating_, pid, property->GetIsAbilityHookOff());
1257     if (GetSessionState() != SessionState::STATE_DISCONNECT && !isTerminating_ &&
1258         !GetSessionInfo().reuseDelegatorWindow) {
1259         TLOGE(WmsLogTag::WMS_LIFE, "state is not disconnect state:%{public}u id:%{public}u!, reuse %{public}d",
1260             GetSessionState(), GetPersistentId(), GetSessionInfo().reuseDelegatorWindow);
1261         return WSError::WS_ERROR_INVALID_SESSION;
1262     }
1263     if (sessionStage == nullptr || eventChannel == nullptr) {
1264         TLOGE(WmsLogTag::WMS_LIFE, "session stage or eventChannel is nullptr");
1265         return WSError::WS_ERROR_NULLPTR;
1266     }
1267     sessionStage_ = sessionStage;
1268     NotifyAppHookWindowInfoUpdated();
1269     sessionStage_->SetCurrentRotation(currentRotation_);
1270     windowEventChannel_ = eventChannel;
1271     SetSurfaceNode(surfaceNode);
1272     abilityToken_ = token;
1273     systemConfig = systemConfig_;
1274     InitSessionPropertyWhenConnect(property);
1275     SetCallingPid(pid);
1276     callingUid_ = uid;
1277     UpdateSessionState(SessionState::STATE_CONNECT);
1278     WindowHelper::IsUIExtensionWindow(GetWindowType()) ?
1279         UpdateRect(GetSessionRect(), SizeChangeReason::UNDEFINED, "Connect") :
1280         NotifyClientToUpdateRect("Connect", nullptr);
1281     EditSessionInfo().disableDelegator = property->GetIsAbilityHookOff();
1282     NotifyConnect();
1283     if (WindowHelper::IsSubWindow(GetWindowType()) && surfaceNode_ != nullptr) {
1284         surfaceNode_->SetFrameGravity(Gravity::TOP_LEFT);
1285     }
1286     return WSError::WS_OK;
1287 }
1288 
InitSessionPropertyWhenConnect(const sptr<WindowSessionProperty> & property)1289 void Session::InitSessionPropertyWhenConnect(const sptr<WindowSessionProperty>& property)
1290 {
1291     if (property == nullptr) {
1292         return;
1293     }
1294     if (GetSessionProperty()->GetIsNeedUpdateWindowMode()) {
1295         property->SetIsNeedUpdateWindowMode(true);
1296         property->SetWindowMode(GetSessionProperty()->GetWindowMode());
1297     }
1298     if (SessionHelper::IsMainWindow(GetWindowType()) && GetSessionInfo().screenId_ != SCREEN_ID_INVALID) {
1299         property->SetDisplayId(GetSessionInfo().screenId_);
1300     }
1301     if (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) {
1302         InitSystemSessionDragEnable(property);
1303     } else {
1304         property->SetDragEnabled(false);
1305     }
1306     property->SetSessionPropertyChangeCallback(
1307         [weakThis = wptr(this)]() {
1308             auto session = weakThis.promote();
1309             if (session == nullptr) {
1310                 TLOGNE(WmsLogTag::DEFAULT, "session is null");
1311                 return;
1312             }
1313             session->NotifySessionInfoChange();
1314         });
1315 
1316     WSRect winRect = GetSessionRect();
1317     Rect rect = {winRect.posX_, winRect.posY_, static_cast<uint32_t>(winRect.width_),
1318         static_cast<uint32_t>(winRect.height_)};
1319     property->SetWindowRect(rect);
1320     property->SetPersistentId(GetPersistentId());
1321     property->SetFullScreenStart(GetSessionInfo().fullScreenStart_);
1322     property->SetSupportedWindowModes(GetSessionInfo().supportedWindowModes);
1323     property->SetWindowSizeLimits(GetSessionInfo().windowSizeLimits);
1324     property->SetIsAtomicService(GetSessionInfo().isAtomicService_);
1325     property->SetRequestedOrientation(GetSessionProperty()->GetRequestedOrientation());
1326     property->SetDefaultRequestedOrientation(GetSessionProperty()->GetDefaultRequestedOrientation());
1327     property->SetUserRequestedOrientation(GetSessionProperty()->GetUserRequestedOrientation());
1328     TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] requestedOrientation: %{public}u,"
1329         " defaultRequestedOrientation: %{public}u,"
1330         " userRequestedOrientation: %{public}u", GetPersistentId(),
1331         static_cast<uint32_t>(GetSessionProperty()->GetRequestedOrientation()),
1332         static_cast<uint32_t>(GetSessionProperty()->GetDefaultRequestedOrientation()),
1333         static_cast<uint32_t>(GetSessionProperty()->GetUserRequestedOrientation()));
1334     property->SetCompatibleModeProperty(GetSessionProperty()->GetCompatibleModeProperty());
1335     if (property->GetCompatibleModeProperty()) {
1336         property->SetDragEnabled(!GetSessionProperty()->IsDragResizeDisabled());
1337     }
1338     if (property->IsAdaptToEventMapping()) {
1339         std::vector<Rect> touchHotAreas;
1340         GetSessionProperty()->GetTouchHotAreas(touchHotAreas);
1341         property->SetTouchHotAreas(touchHotAreas);
1342     }
1343     property->SetIsAppSupportPhoneInPc(GetSessionProperty()->GetIsAppSupportPhoneInPc());
1344     std::optional<bool> clientDragEnable = GetClientDragEnable();
1345     if (clientDragEnable.has_value()) {
1346         property->SetDragEnabled(clientDragEnable.value());
1347     }
1348     if (SessionHelper::IsMainWindow(GetWindowType())) {
1349         property->SetIsPcAppInPad(GetSessionProperty()->GetIsPcAppInPad());
1350     }
1351     property->SetSkipSelfWhenShowOnVirtualScreen(GetSessionProperty()->GetSkipSelfWhenShowOnVirtualScreen());
1352     property->SetSkipEventOnCastPlus(GetSessionProperty()->GetSkipEventOnCastPlus());
1353     property->SetIsAbilityHook(GetSessionInfo().isAbilityHook_);
1354     property->SetPcAppInpadCompatibleMode(GetSessionProperty()->GetPcAppInpadCompatibleMode());
1355     property->SetPcAppInpadSpecificSystemBarInvisible(GetSessionProperty()->GetPcAppInpadSpecificSystemBarInvisible());
1356     property->SetPcAppInpadOrientationLandscape(GetSessionProperty()->GetPcAppInpadOrientationLandscape());
1357     SetSessionProperty(property);
1358     GetSessionProperty()->SetIsNeedUpdateWindowMode(false);
1359 }
1360 
InitSystemSessionDragEnable(const sptr<WindowSessionProperty> & property)1361 void Session::InitSystemSessionDragEnable(const sptr<WindowSessionProperty>& property)
1362 {
1363     auto defaultDragEnable = false;
1364     auto isSystemWindow = WindowHelper::IsSystemWindow(property->GetWindowType());
1365     bool isDialog = WindowHelper::IsDialogWindow(property->GetWindowType());
1366     bool isSystemCalling = property->GetSystemCalling();
1367     TLOGI(WmsLogTag::WMS_LAYOUT, "windId: %{public}d, defaultDragEnable: %{public}d, isSystemWindow: %{public}d, "
1368         "isDialog: %{public}d, isSystemCalling: %{public}d", GetPersistentId(), defaultDragEnable,
1369         isSystemWindow, isDialog, isSystemCalling);
1370     if (isSystemWindow && !isDialog && !isSystemCalling) {
1371         property->SetDragEnabled(defaultDragEnable);
1372     }
1373 }
1374 
Reconnect(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,int32_t pid,int32_t uid)1375 WSError Session::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
1376     const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
1377     int32_t pid, int32_t uid)
1378 {
1379     if (property == nullptr) {
1380         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
1381         return WSError::WS_ERROR_NULLPTR;
1382     }
1383     TLOGI(WmsLogTag::WMS_RECOVER, "id:%{public}d, state:%{public}u, pid:%{public}d, disableDelegator:%{public}d",
1384         property->GetPersistentId(), static_cast<uint32_t>(property->GetWindowState()), pid,
1385         property->GetIsAbilityHookOff());
1386     if (sessionStage == nullptr || eventChannel == nullptr) {
1387         TLOGE(WmsLogTag::WMS_RECOVER, "session stage or eventChannel is nullptr");
1388         return WSError::WS_ERROR_NULLPTR;
1389     }
1390     sessionStage_ = sessionStage;
1391     NotifyAppHookWindowInfoUpdated();
1392     SetSurfaceNode(surfaceNode);
1393     windowEventChannel_ = eventChannel;
1394     abilityToken_ = token;
1395     SetSessionPropertyForReconnect(property);
1396     persistentId_ = property->GetPersistentId();
1397     SetCallingPid(pid);
1398     callingUid_ = uid;
1399     bufferAvailable_ = true;
1400     auto windowRect = property->GetWindowRect();
1401     layoutRect_ = { windowRect.posX_, windowRect.posY_,
1402         static_cast<int32_t>(windowRect.width_), static_cast<int32_t>(windowRect.height_) };
1403     UpdateSessionState(SessionState::STATE_CONNECT);
1404     EditSessionInfo().disableDelegator = property->GetIsAbilityHookOff();
1405     for (const auto& [transitionType, animation] : property->GetTransitionAnimationConfig()) {
1406         property_->SetTransitionAnimationConfig(transitionType, *animation);
1407     }
1408     return WSError::WS_OK;
1409 }
1410 
Foreground(sptr<WindowSessionProperty> property,bool isFromClient,const std::string & identityToken)1411 WSError Session::Foreground(sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)
1412 {
1413     HandleDialogForeground();
1414     SessionState state = GetSessionState();
1415     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] state:%{public}u, isTerminating:%{public}d",
1416         GetPersistentId(), static_cast<uint32_t>(state), isTerminating_);
1417     if (state != SessionState::STATE_CONNECT && state != SessionState::STATE_BACKGROUND &&
1418         state != SessionState::STATE_INACTIVE) {
1419         TLOGE(WmsLogTag::WMS_LIFE, "Foreground state invalid! state:%{public}u", state);
1420         return WSError::WS_ERROR_INVALID_SESSION;
1421     }
1422 
1423     UpdateSessionState(SessionState::STATE_FOREGROUND);
1424     if (!isActive_ || (isActive_ && GetSessionInfo().reuseDelegatorWindow)) {
1425         SetActive(true);
1426     }
1427     isStarting_ = false;
1428     NotifyForeground();
1429 
1430     isTerminating_ = false;
1431     PostSpecificSessionLifeCycleTimeoutTask(ATTACH_EVENT_NAME);
1432 
1433     // Window Layout Global Coordinate System
1434     // When the window enters foreground, notify the client to update GlobalDisplayRect once,
1435     // since background windows skip this notification to avoid IPC wake-up and power issues.
1436     NotifyClientToUpdateGlobalDisplayRect(GetGlobalDisplayRect(), SizeChangeReason::UNDEFINED);
1437     return WSError::WS_OK;
1438 }
1439 
HandleDialogBackground()1440 void Session::HandleDialogBackground()
1441 {
1442     const auto& type = GetWindowType();
1443     if (type < WindowType::APP_MAIN_WINDOW_BASE || type >= WindowType::APP_MAIN_WINDOW_END) {
1444         TLOGD(WmsLogTag::WMS_DIALOG, "Current session is not main window, id: %{public}d, type: %{public}d",
1445             GetPersistentId(), type);
1446         return;
1447     }
1448 
1449     auto dialogVec = GetDialogVector();
1450     for (const auto& dialog : dialogVec) {
1451         if (dialog == nullptr) {
1452             continue;
1453         }
1454         TLOGI(WmsLogTag::WMS_DIALOG, "Background dialog, id: %{public}d, dialogId: %{public}d",
1455             GetPersistentId(), dialog->GetPersistentId());
1456         if (!dialog->sessionStage_) {
1457             TLOGE(WmsLogTag::WMS_DIALOG, "dialog session stage is nullptr");
1458             return;
1459         }
1460         dialog->sessionStage_->NotifyDialogStateChange(false);
1461     }
1462 }
1463 
HandleDialogForeground()1464 void Session::HandleDialogForeground()
1465 {
1466     const auto& type = GetWindowType();
1467     if (type < WindowType::APP_MAIN_WINDOW_BASE || type >= WindowType::APP_MAIN_WINDOW_END) {
1468         TLOGD(WmsLogTag::WMS_DIALOG, "Current session is not main window, id: %{public}d, type: %{public}d",
1469             GetPersistentId(), type);
1470         return;
1471     }
1472 
1473     auto dialogVec = GetDialogVector();
1474     for (const auto& dialog : dialogVec) {
1475         if (dialog == nullptr) {
1476             continue;
1477         }
1478         TLOGI(WmsLogTag::WMS_DIALOG, "Foreground dialog, id: %{public}d, dialogId: %{public}d",
1479             GetPersistentId(), dialog->GetPersistentId());
1480         if (!dialog->sessionStage_) {
1481             TLOGE(WmsLogTag::WMS_DIALOG, "dialog session stage is nullptr");
1482             return;
1483         }
1484         dialog->sessionStage_->NotifyDialogStateChange(true);
1485     }
1486 }
1487 
Background(bool isFromClient,const std::string & identityToken)1488 WSError Session::Background(bool isFromClient, const std::string& identityToken)
1489 {
1490     HandleDialogBackground();
1491     SessionState state = GetSessionState();
1492     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] Background session, state: %{public}" PRIu32, GetPersistentId(),
1493         static_cast<uint32_t>(state));
1494     if (state == SessionState::STATE_ACTIVE && GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1495         UpdateSessionState(SessionState::STATE_INACTIVE);
1496         state = SessionState::STATE_INACTIVE;
1497         isActive_ = false;
1498     }
1499     isStarting_ = false;
1500     isStartingBeforeVisible_ = false;
1501     if (state != SessionState::STATE_INACTIVE) {
1502         TLOGW(WmsLogTag::WMS_LIFE, "[id: %{public}d] Background state invalid! state: %{public}u",
1503             GetPersistentId(), state);
1504         return WSError::WS_ERROR_INVALID_SESSION;
1505     }
1506     UpdateSessionState(SessionState::STATE_BACKGROUND);
1507     lastSnapshotScreen_ = WSSnapshotHelper::GetScreenStatus();
1508     SetIsPendingToBackgroundState(false);
1509     NotifyBackground();
1510     PostSpecificSessionLifeCycleTimeoutTask(DETACH_EVENT_NAME);
1511     return WSError::WS_OK;
1512 }
1513 
ResetSessionConnectState()1514 void Session::ResetSessionConnectState()
1515 {
1516     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] ResetSessionState, state: %{public}u",
1517         GetPersistentId(), GetSessionState());
1518     SetSessionState(SessionState::STATE_DISCONNECT);
1519     SetCallingPid(-1);
1520 }
1521 
ResetIsActive()1522 void Session::ResetIsActive()
1523 {
1524     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] isActive: %{public}u",
1525         GetPersistentId(), IsActive());
1526     isActive_ = false;
1527 }
1528 
Disconnect(bool isFromClient,const std::string & identityToken)1529 WSError Session::Disconnect(bool isFromClient, const std::string& identityToken)
1530 {
1531     auto state = GetSessionState();
1532     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] Disconnect session, state: %{public}u", GetPersistentId(), state);
1533     isActive_ = false;
1534     isStarting_ = false;
1535     isStartingBeforeVisible_ = false;
1536     bufferAvailable_ = false;
1537     isNeedSyncSessionRect_ = true;
1538     if (mainHandler_) {
1539         std::shared_ptr<RSSurfaceNode> surfaceNode;
1540         {
1541             std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
1542             surfaceNode_.swap(surfaceNode);
1543         }
1544         mainHandler_->PostTask([surfaceNode = std::move(surfaceNode)]() mutable {
1545             surfaceNode.reset();
1546         });
1547     }
1548     UpdateSessionState(SessionState::STATE_BACKGROUND);
1549     UpdateSessionState(SessionState::STATE_DISCONNECT);
1550     lastSnapshotScreen_ = WSSnapshotHelper::GetScreenStatus();
1551     NotifyDisconnect();
1552     if (visibilityChangedDetectFunc_) {
1553         visibilityChangedDetectFunc_(GetCallingPid(), isVisible_, false);
1554     }
1555     return WSError::WS_OK;
1556 }
1557 
Show(sptr<WindowSessionProperty> property)1558 WSError Session::Show(sptr<WindowSessionProperty> property)
1559 {
1560     TLOGD(WmsLogTag::WMS_LIFE, "Show session, id: %{public}d", GetPersistentId());
1561     return WSError::WS_OK;
1562 }
1563 
Hide()1564 WSError Session::Hide()
1565 {
1566     TLOGD(WmsLogTag::WMS_LIFE, "Hide session, id: %{public}d", GetPersistentId());
1567     return WSError::WS_OK;
1568 }
1569 
DrawingCompleted()1570 WSError Session::DrawingCompleted()
1571 {
1572     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
1573     if (!SessionPermission::IsSystemAppCall()) {
1574         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
1575         return WSError::WS_ERROR_INVALID_PERMISSION;
1576     }
1577     auto lifecycleListeners = GetListeners<ILifecycleListener>();
1578     for (auto& listener : lifecycleListeners) {
1579         if (auto listenerPtr = listener.lock()) {
1580             listenerPtr->OnDrawingCompleted();
1581         }
1582     }
1583     return WSError::WS_OK;
1584 }
1585 
RemoveStartingWindow()1586 WSError Session::RemoveStartingWindow()
1587 {
1588     auto lifecycleListeners = GetListeners<ILifecycleListener>();
1589     for (auto& listener : lifecycleListeners) {
1590         if (auto listenerPtr = listener.lock()) {
1591             listenerPtr->OnAppRemoveStartingWindow();
1592         }
1593     }
1594     return WSError::WS_OK;
1595 }
1596 
SetActive(bool active)1597 WSError Session::SetActive(bool active)
1598 {
1599     SessionState state = GetSessionState();
1600     TLOGI(WmsLogTag::WMS_LIFE, "new active:%{public}d, id:%{public}d, state:%{public}u",
1601         active, GetPersistentId(), static_cast<uint32_t>(state));
1602     if (!IsSessionValid()) {
1603         TLOGW(WmsLogTag::WMS_LIFE, "Session is invalid, id: %{public}d state: %{public}u",
1604             GetPersistentId(), GetSessionState());
1605         return WSError::WS_ERROR_INVALID_SESSION;
1606     }
1607     if (active == isActive_ && !GetSessionInfo().reuseDelegatorWindow) {
1608         TLOGD(WmsLogTag::WMS_LIFE, "Session active do not change: [%{public}d]", active);
1609         return WSError::WS_DO_NOTHING;
1610     }
1611     if (!sessionStage_) {
1612         TLOGE(WmsLogTag::WMS_LIFE, "session stage is nullptr");
1613         return WSError::WS_ERROR_NULLPTR;
1614     }
1615     if (active && GetSessionState() == SessionState::STATE_FOREGROUND) {
1616         sessionStage_->SetActive(true);
1617         UpdateSessionState(SessionState::STATE_ACTIVE);
1618         isActive_ = active;
1619     }
1620     if (!active && GetSessionState() == SessionState::STATE_ACTIVE) {
1621         sessionStage_->SetActive(false);
1622         UpdateSessionState(SessionState::STATE_INACTIVE);
1623         isActive_ = active;
1624     }
1625     return WSError::WS_OK;
1626 }
1627 
ProcessClickModalWindowOutside(int32_t posX,int32_t posY)1628 void Session::ProcessClickModalWindowOutside(int32_t posX, int32_t posY)
1629 {
1630     if (clickModalWindowOutsideFunc_ && !GetSessionRect().IsInRegion(posX, posY)) {
1631         clickModalWindowOutsideFunc_();
1632     }
1633 }
1634 
SetClickModalWindowOutsideListener(NotifyClickModalWindowOutsideFunc && func)1635 void Session::SetClickModalWindowOutsideListener(NotifyClickModalWindowOutsideFunc&& func)
1636 {
1637     const char* const where = __func__;
1638     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1639         auto session = weakThis.promote();
1640         if (!session || !func) {
1641             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session or func is null", where);
1642             return;
1643         }
1644         session->clickModalWindowOutsideFunc_ = std::move(func);
1645         TLOGNI(WmsLogTag::WMS_DIALOG, "%{public}s id: %{public}d", where, session->GetPersistentId());
1646     }, __func__);
1647 }
1648 
SetClientDragEnable(bool dragEnable)1649 void Session::SetClientDragEnable(bool dragEnable)
1650 {
1651     clientDragEnable_ = dragEnable;
1652 }
1653 
GetClientDragEnable() const1654 std::optional<bool> Session::GetClientDragEnable() const
1655 {
1656     return clientDragEnable_;
1657 }
1658 
SetDragActivated(bool dragActivated)1659 void Session::SetDragActivated(bool dragActivated)
1660 {
1661     dragActivated_ = dragActivated;
1662 }
1663 
IsDragAccessible() const1664 bool Session::IsDragAccessible() const
1665 {
1666     bool isDragEnabled = GetSessionProperty()->GetDragEnabled();
1667     TLOGD(WmsLogTag::WMS_LAYOUT, "PersistentId: %{public}d, dragEnabled: %{public}d, dragActivate: %{public}d",
1668         GetPersistentId(), isDragEnabled, dragActivated_);
1669     return isDragEnabled && dragActivated_;
1670 }
1671 
IsScreenLockWindow() const1672 bool Session::IsScreenLockWindow() const
1673 {
1674     return isScreenLockWindow_;
1675 }
1676 
NotifyForegroundInteractiveStatus(bool interactive)1677 void Session::NotifyForegroundInteractiveStatus(bool interactive)
1678 {
1679     SetForegroundInteractiveStatus(interactive);
1680 }
1681 
SetForegroundInteractiveStatus(bool interactive)1682 void Session::SetForegroundInteractiveStatus(bool interactive)
1683 {
1684     if (interactive != GetForegroundInteractiveStatus()) {
1685         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, %{public}d", GetPersistentId(),
1686             static_cast<int>(interactive));
1687     }
1688     foregroundInteractiveStatus_.store(interactive);
1689     if (Session::IsScbCoreEnabled()) {
1690         return;
1691     }
1692     NotifySessionInfoChange();
1693 }
1694 
GetForegroundInteractiveStatus() const1695 bool Session::GetForegroundInteractiveStatus() const
1696 {
1697     return foregroundInteractiveStatus_.load();
1698 }
1699 
GetIsPendingToBackgroundState() const1700 bool Session::GetIsPendingToBackgroundState() const
1701 {
1702     return isPendingToBackgroundState_.load();
1703 }
1704 
SetIsPendingToBackgroundState(bool isPendingToBackgroundState)1705 void Session::SetIsPendingToBackgroundState(bool isPendingToBackgroundState)
1706 {
1707     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d isPendingToBackgroundState:%{public}d",
1708         GetPersistentId(), isPendingToBackgroundState);
1709     return isPendingToBackgroundState_.store(isPendingToBackgroundState);
1710 }
1711 
IsActivatedAfterScreenLocked() const1712 bool Session::IsActivatedAfterScreenLocked() const
1713 {
1714     return isActivatedAfterScreenLocked_.load();
1715 }
1716 
SetIsActivatedAfterScreenLocked(bool isActivatedAfterScreenLocked)1717 void Session::SetIsActivatedAfterScreenLocked(bool isActivatedAfterScreenLocked)
1718 {
1719     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, isActivatedAfterScreenLocked:%{public}d",
1720         GetPersistentId(), isActivatedAfterScreenLocked);
1721     isActivatedAfterScreenLocked_.store(isActivatedAfterScreenLocked);
1722 }
1723 
SetAttachState(bool isAttach,WindowMode windowMode)1724 void Session::SetAttachState(bool isAttach, WindowMode windowMode)
1725 {
1726     isAttach_ = isAttach;
1727     if (handler_ && IsNeedReportTimeout()) {
1728         handler_->RemoveTask(isAttach_ ? ATTACH_EVENT_NAME : DETACH_EVENT_NAME);
1729     }
1730     PostTask([weakThis = wptr(this), isAttach]() {
1731         auto session = weakThis.promote();
1732         if (session == nullptr) {
1733             TLOGND(WmsLogTag::WMS_LIFE, "session is null");
1734             return;
1735         }
1736         if (session->sessionStage_ && WindowHelper::IsNeedWaitAttachStateWindow(session->GetWindowType())) {
1737             TLOGNI(WmsLogTag::WMS_LIFE, "NotifyWindowAttachStateChange, persistentId:%{public}d",
1738                 session->GetPersistentId());
1739             session->sessionStage_->NotifyWindowAttachStateChange(isAttach);
1740         }
1741         TLOGND(WmsLogTag::WMS_LIFE, "isAttach:%{public}d persistentId:%{public}d", isAttach,
1742             session->GetPersistentId());
1743         if (!isAttach && session->detachCallback_ != nullptr) {
1744             TLOGNI(WmsLogTag::WMS_LIFE, "Session detach, persistentId:%{public}d", session->GetPersistentId());
1745             session->detachCallback_->OnPatternDetach(session->GetPersistentId());
1746             session->detachCallback_ = nullptr;
1747         }
1748     }, "SetAttachState");
1749     CreateDetectStateTask(isAttach, windowMode);
1750 }
1751 
CreateDetectStateTask(bool isAttach,WindowMode windowMode)1752 void Session::CreateDetectStateTask(bool isAttach, WindowMode windowMode)
1753 {
1754     if (!IsSupportDetectWindow(isAttach)) {
1755         return;
1756     }
1757     if (showRecent_) {
1758         return;
1759     }
1760     if (!ShouldCreateDetectTask(isAttach, windowMode)) {
1761         RemoveWindowDetectTask();
1762         DetectTaskInfo detectTaskInfo;
1763         SetDetectTaskInfo(detectTaskInfo);
1764         return;
1765     }
1766     CreateWindowStateDetectTask(isAttach, windowMode);
1767 }
1768 
RegisterDetachCallback(const sptr<IPatternDetachCallback> & callback)1769 void Session::RegisterDetachCallback(const sptr<IPatternDetachCallback>& callback)
1770 {
1771     detachCallback_ = callback;
1772     if (!isAttach_ && detachCallback_ != nullptr) {
1773         TLOGI(WmsLogTag::WMS_LIFE, "Session detach before register, persistentId:%{public}d", GetPersistentId());
1774         detachCallback_->OnPatternDetach(GetPersistentId());
1775         detachCallback_ = nullptr;
1776     }
1777 }
1778 
SetChangeSessionVisibilityWithStatusBarEventListener(NotifyChangeSessionVisibilityWithStatusBarFunc && func)1779 void Session::SetChangeSessionVisibilityWithStatusBarEventListener(
1780     NotifyChangeSessionVisibilityWithStatusBarFunc&& func)
1781 {
1782     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1783         auto session = weakThis.promote();
1784         if (!session || !func) {
1785             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
1786             return;
1787         }
1788         session->changeSessionVisibilityWithStatusBarFunc_ = std::move(func);
1789     }, __func__);
1790 }
1791 
SetPendingSessionActivationEventListener(NotifyPendingSessionActivationFunc && func)1792 void Session::SetPendingSessionActivationEventListener(NotifyPendingSessionActivationFunc&& func)
1793 {
1794     const char* const where = __func__;
1795     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1796         auto session = weakThis.promote();
1797         if (!session) {
1798             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
1799             return;
1800         }
1801         session->pendingSessionActivationFunc_ = std::move(func);
1802     }, where);
1803 }
1804 
SetBatchPendingSessionsActivationEventListener(NotifyBatchPendingSessionsActivationFunc && func)1805 void Session::SetBatchPendingSessionsActivationEventListener(NotifyBatchPendingSessionsActivationFunc&& func)
1806 {
1807     const char* const where = __func__;
1808     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1809         auto session = weakThis.promote();
1810         if (!session) {
1811             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
1812             return;
1813         }
1814         session->batchPendingSessionsActivationFunc_ = std::move(func);
1815     }, where);
1816 }
1817 
SetBackPressedListenser(NotifyBackPressedFunc && func)1818 void Session::SetBackPressedListenser(NotifyBackPressedFunc&& func)
1819 {
1820     const char* const where = __func__;
1821     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1822         auto session = weakThis.promote();
1823         if (!session) {
1824             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
1825             return;
1826         }
1827         session->backPressedFunc_ = std::move(func);
1828     }, where);
1829 }
1830 
SetTerminateSessionListener(NotifyTerminateSessionFunc && func)1831 void Session::SetTerminateSessionListener(NotifyTerminateSessionFunc&& func)
1832 {
1833     const char* const where = __func__;
1834     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1835         auto session = weakThis.promote();
1836         if (!session) {
1837             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
1838             return;
1839         }
1840         session->terminateSessionFunc_ = std::move(func);
1841     }, where);
1842 }
1843 
RemoveLifeCycleTask(const LifeCycleTaskType & taskType)1844 void Session::RemoveLifeCycleTask(const LifeCycleTaskType& taskType)
1845 {
1846     sptr<SessionLifeCycleTask> frontLifeCycleTask = nullptr;
1847     {
1848         std::lock_guard<std::mutex> lock(lifeCycleTaskQueueMutex_);
1849         if (lifeCycleTaskQueue_.empty()) {
1850             return;
1851         }
1852         sptr<SessionLifeCycleTask> currLifeCycleTask = lifeCycleTaskQueue_.front();
1853         if (currLifeCycleTask->type != taskType) {
1854             TLOGW(WmsLogTag::WMS_LIFE,
1855                 "not match, current running taskName=%{public}s, PersistentId=%{public}d",
1856                 currLifeCycleTask->name.c_str(), persistentId_);
1857             return;
1858         }
1859         TLOGI(WmsLogTag::WMS_LIFE, "Removed lifeCyleTask %{public}s. PersistentId=%{public}d",
1860             currLifeCycleTask->name.c_str(), persistentId_);
1861         lifeCycleTaskQueue_.pop_front();
1862         if (lifeCycleTaskQueue_.empty()) {
1863             return;
1864         }
1865         frontLifeCycleTask = lifeCycleTaskQueue_.front();
1866         if (!SetLifeCycleTaskRunning(frontLifeCycleTask)) {
1867             return;
1868         }
1869     }
1870     PostTask(std::move(frontLifeCycleTask->task), frontLifeCycleTask->name);
1871 }
1872 
PostLifeCycleTask(Task && task,const std::string & name,const LifeCycleTaskType & taskType)1873 void Session::PostLifeCycleTask(Task&& task, const std::string& name, const LifeCycleTaskType& taskType)
1874 {
1875     sptr<SessionLifeCycleTask> frontLifeCycleTask = nullptr;
1876     {
1877         std::lock_guard<std::mutex> lock(lifeCycleTaskQueueMutex_);
1878         if (!lifeCycleTaskQueue_.empty()) {
1879         // remove current running task if expired
1880             sptr<SessionLifeCycleTask> currLifeCycleTask = lifeCycleTaskQueue_.front();
1881             std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();
1882             bool isCurrentTaskExpired =
1883                 std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - currLifeCycleTask->startTime)
1884                     .count() > LIFE_CYCLE_TASK_EXPIRED_TIME_LIMIT;
1885             if (isCurrentTaskExpired) {
1886                 TLOGE(WmsLogTag::WMS_LIFE, "Remove expired LifeCycleTask %{public}s. PersistentId=%{public}d",
1887                     currLifeCycleTask->name.c_str(), persistentId_);
1888                 lifeCycleTaskQueue_.pop_front();
1889             }
1890         }
1891 
1892         if (lifeCycleTaskQueue_.size() == MAX_LIFE_CYCLE_TASK_IN_QUEUE) {
1893             TLOGE(WmsLogTag::WMS_LIFE, "Failed to add task %{public}s to life cycle queue", name.c_str());
1894             return;
1895         }
1896         sptr<SessionLifeCycleTask> lifeCycleTask =
1897             sptr<SessionLifeCycleTask>::MakeSptr(std::move(task), name, taskType);
1898         lifeCycleTaskQueue_.push_back(lifeCycleTask);
1899         TLOGI(WmsLogTag::WMS_LIFE, "Add task %{public}s to life cycle queue, PersistentId=%{public}d",
1900             name.c_str(), persistentId_);
1901         frontLifeCycleTask = lifeCycleTaskQueue_.front();
1902         if (!SetLifeCycleTaskRunning(frontLifeCycleTask)) {
1903             return;
1904         }
1905     }
1906     PostTask(std::move(frontLifeCycleTask->task), frontLifeCycleTask->name);
1907 }
1908 
SetLifeCycleTaskRunning(const sptr<SessionLifeCycleTask> & lifeCycleTask)1909 bool Session::SetLifeCycleTaskRunning(const sptr<SessionLifeCycleTask>& lifeCycleTask)
1910 {
1911     if (lifeCycleTask == nullptr || lifeCycleTask->running) {
1912         TLOGW(WmsLogTag::WMS_LIFE, "LifeCycleTask is running or null. PersistentId: %{public}d", persistentId_);
1913         return false;
1914     }
1915     TLOGI(WmsLogTag::WMS_LIFE, "Execute LifeCycleTask %{public}s. PersistentId: %{public}d",
1916         lifeCycleTask->name.c_str(), persistentId_);
1917     lifeCycleTask->running = true;
1918     lifeCycleTask->startTime = std::chrono::steady_clock::now();
1919     return true;
1920 }
1921 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool needStartCaller,bool isFromBroker)1922 WSError Session::TerminateSessionNew(
1923     const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needStartCaller, bool isFromBroker)
1924 {
1925     if (abilitySessionInfo == nullptr) {
1926         TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
1927         return WSError::WS_ERROR_INVALID_SESSION;
1928     }
1929     auto task = [weakThis = wptr(this), abilitySessionInfo, needStartCaller, isFromBroker]() {
1930         auto session = weakThis.promote();
1931         if (session == nullptr) {
1932             TLOGNI(WmsLogTag::WMS_LIFE, "session is null.");
1933             return;
1934         }
1935         session->isTerminating_ = true;
1936         SessionInfo info;
1937         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1938         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1939         info.callerToken_ = abilitySessionInfo->callerToken;
1940         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
1941         {
1942             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
1943             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1944             session->sessionInfo_.resultCode = abilitySessionInfo->resultCode;
1945         }
1946         if (session->terminateSessionFuncNew_) {
1947             session->terminateSessionFuncNew_(info, needStartCaller, isFromBroker, false);
1948         }
1949         TLOGNI(WmsLogTag::WMS_LIFE,
1950             "TerminateSessionNew, id: %{public}d, needStartCaller: %{public}d, isFromBroker: %{public}d",
1951             session->GetPersistentId(), needStartCaller, isFromBroker);
1952     };
1953     PostLifeCycleTask(task, "TerminateSessionNew", LifeCycleTaskType::STOP);
1954     return WSError::WS_OK;
1955 }
1956 
SetTerminateSessionListenerNew(NotifyTerminateSessionFuncNew && func)1957 void Session::SetTerminateSessionListenerNew(NotifyTerminateSessionFuncNew&& func)
1958 {
1959     const char* const where = __func__;
1960     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1961         auto session = weakThis.promote();
1962         if (!session) {
1963             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
1964             return;
1965         }
1966         session->terminateSessionFuncNew_ = std::move(func);
1967     }, where);
1968 }
1969 
TerminateSessionTotal(const sptr<AAFwk::SessionInfo> abilitySessionInfo,TerminateType terminateType)1970 WSError Session::TerminateSessionTotal(const sptr<AAFwk::SessionInfo> abilitySessionInfo, TerminateType terminateType)
1971 {
1972     if (abilitySessionInfo == nullptr) {
1973         TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
1974         return WSError::WS_ERROR_INVALID_SESSION;
1975     }
1976     if (isTerminating_) {
1977         TLOGE(WmsLogTag::WMS_LIFE, "is terminating, return!");
1978         return WSError::WS_ERROR_INVALID_OPERATION;
1979     }
1980     isTerminating_ = true;
1981     SessionInfo info;
1982     info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1983     info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1984     info.callerToken_ = abilitySessionInfo->callerToken;
1985     info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
1986     {
1987         std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
1988         sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1989         sessionInfo_.resultCode = abilitySessionInfo->resultCode;
1990     }
1991     if (terminateSessionFuncTotal_) {
1992         terminateSessionFuncTotal_(info, terminateType);
1993     }
1994     return WSError::WS_OK;
1995 }
1996 
SetTerminateSessionListenerTotal(NotifyTerminateSessionFuncTotal && func)1997 void Session::SetTerminateSessionListenerTotal(NotifyTerminateSessionFuncTotal&& func)
1998 {
1999     const char* const where = __func__;
2000     PostTask([weakThis = wptr(this), func = std::move(func), where] {
2001         auto session = weakThis.promote();
2002         if (!session) {
2003             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
2004             return;
2005         }
2006         session->terminateSessionFuncTotal_ = std::move(func);
2007     }, where);
2008 }
2009 
SetSessionLabel(const std::string & label)2010 WSError Session::SetSessionLabel(const std::string& label)
2011 {
2012     WLOGFI("run Session::SetSessionLabel");
2013     if (updateSessionLabelFunc_) {
2014         updateSessionLabelFunc_(label);
2015     }
2016     return WSError::WS_OK;
2017 }
2018 
SetUpdateSessionLabelListener(const NofitySessionLabelUpdatedFunc & func)2019 void Session::SetUpdateSessionLabelListener(const NofitySessionLabelUpdatedFunc& func)
2020 {
2021     updateSessionLabelFunc_ = func;
2022 }
2023 
SetSessionIcon(const std::shared_ptr<Media::PixelMap> & icon)2024 WSError Session::SetSessionIcon(const std::shared_ptr<Media::PixelMap>& icon)
2025 {
2026     WLOGFD("run Session::SetSessionIcon, id: %{public}d", GetPersistentId());
2027     if (scenePersistence_ == nullptr) {
2028         WLOGFE("scenePersistence_ is nullptr.");
2029         return WSError::WS_ERROR_INVALID_OPERATION;
2030     }
2031     scenePersistence_->SaveUpdatedIcon(icon);
2032     std::string updatedIconPath = scenePersistence_->GetUpdatedIconPath();
2033     if (updateSessionIconFunc_) {
2034         updateSessionIconFunc_(updatedIconPath);
2035     }
2036     return WSError::WS_OK;
2037 }
2038 
SetUpdateSessionIconListener(const NofitySessionIconUpdatedFunc & func)2039 void Session::SetUpdateSessionIconListener(const NofitySessionIconUpdatedFunc& func)
2040 {
2041     updateSessionIconFunc_ = func;
2042 }
2043 
Clear(bool needStartCaller,bool isForceClean)2044 WSError Session::Clear(bool needStartCaller, bool isForceClean)
2045 {
2046     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, needStartCaller:%{public}u, isForceClean:%{public}u",
2047         GetPersistentId(), needStartCaller, isForceClean);
2048     auto task = [weakThis = wptr(this), needStartCaller, isForceClean]() {
2049         auto session = weakThis.promote();
2050         if (session == nullptr) {
2051             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
2052             return;
2053         }
2054         session->isTerminating_ = true;
2055         if (session->terminateSessionFuncNew_) {
2056             session->terminateSessionFuncNew_(session->GetSessionInfo(), needStartCaller, false, isForceClean);
2057         }
2058     };
2059     PostLifeCycleTask(task, "Clear", LifeCycleTaskType::STOP);
2060     return WSError::WS_OK;
2061 }
2062 
SetSessionExceptionListener(NotifySessionExceptionFunc && func,bool fromJsScene)2063 void Session::SetSessionExceptionListener(NotifySessionExceptionFunc&& func, bool fromJsScene)
2064 {
2065     PostTask([weakThis = wptr(this), where = __func__, func = std::move(func), fromJsScene] {
2066         auto session = weakThis.promote();
2067         if (!session) {
2068             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
2069             return;
2070         }
2071         if (fromJsScene) {
2072             session->jsSceneSessionExceptionFunc_ = std::move(func);
2073         } else {
2074             session->sessionExceptionFunc_ = std::move(func);
2075         }
2076     }, __func__);
2077 }
2078 
SetSessionSnapshotListener(const NotifySessionSnapshotFunc & func)2079 void Session::SetSessionSnapshotListener(const NotifySessionSnapshotFunc& func)
2080 {
2081     if (func == nullptr) {
2082         WLOGFE("func is nullptr");
2083         return;
2084     }
2085     notifySessionSnapshotFunc_ = func;
2086 }
2087 
SetPendingSessionToForegroundListener(NotifyPendingSessionToForegroundFunc && func)2088 void Session::SetPendingSessionToForegroundListener(NotifyPendingSessionToForegroundFunc&& func)
2089 {
2090     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
2091         auto session = weakThis.promote();
2092         if (!session) {
2093             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
2094             return;
2095         }
2096         session->pendingSessionToForegroundFunc_ = std::move(func);
2097     }, __func__);
2098 }
2099 
PendingSessionToForeground()2100 WSError Session::PendingSessionToForeground()
2101 {
2102     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
2103     if (pendingSessionActivationFunc_) {
2104         SessionInfo info = GetSessionInfo();
2105         pendingSessionActivationFunc_(info);
2106     }
2107     return WSError::WS_OK;
2108 }
2109 
SetPendingSessionToBackgroundListener(NotifyPendingSessionToBackgroundFunc && func)2110 void Session::SetPendingSessionToBackgroundListener(NotifyPendingSessionToBackgroundFunc&& func)
2111 {
2112     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
2113         auto session = weakThis.promote();
2114         if (!session) {
2115             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
2116             return;
2117         }
2118         session->pendingSessionToBackgroundFunc_ = std::move(func);
2119     }, __func__);
2120 }
2121 
PendingSessionToBackground(const BackgroundParams & params)2122 WSError Session::PendingSessionToBackground(const BackgroundParams& params)
2123 {
2124     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d, shouldBackToCaller: %{public}d",
2125         GetPersistentId(), params.shouldBackToCaller);
2126     if (pendingSessionToBackgroundFunc_) {
2127         pendingSessionToBackgroundFunc_(GetSessionInfo(), params);
2128     }
2129     return WSError::WS_OK;
2130 }
2131 
SetPendingSessionToBackgroundForDelegatorListener(NotifyPendingSessionToBackgroundForDelegatorFunc && func)2132 void Session::SetPendingSessionToBackgroundForDelegatorListener(
2133     NotifyPendingSessionToBackgroundForDelegatorFunc&& func)
2134 {
2135     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
2136         auto session = weakThis.promote();
2137         if (!session) {
2138             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
2139             return;
2140         }
2141         session->pendingSessionToBackgroundForDelegatorFunc_ = std::move(func);
2142     }, __func__);
2143 }
2144 
PendingSessionToBackgroundForDelegator(bool shouldBackToCaller)2145 WSError Session::PendingSessionToBackgroundForDelegator(bool shouldBackToCaller)
2146 {
2147     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d, shouldBackToCaller: %{public}d",
2148         GetPersistentId(), shouldBackToCaller);
2149     if (pendingSessionToBackgroundForDelegatorFunc_) {
2150         pendingSessionToBackgroundForDelegatorFunc_(GetSessionInfo(), shouldBackToCaller);
2151     }
2152     return WSError::WS_OK;
2153 }
2154 
SetRaiseToAppTopForPointDownFunc(const NotifyRaiseToTopForPointDownFunc & func)2155 void Session::SetRaiseToAppTopForPointDownFunc(const NotifyRaiseToTopForPointDownFunc& func)
2156 {
2157     raiseToTopForPointDownFunc_ = func;
2158 }
2159 
NotifyScreenshot()2160 void Session::NotifyScreenshot()
2161 {
2162     if (!sessionStage_) {
2163         return;
2164     }
2165     sessionStage_->NotifyScreenshot();
2166 }
2167 
NotifyScreenshotAppEvent(ScreenshotEventType type)2168 WSError Session::NotifyScreenshotAppEvent(ScreenshotEventType type)
2169 {
2170     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, event: %{public}d", GetPersistentId(), type);
2171     if (!sessionStage_) {
2172         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionStage is null");
2173         return WSError::WS_ERROR_NULLPTR;
2174     }
2175     return sessionStage_->NotifyScreenshotAppEvent(type);
2176 }
2177 
NotifyCloseExistPipWindow()2178 WSError Session::NotifyCloseExistPipWindow()
2179 {
2180     if (!sessionStage_) {
2181         return WSError::WS_ERROR_NULLPTR;
2182     }
2183     return sessionStage_->NotifyCloseExistPipWindow();
2184 }
2185 
NotifyDestroy()2186 WSError Session::NotifyDestroy()
2187 {
2188     if (!sessionStage_) {
2189         return WSError::WS_ERROR_NULLPTR;
2190     }
2191     return sessionStage_->NotifyDestroy();
2192 }
2193 
NotifyAppForceLandscapeConfigUpdated()2194 WSError Session::NotifyAppForceLandscapeConfigUpdated()
2195 {
2196     if (!sessionStage_) {
2197         return WSError::WS_ERROR_NULLPTR;
2198     }
2199     return sessionStage_->NotifyAppForceLandscapeConfigUpdated();
2200 }
2201 
NotifyAppHookWindowInfoUpdated()2202 WSError Session::NotifyAppHookWindowInfoUpdated()
2203 {
2204     if (!sessionStage_) {
2205         return WSError::WS_ERROR_NULLPTR;
2206     }
2207     return sessionStage_->NotifyAppHookWindowInfoUpdated();
2208 }
2209 
SetParentSession(const sptr<Session> & session)2210 void Session::SetParentSession(const sptr<Session>& session)
2211 {
2212     if (session == nullptr) {
2213         WLOGFW("Session is nullptr");
2214         return;
2215     }
2216     {
2217         std::unique_lock<std::shared_mutex> lock(parentSessionMutex_);
2218         parentSession_ = session;
2219     }
2220     TLOGD(WmsLogTag::WMS_SUB, "[WMSDialog][WMSSub]Set parent success, parentId: %{public}d, id: %{public}d",
2221         session->GetPersistentId(), GetPersistentId());
2222 }
2223 
GetParentSession() const2224 sptr<Session> Session::GetParentSession() const
2225 {
2226     std::shared_lock<std::shared_mutex> lock(parentSessionMutex_);
2227     return parentSession_;
2228 }
2229 
GetMainSession() const2230 sptr<Session> Session::GetMainSession() const
2231 {
2232     if (SessionHelper::IsMainWindow(GetWindowType())) {
2233         return const_cast<Session*>(this);
2234     } else if (parentSession_) {
2235         return parentSession_->GetMainSession();
2236     } else {
2237         return nullptr;
2238     }
2239 }
2240 
GetMainOrFloatSession() const2241 sptr<Session> Session::GetMainOrFloatSession() const
2242 {
2243     auto windowType = GetWindowType();
2244     if (SessionHelper::IsMainWindow(windowType) || windowType == WindowType::WINDOW_TYPE_FLOAT) {
2245         return const_cast<Session*>(this);
2246     } else if (parentSession_) {
2247         return parentSession_->GetMainOrFloatSession();
2248     } else {
2249         return nullptr;
2250     }
2251 }
2252 
IsAncestorsSession(int32_t ancestorsId) const2253 bool Session::IsAncestorsSession(int32_t ancestorsId) const
2254 {
2255     if (GetSessionProperty()->GetParentPersistentId() == ancestorsId) {
2256         return true;
2257     }
2258     auto parentSession = GetParentSession();
2259     if (parentSession != nullptr) {
2260         return parentSession->IsAncestorsSession(ancestorsId);
2261     }
2262     return false;
2263 }
2264 
BindDialogToParentSession(const sptr<Session> & session)2265 void Session::BindDialogToParentSession(const sptr<Session>& session)
2266 {
2267     std::unique_lock<std::shared_mutex> lock(dialogVecMutex_);
2268     auto iter = std::find(dialogVec_.begin(), dialogVec_.end(), session);
2269     if (iter != dialogVec_.end()) {
2270         TLOGW(WmsLogTag::WMS_DIALOG, "Dialog is existed in parentVec, id: %{public}d, parentId: %{public}d",
2271             session->GetPersistentId(), GetPersistentId());
2272         return;
2273     }
2274     dialogVec_.push_back(session);
2275     TLOGD(WmsLogTag::WMS_DIALOG, "Bind dialog success, id: %{public}d, parentId: %{public}d",
2276         session->GetPersistentId(), GetPersistentId());
2277 }
2278 
RemoveDialogToParentSession(const sptr<Session> & session)2279 void Session::RemoveDialogToParentSession(const sptr<Session>& session)
2280 {
2281     std::unique_lock<std::shared_mutex> lock(dialogVecMutex_);
2282     auto iter = std::find(dialogVec_.begin(), dialogVec_.end(), session);
2283     if (iter != dialogVec_.end()) {
2284         TLOGD(WmsLogTag::WMS_DIALOG, "Remove dialog success, id: %{public}d, parentId: %{public}d",
2285             session->GetPersistentId(), GetPersistentId());
2286         dialogVec_.erase(iter);
2287     }
2288     TLOGW(WmsLogTag::WMS_DIALOG, "Remove dialog failed, id: %{public}d, parentId: %{public}d",
2289         session->GetPersistentId(), GetPersistentId());
2290 }
2291 
GetDialogVector() const2292 std::vector<sptr<Session>> Session::GetDialogVector() const
2293 {
2294     std::shared_lock<std::shared_mutex> lock(dialogVecMutex_);
2295     return dialogVec_;
2296 }
2297 
ClearDialogVector()2298 void Session::ClearDialogVector()
2299 {
2300     std::unique_lock<std::shared_mutex> lock(dialogVecMutex_);
2301     dialogVec_.clear();
2302     TLOGD(WmsLogTag::WMS_DIALOG, "parentId: %{public}d", GetPersistentId());
2303     return;
2304 }
2305 
CheckDialogOnForeground()2306 bool Session::CheckDialogOnForeground()
2307 {
2308     auto dialogVec = GetDialogVector();
2309     if (dialogVec.empty()) {
2310         TLOGD(WmsLogTag::WMS_DIALOG, "Dialog is empty, id: %{public}d", GetPersistentId());
2311         return false;
2312     }
2313     for (auto iter = dialogVec.rbegin(); iter != dialogVec.rend(); iter++) {
2314         auto dialogSession = *iter;
2315         if (dialogSession && (dialogSession->GetSessionState() == SessionState::STATE_ACTIVE ||
2316             dialogSession->GetSessionState() == SessionState::STATE_FOREGROUND)) {
2317             TLOGD(WmsLogTag::WMS_DIALOG, "Notify touch dialog window, id: %{public}d", GetPersistentId());
2318             return true;
2319         }
2320     }
2321     return false;
2322 }
2323 
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const2324 bool Session::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
2325 {
2326     return true;
2327 }
2328 
IsTopDialog() const2329 bool Session::IsTopDialog() const
2330 {
2331     int32_t currentPersistentId = GetPersistentId();
2332     auto parentSession = GetParentSession();
2333     if (parentSession == nullptr) {
2334         TLOGW(WmsLogTag::WMS_DIALOG, "Dialog's Parent is NULL. id: %{public}d", currentPersistentId);
2335         return false;
2336     }
2337     auto parentDialogVec = parentSession->GetDialogVector();
2338     if (parentDialogVec.size() <= 1) {
2339         return true;
2340     }
2341     for (auto iter = parentDialogVec.rbegin(); iter != parentDialogVec.rend(); iter++) {
2342         auto dialogSession = *iter;
2343         if (dialogSession && (dialogSession->GetSessionState() == SessionState::STATE_ACTIVE ||
2344             dialogSession->GetSessionState() == SessionState::STATE_FOREGROUND)) {
2345             WLOGFI("Dialog id: %{public}d, current dialog id: %{public}d", dialogSession->GetPersistentId(),
2346                 currentPersistentId);
2347             return dialogSession->GetPersistentId() == currentPersistentId;
2348         }
2349     }
2350     return false;
2351 }
2352 
DumpPointerWindowArea(MMI::WindowArea area) const2353 const char* Session::DumpPointerWindowArea(MMI::WindowArea area) const
2354 {
2355     const std::map<MMI::WindowArea, const char*> areaMap = {
2356         { MMI::WindowArea::FOCUS_ON_INNER, "FOCUS_ON_INNER" },
2357         { MMI::WindowArea::FOCUS_ON_TOP, "FOCUS_ON_TOP" },
2358         { MMI::WindowArea::FOCUS_ON_BOTTOM, "FOCUS_ON_BOTTOM" },
2359         { MMI::WindowArea::FOCUS_ON_LEFT, "FOCUS_ON_LEFT" },
2360         { MMI::WindowArea::FOCUS_ON_RIGHT, "FOCUS_ON_RIGHT" },
2361         { MMI::WindowArea::FOCUS_ON_BOTTOM_LEFT, "FOCUS_ON_BOTTOM_LEFT" },
2362         { MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT, "FOCUS_ON_BOTTOM_RIGHT" },
2363         { MMI::WindowArea::FOCUS_ON_TOP_LEFT, "FOCUS_ON_TOP_LEFT" },
2364         { MMI::WindowArea::FOCUS_ON_TOP_RIGHT, "FOCUS_ON_TOP_RIGHT" },
2365         { MMI::WindowArea::EXIT, "EXIT" }
2366     };
2367     auto iter = areaMap.find(area);
2368     if (iter == areaMap.end()) {
2369         return "UNKNOWN";
2370     }
2371     return iter->second;
2372 }
2373 
RaiseToAppTopForPointDown()2374 WSError Session::RaiseToAppTopForPointDown()
2375 {
2376     if (raiseToTopForPointDownFunc_) {
2377         raiseToTopForPointDownFunc_();
2378         WLOGFD("RaiseToAppTopForPointDown, id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
2379     }
2380     return WSError::WS_OK;
2381 }
2382 
PresentFocusIfPointDown()2383 void Session::PresentFocusIfPointDown()
2384 {
2385     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d,type: %{public}d", GetPersistentId(), GetWindowType());
2386     if (!isFocused_ && GetFocusable()) {
2387         FocusChangeReason reason = FocusChangeReason::CLICK;
2388         NotifyRequestFocusStatusNotifyManager(true, false, reason);
2389     }
2390     NotifyClick();
2391 }
2392 
HandlePointDownDialog()2393 void Session::HandlePointDownDialog()
2394 {
2395     auto dialogVec = GetDialogVector();
2396     sptr<Session> lastValidDialog = nullptr;
2397     for (auto dialog : dialogVec) {
2398         if (dialog && (dialog->GetSessionState() == SessionState::STATE_FOREGROUND ||
2399             dialog->GetSessionState() == SessionState::STATE_ACTIVE)) {
2400             dialog->RaiseToAppTopForPointDown();
2401             lastValidDialog = dialog;
2402             TLOGD(WmsLogTag::WMS_DIALOG, "Point main window, raise to top and dialog need focus, "
2403                 "id: %{public}d, dialogId: %{public}d", GetPersistentId(), dialog->GetPersistentId());
2404         }
2405     }
2406     if (lastValidDialog != nullptr) {
2407         lastValidDialog->PresentFocusIfPointDown();
2408     }
2409 }
2410 
HandleSubWindowClick(int32_t action,int32_t sourceType,bool isExecuteDelayRaise)2411 WSError Session::HandleSubWindowClick(int32_t action, int32_t sourceType, bool isExecuteDelayRaise)
2412 {
2413     auto parentSession = GetParentSession();
2414     if (parentSession && parentSession->CheckDialogOnForeground()) {
2415         TLOGD(WmsLogTag::WMS_DIALOG, "Its main window has dialog on foreground, id: %{public}d", GetPersistentId());
2416         return WSError::WS_ERROR_INVALID_PERMISSION;
2417     }
2418     const auto& property = GetSessionProperty();
2419     bool raiseEnabled = property->GetRaiseEnabled();
2420     bool isHoverDown = action == MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER &&
2421         sourceType ==  MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
2422     bool isPointDown = action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
2423         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN || isHoverDown;
2424     bool isPointMove = action == MMI::PointerEvent::POINTER_ACTION_MOVE;
2425     if (isExecuteDelayRaise) {
2426         if (raiseEnabled && action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) {
2427             RaiseToAppTopForPointDown();
2428         }
2429         if (!raiseEnabled && parentSession && !isPointMove) {
2430             parentSession->NotifyClick(!IsScbCoreEnabled());
2431         }
2432         return WSError::WS_OK;
2433     }
2434     bool isModal = WindowHelper::IsModalWindow(property->GetWindowFlags());
2435     TLOGD(WmsLogTag::WMS_EVENT,
2436           "id: %{public}d, raiseEnabled: %{public}d, isPointDown: %{public}d, isModal: %{public}d",
2437           GetPersistentId(), raiseEnabled, isPointDown, isPointDown);
2438     if (raiseEnabled && isPointDown && !isModal) {
2439         RaiseToAppTopForPointDown();
2440     } else if (parentSession && !isPointMove) {
2441         // sub window is forbidden to raise to top after click, but its parent should raise
2442         parentSession->NotifyClick(!IsScbCoreEnabled());
2443     }
2444     return WSError::WS_OK;
2445 }
2446 
HandlePointerEventForFocus(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool isExecuteDelayRaise)2447 WSError Session::HandlePointerEventForFocus(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2448     bool isExecuteDelayRaise)
2449 {
2450     if (pointerEvent == nullptr) {
2451         TLOGE(WmsLogTag::WMS_EVENT, "PointerEvent is nullptr");
2452         return WSError::WS_ERROR_NULLPTR;
2453     }
2454     TLOGD(WmsLogTag::WMS_EVENT, "eventId:%{public}d, action:%{public}s, persistentId:%{public}d ",
2455         pointerEvent->GetId(), pointerEvent->DumpPointerAction(), persistentId_);
2456     auto pointerAction = pointerEvent->GetPointerAction();
2457     auto sourceType = pointerEvent->GetSourceType();
2458     bool isHoverDown = pointerAction == MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER &&
2459         sourceType ==  MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
2460     bool isPointDown = (pointerAction == MMI::PointerEvent::POINTER_ACTION_DOWN) ||
2461         (pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) || isHoverDown;
2462     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2463         if (CheckDialogOnForeground() && isPointDown) {
2464             HandlePointDownDialog();
2465             return WSError::WS_ERROR_INVALID_PERMISSION;
2466         }
2467     } else if (GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
2468         WSError ret = HandleSubWindowClick(pointerAction, sourceType, isExecuteDelayRaise);
2469         if (ret != WSError::WS_OK) {
2470             return ret;
2471         }
2472     } else if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
2473         auto parentSession = GetParentSession();
2474         if (parentSession && parentSession->CheckDialogOnForeground() && isPointDown) {
2475             parentSession->HandlePointDownDialog();
2476             if (!IsTopDialog()) {
2477                 TLOGI(WmsLogTag::WMS_DIALOG, "There is at least one active dialog upon this dialog, id: %{public}d",
2478                     GetPersistentId());
2479                 return WSError::WS_ERROR_INVALID_PERMISSION;
2480             }
2481         }
2482     }
2483     if (!isExecuteDelayRaise) {
2484         PresentFocusIfNeed(pointerAction, sourceType);
2485     } else if (pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) {
2486         if (!isFocused_ && GetFocusable()) {
2487             NotifyRequestFocusStatusNotifyManager(true, false, FocusChangeReason::CLICK);
2488         }
2489         NotifyClick();
2490     }
2491     return WSError::WS_OK;
2492 }
2493 
HasParentSessionWithToken(const sptr<IRemoteObject> & token)2494 bool Session::HasParentSessionWithToken(const sptr<IRemoteObject>& token)
2495 {
2496     auto parentSession = GetParentSession();
2497     if (parentSession == nullptr) {
2498         TLOGD(WmsLogTag::WMS_FOCUS, "parent session is nullptr: %{public}d", GetPersistentId());
2499         return false;
2500     }
2501     if (parentSession->GetAbilityToken() == token) {
2502         return true;
2503     }
2504     return parentSession->HasParentSessionWithToken(token);
2505 }
2506 
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient,bool isExecuteDelayRaise)2507 WSError Session::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2508     bool needNotifyClient, bool isExecuteDelayRaise)
2509 {
2510     TLOGD(WmsLogTag::WMS_EVENT, "id: %{public}d", GetPersistentId());
2511     if (!IsSystemSession() && !IsSessionValid()) {
2512         return WSError::WS_ERROR_INVALID_SESSION;
2513     }
2514     if (pointerEvent == nullptr) {
2515         TLOGE(WmsLogTag::WMS_EVENT, "PointerEvent is nullptr");
2516         return WSError::WS_ERROR_NULLPTR;
2517     }
2518     WSError focusRet = HandlePointerEventForFocus(pointerEvent, isExecuteDelayRaise);
2519     if (focusRet != WSError::WS_OK) {
2520         return focusRet;
2521     }
2522     if (!windowEventChannel_) {
2523         if (!IsSystemSession()) {
2524             TLOGE(WmsLogTag::WMS_EVENT, "windowEventChannel_ is null");
2525         }
2526         return WSError::WS_ERROR_NULLPTR;
2527     }
2528 
2529     if (needNotifyClient) {
2530         WSError ret = windowEventChannel_->TransferPointerEvent(pointerEvent);
2531         if (ret != WSError::WS_OK) {
2532             WLOGFE("InputTracking id:%{public}d, TransferPointer failed, ret:%{public}d ",
2533                 pointerEvent->GetId(), ret);
2534         }
2535         return ret;
2536     } else {
2537         pointerEvent->MarkProcessed();
2538     }
2539     auto pointerAction = pointerEvent->GetPointerAction();
2540     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_MOVE ||
2541         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) {
2542         TLOGD(WmsLogTag::WMS_EVENT, "eventId:%{public}d, action:%{public}s, persistentId:%{public}d, "
2543             "bundleName:%{public}s, pid:%{public}d", pointerEvent->GetId(), pointerEvent->DumpPointerAction(),
2544             persistentId_, callingBundleName_.c_str(), callingPid_);
2545     } else {
2546         TLOGD(WmsLogTag::WMS_EVENT, "eventId:%{public}d, action:%{public}s, "
2547             "persistentId:%{public}d, bundleName:%{public}s, pid:%{public}d",
2548             pointerEvent->GetId(), pointerEvent->DumpPointerAction(),
2549             persistentId_, callingBundleName_.c_str(), callingPid_);
2550     }
2551     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW ||
2552         pointerAction == MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW ||
2553         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
2554         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
2555         TLOGD(WmsLogTag::WMS_EVENT, "Action:%{public}s, eventId:%{public}d, report without timer",
2556             pointerEvent->DumpPointerAction(), pointerEvent->GetId());
2557     }
2558     return WSError::WS_OK;
2559 }
2560 
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)2561 WSError Session::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
2562 {
2563     WLOGFD("Session TransferKeyEvent eventId:%{public}d persistentId:%{public}d bundleName:%{public}s pid:%{public}d",
2564         keyEvent->GetId(), persistentId_, callingBundleName_.c_str(), callingPid_);
2565     if (!windowEventChannel_) {
2566         WLOGFE("windowEventChannel_ is null");
2567         return WSError::WS_ERROR_NULLPTR;
2568     }
2569     WLOGD("TransferKeyEvent, id: %{public}d", persistentId_);
2570     WSError ret = windowEventChannel_->TransferKeyEvent(keyEvent);
2571     if (ret != WSError::WS_OK) {
2572         WLOGFE("TransferKeyEvent failed, ret:%{public}d", ret);
2573         return ret;
2574     }
2575     return WSError::WS_OK;
2576 }
2577 
TransferBackPressedEventForConsumed(bool & isConsumed)2578 WSError Session::TransferBackPressedEventForConsumed(bool& isConsumed)
2579 {
2580     if (!windowEventChannel_) {
2581         WLOGFE("windowEventChannel_ is null");
2582         return WSError::WS_ERROR_NULLPTR;
2583     }
2584     return windowEventChannel_->TransferBackpressedEventForConsumed(isConsumed);
2585 }
2586 
TransferKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed,bool isPreImeEvent)2587 WSError Session::TransferKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed,
2588     bool isPreImeEvent)
2589 {
2590     if (!windowEventChannel_) {
2591         WLOGFE("windowEventChannel_ is null");
2592         return WSError::WS_ERROR_NULLPTR;
2593     }
2594     if (keyEvent == nullptr) {
2595         WLOGFE("KeyEvent is nullptr");
2596         return WSError::WS_ERROR_NULLPTR;
2597     }
2598     return windowEventChannel_->TransferKeyEventForConsumed(keyEvent, isConsumed, isPreImeEvent);
2599 }
2600 
TransferFocusActiveEvent(bool isFocusActive)2601 WSError Session::TransferFocusActiveEvent(bool isFocusActive)
2602 {
2603     if (!windowEventChannel_) {
2604         WLOGFE("windowEventChannel_ is null");
2605         return WSError::WS_ERROR_NULLPTR;
2606     }
2607     return windowEventChannel_->TransferFocusActiveEvent(isFocusActive);
2608 }
2609 
TransferFocusStateEvent(bool focusState)2610 WSError Session::TransferFocusStateEvent(bool focusState)
2611 {
2612     if (!windowEventChannel_) {
2613         if (!IsSystemSession()) {
2614             WLOGFW("windowEventChannel_ is null");
2615         }
2616         return WSError::WS_ERROR_NULLPTR;
2617     }
2618     return windowEventChannel_->TransferFocusState(focusState);
2619 }
2620 
Snapshot(bool runInFfrt,float scaleParam,bool useCurWindow) const2621 std::shared_ptr<Media::PixelMap> Session::Snapshot(bool runInFfrt, float scaleParam, bool useCurWindow) const
2622 {
2623     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Snapshot[%d][%s]", persistentId_, sessionInfo_.bundleName_.c_str());
2624     if (scenePersistence_ == nullptr) {
2625         return nullptr;
2626     }
2627     auto surfaceNode = GetSurfaceNode();
2628     auto key = GetSessionStatus();
2629     auto isPersistentImageFit = IsPersistentImageFit();
2630     if (isPersistentImageFit) key = defaultStatus;
2631     if (!surfaceNode || !surfaceNode->IsBufferAvailable()) {
2632         scenePersistence_->SetHasSnapshot(false, key);
2633         scenePersistence_->SetHasSnapshotFreeMultiWindow(false);
2634         return nullptr;
2635     }
2636     auto callback = std::make_shared<SurfaceCaptureFuture>();
2637     auto scaleValue = (scaleParam < 0.0f || std::fabs(scaleParam) < std::numeric_limits<float>::min()) ?
2638         snapshotScale_ : scaleParam;
2639     uint32_t backGroundColor = GetBackgroundColor();
2640     RSSurfaceCaptureConfig config = {
2641         .scaleX = scaleValue,
2642         .scaleY = scaleValue,
2643         .useDma = true,
2644         .useCurWindow = useCurWindow,
2645         .backGroundColor = backGroundColor,
2646     };
2647     bool ret = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode, callback, config);
2648     if (!ret) {
2649         TLOGE(WmsLogTag::WMS_MAIN, "TakeSurfaceCapture failed");
2650         return nullptr;
2651     }
2652     constexpr int32_t FFRT_SNAPSHOT_TIMEOUT_MS = 5000;
2653     auto pixelMap = callback->GetResult(runInFfrt ? FFRT_SNAPSHOT_TIMEOUT_MS : SNAPSHOT_TIMEOUT_MS);
2654     if (isPersistentImageFit && GetSnapshot()) {
2655         TLOGI(WmsLogTag::WMS_PATTERN, "id: %{public}d", persistentId_);
2656         pixelMap = GetSnapshot();
2657     }
2658     if (pixelMap != nullptr) {
2659         TLOGI(WmsLogTag::WMS_MAIN, "Save snapshot WxH=%{public}dx%{public}d, id: %{public}d, uniqueId: %{public}d",
2660             pixelMap->GetWidth(), pixelMap->GetHeight(), persistentId_, pixelMap->GetUniqueId());
2661         if (notifySessionSnapshotFunc_) {
2662             notifySessionSnapshotFunc_(persistentId_);
2663         }
2664         return pixelMap;
2665     }
2666     TLOGE(WmsLogTag::WMS_MAIN, "Save snapshot failed, id: %{public}d", persistentId_);
2667     return nullptr;
2668 }
2669 
GetBackgroundColor() const2670 uint32_t Session::GetBackgroundColor() const
2671 {
2672     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
2673     if (appContext != nullptr) {
2674         std::shared_ptr<AppExecFwk::Configuration> appConfig = appContext->GetConfiguration();
2675         if (appConfig != nullptr) {
2676             std::string colorMode = appConfig->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
2677             TLOGI(WmsLogTag::WMS_PATTERN, ":%{public}s", colorMode.c_str());
2678             return (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK) ? COLOR_BLACK : COLOR_WHITE;
2679         }
2680     } else {
2681         TLOGE(WmsLogTag::WMS_PATTERN, "app context is nullptr, use default backGroundColor WHITE");
2682     }
2683     return COLOR_WHITE;
2684 }
2685 
ResetSnapshot()2686 void Session::ResetSnapshot()
2687 {
2688     TLOGI(WmsLogTag::WMS_PATTERN, "id: %{public}d", persistentId_);
2689     std::lock_guard lock(snapshotMutex_);
2690     snapshot_ = nullptr;
2691     if (scenePersistence_ == nullptr) {
2692         TLOGI(WmsLogTag::WMS_PATTERN, "scenePersistence_ %{public}d nullptr", persistentId_);
2693         return;
2694     }
2695     scenePersistence_->ResetSnapshotCache();
2696 }
2697 
SetEnableAddSnapshot(bool enableAddSnapshot)2698 void Session::SetEnableAddSnapshot(bool enableAddSnapshot)
2699 {
2700     TLOGI(WmsLogTag::WMS_PATTERN, "enableAddSnapshot: %{public}d", enableAddSnapshot);
2701     enableAddSnapshot_ = enableAddSnapshot;
2702 }
2703 
GetEnableAddSnapshot() const2704 bool Session::GetEnableAddSnapshot() const
2705 {
2706     return enableAddSnapshot_;
2707 }
2708 
SaveSnapshot(bool useFfrt,bool needPersist,std::shared_ptr<Media::PixelMap> persistentPixelMap,bool updateSnapshot,ScreenLockReason reason)2709 void Session::SaveSnapshot(bool useFfrt, bool needPersist, std::shared_ptr<Media::PixelMap> persistentPixelMap,
2710     bool updateSnapshot, ScreenLockReason reason)
2711 {
2712     if (scenePersistence_ == nullptr) {
2713         return;
2714     }
2715     auto key = GetSessionStatus(reason);
2716     auto rotate = WSSnapshotHelper::GetDisplayOrientation(currentRotation_);
2717     if (persistentPixelMap) {
2718         key = defaultStatus;
2719         rotate = DisplayOrientation::PORTRAIT;
2720     }
2721     auto task = [weakThis = wptr(this), runInFfrt = useFfrt, requirePersist = needPersist, persistentPixelMap,
2722         updateSnapshot, key, rotate]() {
2723         auto session = weakThis.promote();
2724         if (session == nullptr) {
2725             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
2726             return;
2727         }
2728         session->lastLayoutRect_ = session->layoutRect_;
2729         auto pixelMap = persistentPixelMap ? persistentPixelMap : session->Snapshot(runInFfrt);
2730         if (pixelMap == nullptr) {
2731             return;
2732         }
2733         {
2734             std::lock_guard<std::mutex> lock(session->snapshotMutex_);
2735             session->snapshot_ = pixelMap;
2736         }
2737         {
2738             std::lock_guard<std::mutex> lock(session->addSnapshotCallbackMutex_);
2739             session->addSnapshotCallback_();
2740         }
2741         session->SetAddSnapshotCallback([]() {});
2742         {
2743             std::lock_guard<std::mutex> lock(session->saveSnapshotCallbackMutex_);
2744             session->saveSnapshotCallback_();
2745         }
2746         if (!requirePersist) {
2747             return;
2748         }
2749         if (!session->scenePersistence_) {
2750             TLOGNE(WmsLogTag::WMS_PATTERN, "scenePersistence_ is null");
2751             return;
2752         }
2753         if (session->freeMultiWindow_.load()) {
2754             session->scenePersistence_->SetHasSnapshotFreeMultiWindow(true);
2755             ScenePersistentStorage::Insert("Snapshot_" + std::to_string(session->persistentId_), true,
2756                 ScenePersistentStorageType::MAXIMIZE_STATE);
2757         } else {
2758             session->scenePersistence_->SetHasSnapshot(true, key);
2759             ScenePersistentStorage::Insert("Snapshot_" + std::to_string(session->persistentId_) +
2760                 "_" + std::to_string(key.first) + std::to_string(key.second), true,
2761                 ScenePersistentStorageType::MAXIMIZE_STATE);
2762         }
2763         session->scenePersistence_->ResetSnapshotCache();
2764         Task removeSnapshotCallback = []() {};
2765         {
2766             std::lock_guard lock(session->removeSnapshotCallbackMutex_);
2767             removeSnapshotCallback = session->removeSnapshotCallback_;
2768         }
2769         session->scenePersistence_->SaveSnapshot(pixelMap, removeSnapshotCallback, key, rotate,
2770             session->freeMultiWindow_.load());
2771         if (updateSnapshot) {
2772             session->SetExitSplitOnBackground(false);
2773             session->scenePersistence_->ClearSnapshot(key);
2774             session->NotifyUpdateSnapshotWindow();
2775         }
2776     };
2777     if (!useFfrt) {
2778         task();
2779         return;
2780     }
2781     auto snapshotFfrtHelper = scenePersistence_->GetSnapshotFfrtHelper();
2782     std::string taskName = "Session::SaveSnapshot" + std::to_string(persistentId_);
2783     snapshotFfrtHelper->CancelTask(taskName);
2784     snapshotFfrtHelper->SubmitTask(std::move(task), taskName);
2785 }
2786 
SetFreeMultiWindow()2787 void Session::SetFreeMultiWindow()
2788 {
2789     if (!SupportSnapshotAllSessionStatus()) {
2790         return;
2791     }
2792     if (GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
2793         freeMultiWindow_.store(false);
2794     } else {
2795         freeMultiWindow_.store(true);
2796     }
2797 }
2798 
DeleteHasSnapshot()2799 void Session::DeleteHasSnapshot()
2800 {
2801     for (uint32_t screenStatus = SCREEN_UNKNOWN; screenStatus < SCREEN_COUNT; screenStatus++) {
2802         for (uint32_t orientation = SNAPSHOT_PORTRAIT; orientation < ORIENTATION_COUNT; orientation++) {
2803             DeleteHasSnapshot({ screenStatus, orientation });
2804         }
2805     }
2806     DeleteHasSnapshotFreeMultiWindow();
2807 }
2808 
DeleteHasSnapshot(SnapshotStatus key)2809 void Session::DeleteHasSnapshot(SnapshotStatus key)
2810 {
2811     auto hasSnapshot = ScenePersistentStorage::HasKey("Snapshot_" + std::to_string(persistentId_) +
2812         "_" + std::to_string(key.first) + std::to_string(key.second),
2813         ScenePersistentStorageType::MAXIMIZE_STATE);
2814     if (hasSnapshot) {
2815         ScenePersistentStorage::Delete("Snapshot_" + std::to_string(persistentId_) +
2816             "_" + std::to_string(key.first) + std::to_string(key.second),
2817             ScenePersistentStorageType::MAXIMIZE_STATE);
2818     }
2819 }
2820 
DeleteHasSnapshotFreeMultiWindow()2821 void Session::DeleteHasSnapshotFreeMultiWindow()
2822 {
2823     auto hasSnapshotFreeMultiWindow = ScenePersistentStorage::HasKey("Snapshot_" + std::to_string(persistentId_),
2824         ScenePersistentStorageType::MAXIMIZE_STATE);
2825     if (hasSnapshotFreeMultiWindow) {
2826         ScenePersistentStorage::Delete("Snapshot_" + std::to_string(persistentId_),
2827             ScenePersistentStorageType::MAXIMIZE_STATE);
2828     }
2829 }
2830 
HasSnapshot(SnapshotStatus key)2831 bool Session::HasSnapshot(SnapshotStatus key)
2832 {
2833     auto hasSnapshot = ScenePersistentStorage::HasKey("Snapshot_" + std::to_string(persistentId_) +
2834         "_" + std::to_string(key.first) + std::to_string(key.second),
2835         ScenePersistentStorageType::MAXIMIZE_STATE);
2836     if (hasSnapshot && scenePersistence_) {
2837         scenePersistence_->SetHasSnapshot(true, key);
2838     }
2839     return hasSnapshot;
2840 }
2841 
HasSnapshotFreeMultiWindow()2842 bool Session::HasSnapshotFreeMultiWindow()
2843 {
2844     auto hasSnapshotFreeMultiWindow = ScenePersistentStorage::HasKey("Snapshot_" + std::to_string(persistentId_),
2845         ScenePersistentStorageType::MAXIMIZE_STATE);
2846     if (hasSnapshotFreeMultiWindow && scenePersistence_) {
2847         freeMultiWindow_.store(true);
2848         scenePersistence_->SetHasSnapshotFreeMultiWindow(true);
2849     }
2850     return hasSnapshotFreeMultiWindow;
2851 }
2852 
HasSnapshot()2853 bool Session::HasSnapshot()
2854 {
2855     for (uint32_t screenStatus = SCREEN_UNKNOWN; screenStatus < SCREEN_COUNT; screenStatus++) {
2856         for (uint32_t orientation = SNAPSHOT_PORTRAIT; orientation < ORIENTATION_COUNT; orientation++) {
2857             if (HasSnapshot({ screenStatus, orientation })) {
2858                 return true;
2859             }
2860         }
2861     }
2862     return HasSnapshotFreeMultiWindow();
2863 }
2864 
InitSnapshotCapacity()2865 void Session::InitSnapshotCapacity()
2866 {
2867     if (systemConfig_.supportSnapshotAllSessionStatus_) {
2868         capacity_ = maxCapacity;
2869     }
2870     if (scenePersistence_) {
2871         scenePersistence_->SetSnapshotCapacity(capacity_);
2872     }
2873 }
2874 
IsPersistentImageFit() const2875 bool Session::IsPersistentImageFit() const
2876 {
2877     auto isPersistentImageFit = Rosen::ScenePersistentStorage::HasKey(
2878         "SetImageForRecent_" + std::to_string(GetPersistentId()), Rosen::ScenePersistentStorageType::MAXIMIZE_STATE);
2879     return isPersistentImageFit;
2880 }
2881 
SupportSnapshotAllSessionStatus() const2882 bool Session::SupportSnapshotAllSessionStatus() const
2883 {
2884     return (!IsPersistentImageFit() && (capacity_ != defaultCapacity));
2885 }
2886 
GetWindowStatus() const2887 SnapshotStatus Session::GetWindowStatus() const
2888 {
2889     if (!SupportSnapshotAllSessionStatus()) {
2890         return defaultStatus;
2891     }
2892     uint32_t snapshotScreen = WSSnapshotHelper::GetScreenStatus();
2893     auto windowOrientation = GetWindowOrientation();
2894     uint32_t orientation = WSSnapshotHelper::GetOrientation(windowOrientation);
2895     return std::make_pair(snapshotScreen, orientation);
2896 }
2897 
GetSessionStatus(ScreenLockReason reason) const2898 SnapshotStatus Session::GetSessionStatus(ScreenLockReason reason) const
2899 {
2900     if (!SupportSnapshotAllSessionStatus()) {
2901         return defaultStatus;
2902     }
2903     uint32_t snapshotScreen;
2904     if (state_ == SessionState::STATE_BACKGROUND || state_ == SessionState::STATE_DISCONNECT) {
2905         snapshotScreen = lastSnapshotScreen_;
2906     } else {
2907         snapshotScreen = WSSnapshotHelper::GetScreenStatus();
2908     }
2909     if (reason == ScreenLockReason::EXPAND_TO_FOLD_SINGLE_POCKET) {
2910         snapshotScreen = SCREEN_EXPAND;
2911     }
2912     uint32_t orientation = WSSnapshotHelper::GetOrientation(currentRotation_);
2913     return std::make_pair(snapshotScreen, orientation);
2914 }
2915 
GetWindowOrientation() const2916 DisplayOrientation Session::GetWindowOrientation() const
2917 {
2918     if (!SupportSnapshotAllSessionStatus()) {
2919         return DisplayOrientation::PORTRAIT;
2920     }
2921     DisplayId displayId = GetScreenId();
2922     auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
2923     if (!screenSession) {
2924         TLOGE(WmsLogTag::WMS_PATTERN, "screenSession is nullptr, id:%{public}d", persistentId_);
2925         return DisplayOrientation::PORTRAIT;
2926     }
2927     auto screenProperty = screenSession->GetScreenProperty();
2928     DisplayOrientation displayOrientation = screenProperty.GetDisplayOrientation();
2929     auto windowOrientation = static_cast<uint32_t>(displayOrientation);
2930     auto snapshotScreen = WSSnapshotHelper::GetScreenStatus();
2931     if (snapshotScreen == SCREEN_UNKNOWN) {
2932         windowOrientation = (windowOrientation + SECONDARY_EXPAND_OFFSET) % ROTATION_COUNT;
2933     }
2934     return static_cast<DisplayOrientation>(windowOrientation);
2935 }
2936 
GetLastOrientation() const2937 uint32_t Session::GetLastOrientation() const
2938 {
2939     if (!SupportSnapshotAllSessionStatus()) {
2940         return SNAPSHOT_PORTRAIT;
2941     }
2942     return static_cast<uint32_t>(WSSnapshotHelper::GetDisplayOrientation(currentRotation_));
2943 }
2944 
SetSessionStateChangeListenser(const NotifySessionStateChangeFunc & func)2945 void Session::SetSessionStateChangeListenser(const NotifySessionStateChangeFunc& func)
2946 {
2947     PostTask([weakThis = wptr(this), func]() {
2948         auto session = weakThis.promote();
2949         if (session == nullptr) {
2950             WLOGFE("session is null");
2951             return;
2952         }
2953         session->sessionStateChangeFunc_ = func;
2954         auto changedState = session->GetSessionState(); // read and write state should in one thread
2955         if (changedState == SessionState::STATE_ACTIVE) {
2956             changedState = SessionState::STATE_FOREGROUND;
2957         } else if (changedState == SessionState::STATE_INACTIVE) {
2958             changedState = SessionState::STATE_BACKGROUND;
2959         } else if (changedState == SessionState::STATE_DISCONNECT) {
2960             return;
2961         }
2962         session->NotifySessionStateChange(changedState);
2963         TLOGNI(WmsLogTag::WMS_LIFE, "id: %{public}d, state_: %{public}d, changedState: %{public}d",
2964             session->GetPersistentId(), session->GetSessionState(), changedState);
2965     }, "SetSessionStateChangeListenser");
2966 }
2967 
SetClearSubSessionCallback(const NotifyClearSubSessionFunc & func)2968 void Session::SetClearSubSessionCallback(const NotifyClearSubSessionFunc& func)
2969 {
2970     PostTask(
2971         [weakThis = wptr(this), func, where = __func__]() {
2972             auto session = weakThis.promote();
2973             if (session == nullptr) {
2974                 TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
2975                 return;
2976             }
2977             session->clearSubSessionFunc_ = std::move(func);
2978         }, __func__);
2979 }
2980 
SetBufferAvailableChangeListener(const NotifyBufferAvailableChangeFunc & func)2981 void Session::SetBufferAvailableChangeListener(const NotifyBufferAvailableChangeFunc& func)
2982 {
2983     bufferAvailableChangeFunc_ = func;
2984     if (bufferAvailable_ && bufferAvailableChangeFunc_ != nullptr) {
2985         bufferAvailableChangeFunc_(bufferAvailable_, false);
2986     }
2987     WLOGFD("SetBufferAvailableChangeListener, id: %{public}d", GetPersistentId());
2988 }
2989 
UpdateWindowModeSupportType(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)2990 bool Session::UpdateWindowModeSupportType(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
2991 {
2992     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes =
2993         ExtractSupportWindowModeFromMetaData(abilityInfo);
2994     auto windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(updateWindowModes);
2995     const uint32_t noType = 0;
2996     if (windowModeSupportType != noType) {
2997         GetSessionProperty()->SetWindowModeSupportType(windowModeSupportType);
2998         return true;
2999     }
3000     return false;
3001 }
3002 
SetAcquireRotateAnimationConfigFunc(const AcquireRotateAnimationConfigFunc & func)3003 void Session::SetAcquireRotateAnimationConfigFunc(const AcquireRotateAnimationConfigFunc& func)
3004 {
3005     if (func == nullptr) {
3006         TLOGI(WmsLogTag::DEFAULT, "func is nullptr");
3007         return;
3008     }
3009     acquireRotateAnimationConfigFunc_ = func;
3010 }
3011 
GetRotateAnimationDuration()3012 int32_t Session::GetRotateAnimationDuration()
3013 {
3014     if (acquireRotateAnimationConfigFunc_) {
3015         RotateAnimationConfig rotateAnimationConfig;
3016         acquireRotateAnimationConfigFunc_(rotateAnimationConfig);
3017         return rotateAnimationConfig.duration_;
3018     }
3019     return ROTATE_ANIMATION_DURATION;
3020 }
3021 
UnregisterSessionChangeListeners()3022 void Session::UnregisterSessionChangeListeners()
3023 {
3024     sessionStateChangeFunc_ = nullptr;
3025     keyboardStateChangeFunc_ = nullptr;
3026     sessionFocusableChangeFunc_ = nullptr;
3027     sessionTouchableChangeFunc_ = nullptr;
3028     clickFunc_ = nullptr;
3029     jsSceneSessionExceptionFunc_ = nullptr;
3030     sessionExceptionFunc_ = nullptr;
3031     terminateSessionFunc_ = nullptr;
3032     pendingSessionActivationFunc_ = nullptr;
3033     changeSessionVisibilityWithStatusBarFunc_ = nullptr;
3034     bufferAvailableChangeFunc_ = nullptr;
3035     backPressedFunc_ = nullptr;
3036     terminateSessionFuncNew_ = nullptr;
3037     terminateSessionFuncTotal_ = nullptr;
3038     updateSessionLabelFunc_ = nullptr;
3039     updateSessionIconFunc_ = nullptr;
3040     pendingSessionToForegroundFunc_ = nullptr;
3041     pendingSessionToBackgroundForDelegatorFunc_ = nullptr;
3042     raiseToTopForPointDownFunc_ = nullptr;
3043     sessionInfoLockedStateChangeFunc_ = nullptr;
3044     contextTransparentFunc_ = nullptr;
3045     sessionRectChangeFunc_ = nullptr;
3046     updateSessionLabelAndIconFunc_ = nullptr;
3047     onRaiseMainWindowAboveTarget_ = nullptr;
3048     WLOGFD("UnregisterSessionChangeListenser, id: %{public}d", GetPersistentId());
3049 }
3050 
SetSessionStateChangeNotifyManagerListener(const NotifySessionStateChangeNotifyManagerFunc & func)3051 void Session::SetSessionStateChangeNotifyManagerListener(const NotifySessionStateChangeNotifyManagerFunc& func)
3052 {
3053     sessionStateChangeNotifyManagerFunc_ = func;
3054     if (state_ == SessionState::STATE_DISCONNECT) {
3055         return;
3056     }
3057     NotifySessionStateChange(state_);
3058 }
3059 
SetSessionInfoChangeNotifyManagerListener(const NotifySessionInfoChangeNotifyManagerFunc & func)3060 void Session::SetSessionInfoChangeNotifyManagerListener(const NotifySessionInfoChangeNotifyManagerFunc& func)
3061 {
3062     sessionInfoChangeNotifyManagerFunc_ = func;
3063 }
3064 
SetSessionPropertyChangeNotifyManagerListener(const NotifySessionPropertyChangeNotifyManagerFunc & func)3065 void Session::SetSessionPropertyChangeNotifyManagerListener(const NotifySessionPropertyChangeNotifyManagerFunc& func)
3066 {
3067     sessionPropertyChangeNotifyManagerFunc_ = func;
3068 }
3069 
SetDisplayIdChangedNotifyManagerListener(const NotifyDisplayIdChangedNotifyManagerFunc & func)3070 void Session::SetDisplayIdChangedNotifyManagerListener(const NotifyDisplayIdChangedNotifyManagerFunc& func)
3071 {
3072     displayIdChangedNotifyManagerFunc_ = func;
3073 }
3074 
SetRequestFocusStatusNotifyManagerListener(const NotifyRequestFocusStatusNotifyManagerFunc & func)3075 void Session::SetRequestFocusStatusNotifyManagerListener(const NotifyRequestFocusStatusNotifyManagerFunc& func)
3076 {
3077     requestFocusStatusNotifyManagerFunc_ = func;
3078 }
3079 
SetNotifyUIRequestFocusFunc(const NotifyUIRequestFocusFunc & func)3080 void Session::SetNotifyUIRequestFocusFunc(const NotifyUIRequestFocusFunc& func)
3081 {
3082     std::unique_lock<std::shared_mutex> lock(uiRequestFocusMutex_);
3083     requestFocusFunc_ = func;
3084 }
3085 
SetNotifyUILostFocusFunc(const NotifyUILostFocusFunc & func)3086 void Session::SetNotifyUILostFocusFunc(const NotifyUILostFocusFunc& func)
3087 {
3088     std::unique_lock<std::shared_mutex> lock(uiLostFocusMutex_);
3089     lostFocusFunc_ = func;
3090 }
3091 
SetGetStateFromManagerListener(const GetStateFromManagerFunc & func)3092 void Session::SetGetStateFromManagerListener(const GetStateFromManagerFunc& func)
3093 {
3094     getStateFromManagerFunc_ = func;
3095 }
3096 
NotifySessionStateChange(const SessionState & state)3097 void Session::NotifySessionStateChange(const SessionState& state)
3098 {
3099     PostTask([weakThis = wptr(this), state]() {
3100         auto session = weakThis.promote();
3101         if (session == nullptr) {
3102             WLOGFE("session is null");
3103             return;
3104         }
3105         TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionStateChange, [state: %{public}u, persistent: %{public}d]",
3106             static_cast<uint32_t>(state), session->GetPersistentId());
3107         if (session->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
3108             session->keyboardStateChangeFunc_) {
3109             session->keyboardStateChangeFunc_(state, session->GetSessionProperty()->GetKeyboardEffectOption());
3110         } else if (session->sessionStateChangeFunc_) {
3111             session->sessionStateChangeFunc_(state);
3112         } else {
3113             TLOGNI(WmsLogTag::WMS_LIFE, "sessionStateChangeFunc is null");
3114         }
3115         if (!session->sessionStateChangeFunc_ && state == SessionState::STATE_DISCONNECT) {
3116             auto parentSession = session->GetParentSession();
3117             if (parentSession && parentSession->clearSubSessionFunc_) {
3118                 parentSession->clearSubSessionFunc_(session->GetPersistentId());
3119                 TLOGNI(WmsLogTag::WMS_LIFE, "notify clear subSession, parentId: %{public}d, "
3120                     "persistentId: %{public}d", parentSession->GetPersistentId(), session->GetPersistentId());
3121             }
3122         }
3123 
3124         if (session->sessionStateChangeNotifyManagerFunc_) {
3125             session->sessionStateChangeNotifyManagerFunc_(session->GetPersistentId(), state);
3126         } else {
3127             TLOGNI(WmsLogTag::WMS_LIFE, "sessionStateChangeNotifyManagerFunc is null");
3128         }
3129     }, "NotifySessionStateChange");
3130 }
3131 
SetSessionFocusableChangeListener(const NotifySessionFocusableChangeFunc & func)3132 void Session::SetSessionFocusableChangeListener(const NotifySessionFocusableChangeFunc& func)
3133 {
3134     sessionFocusableChangeFunc_ = func;
3135     NotifySessionFocusableChange(GetFocusable());
3136 }
3137 
GetSkipSelfWhenShowOnVirtualScreen() const3138 bool Session::GetSkipSelfWhenShowOnVirtualScreen() const
3139 {
3140     return GetSessionProperty()->GetSkipSelfWhenShowOnVirtualScreen();
3141 }
3142 
SetSessionTouchableChangeListener(const NotifySessionTouchableChangeFunc & func)3143 void Session::SetSessionTouchableChangeListener(const NotifySessionTouchableChangeFunc& func)
3144 {
3145     sessionTouchableChangeFunc_ = func;
3146     sessionTouchableChangeFunc_(GetTouchable());
3147 }
3148 
SetClickListener(const NotifyClickFunc & func)3149 void Session::SetClickListener(const NotifyClickFunc& func)
3150 {
3151     clickFunc_ = func;
3152 }
3153 
NotifySessionFocusableChange(bool isFocusable)3154 void Session::NotifySessionFocusableChange(bool isFocusable)
3155 {
3156     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, focusable: %{public}u", GetPersistentId(), isFocusable);
3157     if (sessionFocusableChangeFunc_) {
3158         sessionFocusableChangeFunc_(isFocusable);
3159     }
3160 }
3161 
NotifySessionTouchableChange(bool touchable)3162 void Session::NotifySessionTouchableChange(bool touchable)
3163 {
3164     WLOGFD("Notify session touchable change: %{public}d", touchable);
3165     if (sessionTouchableChangeFunc_) {
3166         sessionTouchableChangeFunc_(touchable);
3167     }
3168 }
3169 
NotifyClick(bool requestFocus,bool isClick)3170 void Session::NotifyClick(bool requestFocus, bool isClick)
3171 {
3172     TLOGD(WmsLogTag::WMS_FOCUS, "requestFocus: %{public}u, isClick: %{public}u", requestFocus, isClick);
3173     if (clickFunc_) {
3174         clickFunc_(requestFocus, isClick);
3175     }
3176 }
3177 
NotifyRequestFocusStatusNotifyManager(bool isFocused,bool byForeground,FocusChangeReason reason)3178 void Session::NotifyRequestFocusStatusNotifyManager(bool isFocused, bool byForeground, FocusChangeReason reason)
3179 {
3180     TLOGD(WmsLogTag::WMS_FOCUS, "NotifyRequestFocusStatusNotifyManager id: %{public}d, focused: %{public}d,\
3181         reason:  %{public}d", GetPersistentId(), isFocused, reason);
3182     if (requestFocusStatusNotifyManagerFunc_) {
3183         requestFocusStatusNotifyManagerFunc_(GetPersistentId(), isFocused, byForeground, reason);
3184     }
3185 }
3186 
GetStateFromManager(const ManagerState key)3187 bool Session::GetStateFromManager(const ManagerState key)
3188 {
3189     if (getStateFromManagerFunc_) {
3190         return getStateFromManagerFunc_(key);
3191     }
3192     switch (key) {
3193         case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
3194             return false;
3195             break;
3196         default:
3197             return false;
3198     }
3199 }
3200 
NotifyUIRequestFocus()3201 void Session::NotifyUIRequestFocus()
3202 {
3203     WLOGFD("NotifyUIRequestFocus id: %{public}d", GetPersistentId());
3204     std::shared_lock<std::shared_mutex> lock(uiRequestFocusMutex_);
3205     if (requestFocusFunc_) {
3206         requestFocusFunc_();
3207     }
3208 }
3209 
NotifyUILostFocus()3210 void Session::NotifyUILostFocus()
3211 {
3212     WLOGFD("NotifyUILostFocus id: %{public}d", GetPersistentId());
3213     std::shared_lock<std::shared_mutex> lock(uiLostFocusMutex_);
3214     if (lostFocusFunc_) {
3215         lostFocusFunc_();
3216     }
3217 }
3218 
PresentFocusIfNeed(int32_t pointerAction,int32_t sourceType)3219 void Session::PresentFocusIfNeed(int32_t pointerAction, int32_t sourceType)
3220 {
3221     TLOGD(WmsLogTag::WMS_FOCUS, "OnClick down, id: %{public}d", GetPersistentId());
3222     bool isHoverDown = pointerAction == MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER &&
3223         sourceType ==  MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
3224     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_DOWN ||
3225         pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN ||
3226         isHoverDown) {
3227         if (!isFocused_ && GetFocusable()) {
3228             FocusChangeReason reason = FocusChangeReason::CLICK;
3229             NotifyRequestFocusStatusNotifyManager(true, false, reason);
3230         }
3231         NotifyClick();
3232     }
3233 }
3234 
UpdateFocus(bool isFocused)3235 WSError Session::UpdateFocus(bool isFocused)
3236 {
3237     if (isFocused_ == isFocused) {
3238         TLOGD(WmsLogTag::WMS_FOCUS, "Session focus do not change");
3239         return WSError::WS_DO_NOTHING;
3240     }
3241     isFocused_ = isFocused;
3242     UpdateGestureBackEnabled();
3243     // notify scb arkui focus
3244     if (!isFocused) {
3245         NotifyUILostFocus();
3246     }
3247     return WSError::WS_OK;
3248 }
3249 
NotifyFocusStatus(bool isFocused)3250 WSError Session::NotifyFocusStatus(bool isFocused)
3251 {
3252     if (!IsSessionValid()) {
3253         TLOGD(WmsLogTag::WMS_FOCUS, "Session is invalid, id: %{public}d state: %{public}u",
3254             GetPersistentId(), GetSessionState());
3255         return WSError::WS_ERROR_INVALID_SESSION;
3256     }
3257     if (!sessionStage_) {
3258         TLOGE(WmsLogTag::WMS_FOCUS, "Session stage is invalid, id: %{public}d state: %{public}u",
3259             GetPersistentId(), GetSessionState());
3260         return WSError::WS_ERROR_NULLPTR;
3261     }
3262     sessionStage_->UpdateFocus(isFocused);
3263 
3264     return WSError::WS_OK;
3265 }
3266 
RequestFocus(bool isFocused)3267 WSError Session::RequestFocus(bool isFocused)
3268 {
3269     if (!SessionPermission::IsSystemCalling()) {
3270         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
3271         return WSError::WS_ERROR_NOT_SYSTEM_APP;
3272     }
3273     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
3274     NotifyRequestFocusStatusNotifyManager(isFocused, false, reason);
3275     return WSError::WS_OK;
3276 }
3277 
SetExclusivelyHighlighted(bool isExclusivelyHighlighted)3278 void Session::SetExclusivelyHighlighted(bool isExclusivelyHighlighted)
3279 {
3280     auto property = GetSessionProperty();
3281     if (property == nullptr) {
3282         TLOGE(WmsLogTag::WMS_FOCUS, "property is nullptr, windowId: %{public}d", persistentId_);
3283         return;
3284     }
3285     if (isExclusivelyHighlighted == property->GetExclusivelyHighlighted()) {
3286         return;
3287     }
3288     TLOGI(WmsLogTag::WMS_FOCUS, "windowId: %{public}d, isExclusivelyHighlighted: %{public}d", persistentId_,
3289         isExclusivelyHighlighted);
3290     property->SetExclusivelyHighlighted(isExclusivelyHighlighted);
3291 }
3292 
UpdateHighlightStatus(bool isHighlight,bool needBlockHighlightNotify)3293 WSError Session::UpdateHighlightStatus(bool isHighlight, bool needBlockHighlightNotify)
3294 {
3295     TLOGD(WmsLogTag::WMS_FOCUS,
3296         "windowId: %{public}d, currHighlight: %{public}d, nextHighlight: %{public}d, needBlockNotify:%{public}d",
3297         persistentId_, isHighlighted_, isHighlight, needBlockHighlightNotify);
3298     if (isHighlighted_ == isHighlight) {
3299         return WSError::WS_DO_NOTHING;
3300     }
3301     isHighlighted_ = isHighlight;
3302     if (needBlockHighlightNotify) {
3303         NotifyHighlightChange(isHighlight);
3304     }
3305     std::lock_guard lock(highlightChangeFuncMutex_);
3306     if (highlightChangeFunc_ != nullptr) {
3307         highlightChangeFunc_(isHighlight);
3308     }
3309     return WSError::WS_OK;
3310 }
3311 
NotifyHighlightChange(bool isHighlight)3312 WSError Session::NotifyHighlightChange(bool isHighlight)
3313 {
3314     if (IsSystemSession()) {
3315         TLOGW(WmsLogTag::WMS_FOCUS, "Invalid [%{public}d, %{public}u]", persistentId_, GetSessionState());
3316         return WSError::WS_ERROR_INVALID_SESSION;
3317     }
3318     if (!sessionStage_) {
3319         TLOGE(WmsLogTag::WMS_FOCUS, "sessionStage is null");
3320         return WSError::WS_ERROR_NULLPTR;
3321     }
3322     sessionStage_->NotifyHighlightChange(isHighlight);
3323     return WSError::WS_OK;
3324 }
3325 
GetIsHighlighted(bool & isHighlighted)3326 WSError Session::GetIsHighlighted(bool& isHighlighted)
3327 {
3328     isHighlighted = isHighlighted_;
3329     TLOGD(WmsLogTag::WMS_FOCUS, "windowId: %{public}d, isHighlighted: %{public}d",
3330         GetPersistentId(), isHighlighted_);
3331     return WSError::WS_OK;
3332 }
3333 
SetAppSupportPhoneInPc(bool isSupportPhone)3334 WSError Session::SetAppSupportPhoneInPc(bool isSupportPhone)
3335 {
3336     TLOGI(WmsLogTag::WMS_SCB, "isSupportPhone: %{public}d", isSupportPhone);
3337     GetSessionProperty()->SetIsAppSupportPhoneInPc(isSupportPhone);
3338     return WSError::WS_OK;
3339 }
3340 
SetCompatibleModeProperty(const sptr<CompatibleModeProperty> compatibleModeProperty)3341 WSError Session::SetCompatibleModeProperty(const sptr<CompatibleModeProperty> compatibleModeProperty)
3342 {
3343     auto property = GetSessionProperty();
3344     if (property == nullptr) {
3345         TLOGE(WmsLogTag::WMS_COMPAT, "id: %{public}d property is nullptr", persistentId_);
3346         return WSError::WS_ERROR_NULLPTR;
3347     }
3348     property->SetCompatibleModeProperty(compatibleModeProperty);
3349     if (!sessionStage_) {
3350         TLOGE(WmsLogTag::WMS_COMPAT, "sessionStage is null");
3351         return WSError::WS_ERROR_NULLPTR;
3352     }
3353     return sessionStage_->NotifyCompatibleModePropertyChange(compatibleModeProperty);
3354 }
3355 
SetIsPcAppInPad(bool enable)3356 WSError Session::SetIsPcAppInPad(bool enable)
3357 {
3358     TLOGI(WmsLogTag::WMS_COMPAT, "SetIsPcAppInPad enable: %{public}d", enable);
3359     GetSessionProperty()->SetIsPcAppInPad(enable);
3360     return WSError::WS_OK;
3361 }
3362 
SetPcAppInpadCompatibleMode(bool enabled)3363 WSError Session::SetPcAppInpadCompatibleMode(bool enabled)
3364 {
3365     TLOGD(WmsLogTag::WMS_COMPAT, "isPcAppInpadCompatibleMode: %{public}d", enabled);
3366     GetSessionProperty()->SetPcAppInpadCompatibleMode(enabled);
3367     return WSError::WS_OK;
3368 }
3369 
SetPcAppInpadSpecificSystemBarInvisible(bool isPcAppInpadSpecificSystemBarInvisible)3370 WSError Session::SetPcAppInpadSpecificSystemBarInvisible(bool isPcAppInpadSpecificSystemBarInvisible)
3371 {
3372     TLOGD(WmsLogTag::WMS_COMPAT, "isPcAppInpadSpecificSystemBarInvisible: %{public}d",
3373         isPcAppInpadSpecificSystemBarInvisible);
3374     GetSessionProperty()->SetPcAppInpadSpecificSystemBarInvisible(isPcAppInpadSpecificSystemBarInvisible);
3375     return WSError::WS_OK;
3376 }
3377 
SetPcAppInpadOrientationLandscape(bool isPcAppInpadOrientationLandscape)3378 WSError Session::SetPcAppInpadOrientationLandscape(bool isPcAppInpadOrientationLandscape)
3379 {
3380     TLOGD(WmsLogTag::WMS_COMPAT, "isPcAppInpadOrientationLandscape: %{public}d",
3381         isPcAppInpadOrientationLandscape);
3382     GetSessionProperty()->SetPcAppInpadOrientationLandscape(isPcAppInpadOrientationLandscape);
3383     return WSError::WS_OK;
3384 }
3385 
PcAppInPadNormalClose()3386 WSError Session::PcAppInPadNormalClose()
3387 {
3388     TLOGD(WmsLogTag::WMS_COMPAT, "windowId:%{public}d", GetPersistentId());
3389     if (!IsSessionValid()) {
3390         TLOGD(WmsLogTag::WMS_COMPAT, "Session is invalid, id: %{public}d state: %{public}u",
3391             GetPersistentId(), GetSessionState());
3392         return WSError::WS_ERROR_INVALID_SESSION;
3393     }
3394     if (sessionStage_ == nullptr) {
3395         TLOGE(WmsLogTag::WMS_COMPAT, "session stage is nullptr id: %{public}d state: %{public}u",
3396               GetPersistentId(), GetSessionState());
3397         return WSError::WS_ERROR_NULLPTR;
3398     }
3399     return sessionStage_->PcAppInPadNormalClose();
3400 }
3401 
SetHasRequestedVsyncFunc(HasRequestedVsyncFunc && func)3402 void Session::SetHasRequestedVsyncFunc(HasRequestedVsyncFunc&& func)
3403 {
3404     if (!func) {
3405         TLOGW(WmsLogTag::WMS_LAYOUT, "id:%{public}d, func is null", GetPersistentId());
3406         return;
3407     }
3408     hasRequestedVsyncFunc_ = std::move(func);
3409 }
3410 
SetRequestNextVsyncWhenModeChangeFunc(RequestNextVsyncWhenModeChangeFunc && func)3411 void Session::SetRequestNextVsyncWhenModeChangeFunc(RequestNextVsyncWhenModeChangeFunc&& func)
3412 {
3413     if (!func) {
3414         TLOGW(WmsLogTag::WMS_LAYOUT, "id:%{public}d, func is null", GetPersistentId());
3415         return;
3416     }
3417     requestNextVsyncWhenModeChangeFunc_ = std::move(func);
3418 }
3419 
RequestNextVsyncWhenModeChange()3420 WSError Session::RequestNextVsyncWhenModeChange()
3421 {
3422     if (!hasRequestedVsyncFunc_) {
3423         TLOGW(WmsLogTag::WMS_LAYOUT, "id:%{public}d, func is null", GetPersistentId());
3424         return WSError::WS_ERROR_NULLPTR;
3425     }
3426     isWindowModeDirty_.store(true);
3427     bool hasRequestedVsync = false;
3428     hasRequestedVsyncFunc_(hasRequestedVsync);
3429     timesToWaitForVsync_.store(hasRequestedVsync ? TIMES_TO_WAIT_FOR_VSYNC_TWICE : TIMES_TO_WAIT_FOR_VSYNC_ONECE);
3430     InitVsyncCallbackForModeChangeAndRequestNextVsync();
3431     return WSError::WS_OK;
3432 }
3433 
OnVsyncReceivedAfterModeChanged()3434 void Session::OnVsyncReceivedAfterModeChanged()
3435 {
3436     const char* const funcName = __func__;
3437     PostTask([weakThis = wptr(this), funcName] {
3438         auto session = weakThis.promote();
3439         if (!session) {
3440             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
3441             return;
3442         }
3443         if (!session->isWindowModeDirty_.load()) {
3444             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: windowMode is not dirty, nothing to do, id:%{public}d",
3445                 funcName, session->GetPersistentId());
3446             return;
3447         }
3448         session->timesToWaitForVsync_.fetch_sub(1);
3449         TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, mode:%{public}d, waitVsyncTimes:%{public}d",
3450             funcName, session->GetPersistentId(), session->GetWindowMode(), session->timesToWaitForVsync_.load());
3451         bool isWindowModeDirty = true;
3452         if (session->timesToWaitForVsync_.load() > 0) {
3453             session->InitVsyncCallbackForModeChangeAndRequestNextVsync();
3454         } else if (session->timesToWaitForVsync_.load() < 0) {
3455             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, waitVsyncTimes:%{public}d",
3456                 funcName, session->GetPersistentId(), session->timesToWaitForVsync_.load());
3457             session->timesToWaitForVsync_.store(0);
3458             session->isWindowModeDirty_.store(false);
3459         } else if (session->timesToWaitForVsync_.load() == 0 && session->sessionStage_ &&
3460                    session->isWindowModeDirty_.compare_exchange_strong(isWindowModeDirty, false)) {
3461             session->sessionStage_->NotifyLayoutFinishAfterWindowModeChange(session->GetWindowMode());
3462         } else {
3463             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, sessionStage is null or mode is not dirty",
3464                 funcName, session->GetPersistentId());
3465             session->isWindowModeDirty_.store(false);
3466         }
3467         }, funcName);
3468 }
3469 
InitVsyncCallbackForModeChangeAndRequestNextVsync()3470 void Session::InitVsyncCallbackForModeChangeAndRequestNextVsync()
3471 {
3472     if (!requestNextVsyncWhenModeChangeFunc_) {
3473         TLOGW(WmsLogTag::WMS_LAYOUT, "id:%{public}d, func is null", GetPersistentId());
3474         return;
3475     }
3476     std::shared_ptr<VsyncCallback> nextVsyncCallback = std::make_shared<VsyncCallback>();
3477     nextVsyncCallback->onCallback = [weakThis = wptr(this), funcName = __func__](int64_t, int64_t) {
3478         auto session = weakThis.promote();
3479         if (!session) {
3480             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
3481             return;
3482         }
3483         session->OnVsyncReceivedAfterModeChanged();
3484     };
3485     requestNextVsyncWhenModeChangeFunc_(nextVsyncCallback);
3486 }
3487 
UpdateWindowMode(WindowMode mode)3488 WSError Session::UpdateWindowMode(WindowMode mode)
3489 {
3490     WLOGFD("Session update window mode, id: %{public}d, mode: %{public}d", GetPersistentId(),
3491         static_cast<int32_t>(mode));
3492     if (state_ == SessionState::STATE_END) {
3493         WLOGFI("session is already destroyed or property is nullptr! id: %{public}d state: %{public}u",
3494             GetPersistentId(), GetSessionState());
3495         return WSError::WS_ERROR_INVALID_SESSION;
3496     } else if (state_ == SessionState::STATE_DISCONNECT) {
3497         GetSessionProperty()->SetWindowMode(mode);
3498         NotifySessionPropertyChange(WindowInfoKey::WINDOW_MODE);
3499         GetSessionProperty()->SetIsNeedUpdateWindowMode(true);
3500         UpdateGestureBackEnabled();
3501     } else {
3502         GetSessionProperty()->SetWindowMode(mode);
3503         NotifySessionPropertyChange(WindowInfoKey::WINDOW_MODE);
3504         RequestNextVsyncWhenModeChange();
3505         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
3506             GetSessionProperty()->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
3507         }
3508         UpdateGestureBackEnabled();
3509         UpdateGravityWhenUpdateWindowMode(mode);
3510         if (!sessionStage_) {
3511             return WSError::WS_ERROR_NULLPTR;
3512         }
3513         return sessionStage_->UpdateWindowMode(mode);
3514     }
3515     return WSError::WS_OK;
3516 }
3517 
UpdateGravityWhenUpdateWindowMode(WindowMode mode)3518 void Session::UpdateGravityWhenUpdateWindowMode(WindowMode mode)
3519 {
3520     auto surfaceNode = GetSurfaceNode();
3521     if ((systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) && surfaceNode != nullptr) {
3522         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
3523             surfaceNode->SetFrameGravity(Gravity::LEFT);
3524         } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
3525             surfaceNode->SetFrameGravity(Gravity::RIGHT);
3526         } else if (mode == WindowMode::WINDOW_MODE_FLOATING || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
3527             surfaceNode->SetFrameGravity(Gravity::RESIZE);
3528         }
3529     }
3530 }
3531 
SetSystemSceneBlockingFocus(bool blocking)3532 WSError Session::SetSystemSceneBlockingFocus(bool blocking)
3533 {
3534     TLOGW(WmsLogTag::WMS_FOCUS, "Session set blocking focus, id: %{public}d, mode: %{public}d, Session is not system.",
3535         GetPersistentId(), blocking);
3536     return WSError::WS_ERROR_INVALID_SESSION;
3537 }
3538 
GetBlockingFocus() const3539 bool Session::GetBlockingFocus() const
3540 {
3541     return blockingFocus_;
3542 }
3543 
SetSessionProperty(const sptr<WindowSessionProperty> & property)3544 WSError Session::SetSessionProperty(const sptr<WindowSessionProperty>& property)
3545 {
3546     property_->CopyFrom(property);
3547 
3548     NotifySessionInfoChange();
3549     return WSError::WS_OK;
3550 }
3551 
SetSessionPropertyForReconnect(const sptr<WindowSessionProperty> & property)3552 WSError Session::SetSessionPropertyForReconnect(const sptr<WindowSessionProperty>& property)
3553 {
3554     property_->CopyFrom(property);
3555 
3556     auto hotAreasChangeCallback = [weakThis = wptr(this)]() {
3557         auto session = weakThis.promote();
3558         if (session == nullptr) {
3559             TLOGNE(WmsLogTag::WMS_EVENT, "session is nullptr");
3560             return;
3561         }
3562         session->NotifySessionInfoChange();
3563     };
3564     property_->SetSessionPropertyChangeCallback(hotAreasChangeCallback);
3565     NotifySessionInfoChange();
3566     return WSError::WS_OK;
3567 }
3568 
3569 /** @note @window.layout */
RectSizeCheckProcess(uint32_t curWidth,uint32_t curHeight,uint32_t minWidth,uint32_t minHeight,uint32_t maxFloatingWindowSize)3570 void Session::RectSizeCheckProcess(uint32_t curWidth, uint32_t curHeight, uint32_t minWidth,
3571     uint32_t minHeight, uint32_t maxFloatingWindowSize)
3572 {
3573     constexpr uint32_t marginOfError = 2; // The max vp bias for preventing giant logs.
3574     if (curWidth + marginOfError < minWidth || curWidth > maxFloatingWindowSize + marginOfError ||
3575         curHeight + marginOfError < minHeight || curHeight > maxFloatingWindowSize + marginOfError) {
3576         TLOGE(WmsLogTag::WMS_LAYOUT, "RectCheck err sessionID: %{public}d rect %{public}s",
3577             GetPersistentId(), GetSessionRect().ToString().c_str());
3578         std::ostringstream oss;
3579         oss << " RectCheck err size ";
3580         oss << " cur persistentId: " << GetPersistentId() << ",";
3581         oss << " windowType: " << static_cast<uint32_t>(GetWindowType()) << ",";
3582         oss << " windowName: " << GetSessionProperty()->GetWindowName() << ",";
3583         oss << " windowState: " << static_cast<uint32_t>(GetSessionProperty()->GetWindowState()) << ",";
3584         oss << " curWidth: " << curWidth << ",";
3585         oss << " curHeight: " << curHeight << ",";
3586         oss << " minWidth: " << minWidth << ",";
3587         oss << " minHeight: " << minHeight << ",";
3588         oss << " maxFloatingWindowSize: " << maxFloatingWindowSize << ",";
3589         oss << " sessionRect: " << GetSessionRect().ToString() << ";";
3590         WindowInfoReporter::GetInstance().ReportWindowException(
3591             static_cast<int32_t>(WindowDFXHelperType::WINDOW_RECT_CHECK), getpid(), oss.str());
3592     }
3593 }
3594 
3595 /** @note @window.layout */
RectCheckProcess()3596 void Session::RectCheckProcess()
3597 {
3598     if (!(IsSessionForeground() || isVisible_)) {
3599         return;
3600     }
3601     auto displayId = GetSessionProperty()->GetDisplayId();
3602     std::map<ScreenId, ScreenProperty> screensProperties =
3603         Rosen::ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
3604     if (screensProperties.find(displayId) == screensProperties.end()) {
3605         return;
3606     }
3607     auto screenProperty = screensProperties[displayId];
3608     float density = screenProperty.GetDensity();
3609     if (!NearZero(density) && !NearZero(GetSessionRect().height_)) {
3610         float curWidth = GetSessionRect().width_ / density;
3611         float curHeight = GetSessionRect().height_ / density;
3612         float ratio = GetAspectRatio();
3613         float actRatio = curWidth / curHeight;
3614         if (!NearZero(ratio) && !NearEqual(ratio, actRatio)) {
3615             TLOGE(WmsLogTag::WMS_LAYOUT, "RectCheck err ratio %{public}f != actRatio: %{public}f", ratio, actRatio);
3616             std::ostringstream oss;
3617             oss << " RectCheck err ratio ";
3618             oss << " cur persistentId: " << GetPersistentId() << ",";
3619             oss << " windowType: " << static_cast<uint32_t>(GetWindowType()) << ",";
3620             oss << " windowName: " << GetSessionProperty()->GetWindowName() << ",";
3621             oss << " windowState: " << static_cast<uint32_t>(GetSessionProperty()->GetWindowState()) << ",";
3622             oss << " curWidth: " << curWidth << ",";
3623             oss << " curHeight: " << curHeight << ",";
3624             oss << " setting ratio: " << ratio << ",";
3625             oss << " sessionRect: " << GetSessionRect().ToString() << ";";
3626             WindowInfoReporter::GetInstance().ReportWindowException(
3627                 static_cast<int32_t>(WindowDFXHelperType::WINDOW_RECT_CHECK), getpid(), oss.str());
3628         }
3629         RectCheck(curWidth, curHeight);
3630     }
3631 }
3632 
3633 /** @note @window.layout */
SetSessionRect(const WSRect & rect)3634 void Session::SetSessionRect(const WSRect& rect)
3635 {
3636     if (GetSessionRect() == rect) {
3637         TLOGW(WmsLogTag::WMS_LAYOUT, "id: %{public}d skip same rect", persistentId_);
3638         return;
3639     }
3640     layoutController_->SetSessionRect(rect);
3641     dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
3642     RectCheckProcess();
3643 }
3644 
3645 /** @note @window.layout */
GetSessionRect() const3646 WSRect Session::GetSessionRect() const
3647 {
3648     return layoutController_->GetSessionRect();
3649 }
3650 
3651 /** @note @window.layout */
GetSessionScreenRelativeRect() const3652 WSRect Session::GetSessionScreenRelativeRect() const
3653 {
3654     if (layoutController_->GetSizeChangeReason() == SizeChangeReason::DRAG_MOVE) {
3655         return layoutController_->ConvertGlobalRectToRelative(layoutController_->GetSessionRect(), GetDisplayId());
3656     }
3657     return layoutController_->GetSessionRect();
3658 }
3659 
3660 /** @note @window.layout */
GetGlobalScaledRect(Rect & globalScaledRect)3661 WMError Session::GetGlobalScaledRect(Rect& globalScaledRect)
3662 {
3663     auto task = [weakThis = wptr(this), &globalScaledRect] {
3664         auto session = weakThis.promote();
3665         if (!session) {
3666             TLOGNE(WmsLogTag::WMS_LAYOUT, "session is null");
3667             return WMError::WM_ERROR_DESTROYED_OBJECT;
3668         }
3669         session->GetLayoutController()->GetGlobalScaledRect(globalScaledRect);
3670         TLOGND(WmsLogTag::WMS_LAYOUT, "Id:%{public}d globalScaledRect:%{public}s",
3671             session->GetPersistentId(), globalScaledRect.ToString().c_str());
3672         return WMError::WM_OK;
3673     };
3674     return PostSyncTask(task, __func__);
3675 }
3676 
3677 /** @note @window.layout */
GetSessionGlobalRect() const3678 WSRect Session::GetSessionGlobalRect() const
3679 {
3680     return layoutController_->GetSessionGlobalRect();
3681 }
3682 
3683 /** @note @window.layout */
GetSessionGlobalRectInMultiScreen() const3684 WSRect Session::GetSessionGlobalRectInMultiScreen() const
3685 {
3686     if (IsDragMoving()) {
3687         return GetLayoutController()->ConvertGlobalRectToRelative(GetSessionRect(), GetDisplayId());
3688     }
3689     return GetSessionGlobalRect();
3690 }
3691 
3692 /** @note @window.layout */
SetSessionGlobalRect(const WSRect & rect)3693 void Session::SetSessionGlobalRect(const WSRect& rect)
3694 {
3695     if (layoutController_->SetSessionGlobalRect(rect)) {
3696         dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::GLOBAL_RECT);
3697     }
3698 }
3699 
3700 /** @note @window.layout */
GetLastLayoutRect() const3701 WSRect Session::GetLastLayoutRect() const
3702 {
3703     return lastLayoutRect_;
3704 }
3705 
3706 /** @note @window.layout */
GetLayoutRect() const3707 WSRect Session::GetLayoutRect() const
3708 {
3709     return layoutRect_;
3710 }
3711 
SetSessionRequestRect(const WSRect & rect)3712 void Session::SetSessionRequestRect(const WSRect& rect)
3713 {
3714     GetSessionProperty()->SetRequestRect(SessionHelper::TransferToRect(rect));
3715     WLOGFD("is: %{public}d, rect: [%{public}d, %{public}d, %{public}u, %{public}u]", persistentId_,
3716         rect.posX_, rect.posY_, rect.width_, rect.height_);
3717 }
3718 
GetSessionRequestRect() const3719 WSRect Session::GetSessionRequestRect() const
3720 {
3721     WSRect rect = SessionHelper::TransferToWSRect(GetSessionProperty()->GetRequestRect());
3722     WLOGFD("id: %{public}d, rect: %{public}s", persistentId_, rect.ToString().c_str());
3723     return rect;
3724 }
3725 
3726 /** @note @window.layout */
SetClientRect(const WSRect & rect)3727 void Session::SetClientRect(const WSRect& rect)
3728 {
3729     layoutController_->SetClientRect(rect);
3730 }
3731 
3732 /** @note @window.layout */
GetClientRect() const3733 WSRect Session::GetClientRect() const
3734 {
3735     return layoutController_->GetClientRect();
3736 }
3737 
SetHidingStartingWindow(bool hidingStartWindow)3738 WSError Session::SetHidingStartingWindow(bool hidingStartWindow)
3739 {
3740     hidingStartWindow_ = hidingStartWindow;
3741     auto leashSurfaceNode = GetLeashWinSurfaceNode();
3742     if (leashSurfaceNode == nullptr) {
3743         TLOGI(WmsLogTag::WMS_PATTERN, "no leashWindow: %{public}d", hidingStartWindow);
3744         return WSError::WS_ERROR_NULLPTR;
3745     }
3746     TLOGI(WmsLogTag::WMS_PATTERN, "hidingStartWindow: %{public}d", hidingStartWindow);
3747     hidingStartWindow ? leashSurfaceNode->SetAlpha(0) : leashSurfaceNode->SetAlpha(1);
3748     SetTouchable(!hidingStartWindow);
3749     return WSError::WS_OK;
3750 }
3751 
GetHidingStartingWindow() const3752 bool Session::GetHidingStartingWindow() const
3753 {
3754     return hidingStartWindow_;
3755 }
3756 
SetEnableRemoveStartingWindow(bool enableRemoveStartingWindow)3757 void Session::SetEnableRemoveStartingWindow(bool enableRemoveStartingWindow)
3758 {
3759     enableRemoveStartingWindow_ = enableRemoveStartingWindow;
3760 }
3761 
GetEnableRemoveStartingWindow() const3762 bool Session::GetEnableRemoveStartingWindow() const
3763 {
3764     return enableRemoveStartingWindow_;
3765 }
3766 
SetAppBufferReady(bool appBufferReady)3767 void Session::SetAppBufferReady(bool appBufferReady)
3768 {
3769     appBufferReady_ = appBufferReady;
3770 }
3771 
GetAppBufferReady() const3772 bool Session::GetAppBufferReady() const
3773 {
3774     return appBufferReady_;
3775 }
3776 
SetUseStartingWindowAboveLocked(bool useStartingWindowAboveLocked)3777 void Session::SetUseStartingWindowAboveLocked(bool useStartingWindowAboveLocked)
3778 {
3779     useStartingWindowAboveLocked_ = useStartingWindowAboveLocked;
3780 }
3781 
UseStartingWindowAboveLocked() const3782 bool Session::UseStartingWindowAboveLocked() const
3783 {
3784     return useStartingWindowAboveLocked_;
3785 }
3786 
SetRequestRectAnimationConfig(const RectAnimationConfig & rectAnimationConfig)3787 void Session::SetRequestRectAnimationConfig(const RectAnimationConfig& rectAnimationConfig)
3788 {
3789     auto property = GetSessionProperty();
3790     if (property == nullptr) {
3791         TLOGE(WmsLogTag::WMS_LAYOUT, "id: %{public}d property is nullptr", persistentId_);
3792         return;
3793     }
3794     property->SetRectAnimationConfig(rectAnimationConfig);
3795     TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, animation duration: [%{public}u]", persistentId_,
3796         rectAnimationConfig.duration);
3797 }
3798 
GetRequestRectAnimationConfig() const3799 RectAnimationConfig Session::GetRequestRectAnimationConfig() const
3800 {
3801     RectAnimationConfig rectAnimationConfig;
3802     auto property = GetSessionProperty();
3803     if (property == nullptr) {
3804         TLOGE(WmsLogTag::WMS_LAYOUT, "id: %{public}d property is nullptr", persistentId_);
3805         return rectAnimationConfig;
3806     }
3807     rectAnimationConfig = property->GetRectAnimationConfig();
3808     TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, animation duration: [%{public}u]", persistentId_,
3809         rectAnimationConfig.duration);
3810     return rectAnimationConfig;
3811 }
3812 
GetWindowType() const3813 WindowType Session::GetWindowType() const
3814 {
3815     return GetSessionProperty()->GetWindowType();
3816 }
3817 
GetWindowName() const3818 std::string Session::GetWindowName() const
3819 {
3820     if (GetSessionInfo().isSystem_) {
3821         return GetSessionInfo().abilityName_;
3822     } else {
3823         return GetSessionProperty()->GetWindowName();
3824     }
3825 }
3826 
SetSystemConfig(const SystemSessionConfig & systemConfig)3827 void Session::SetSystemConfig(const SystemSessionConfig& systemConfig)
3828 {
3829     systemConfig_ = systemConfig;
3830 }
3831 
GetSystemConfig() const3832 SystemSessionConfig Session::GetSystemConfig() const
3833 {
3834     return systemConfig_;
3835 }
3836 
SetSnapshotScale(const float snapshotScale)3837 void Session::SetSnapshotScale(const float snapshotScale)
3838 {
3839     snapshotScale_ = snapshotScale;
3840 }
3841 
ProcessBackEvent()3842 WSError Session::ProcessBackEvent()
3843 {
3844     if (!IsSessionValid()) {
3845         TLOGW(WmsLogTag::WMS_EVENT, "Session is invalid, id: %{public}d state: %{public}u",
3846             GetPersistentId(), GetSessionState());
3847         return WSError::WS_ERROR_INVALID_SESSION;
3848     }
3849     if (!sessionStage_) {
3850         TLOGE(WmsLogTag::WMS_EVENT, "session stage is nullptr");
3851         return WSError::WS_ERROR_NULLPTR;
3852     }
3853     if (auto remoteObject = sessionStage_->AsObject();
3854         remoteObject && !remoteObject->IsProxyObject()) {
3855         PostExportTask([sessionStage = sessionStage_] {
3856             sessionStage->HandleBackEvent();
3857         });
3858         return WSError::WS_OK;
3859     }
3860     return sessionStage_->HandleBackEvent();
3861 }
3862 
GeneratePersistentId(bool isExtension,int32_t persistentId)3863 void Session::GeneratePersistentId(bool isExtension, int32_t persistentId)
3864 {
3865     std::lock_guard lock(g_persistentIdSetMutex);
3866     if (persistentId != INVALID_SESSION_ID  && !g_persistentIdSet.count(persistentId)) {
3867         g_persistentIdSet.insert(persistentId);
3868         persistentId_ = persistentId;
3869         return;
3870     }
3871 
3872     if (g_persistentId == INVALID_SESSION_ID) {
3873         g_persistentId++; // init non system session id from 2
3874     }
3875 
3876     g_persistentId++;
3877     while (g_persistentIdSet.count(g_persistentId)) {
3878         g_persistentId++;
3879     }
3880     if (isExtension) {
3881         constexpr uint32_t pidLength = 18;
3882         constexpr uint32_t pidMask = (1 << pidLength) - 1;
3883         constexpr uint32_t persistentIdLength = 12;
3884         constexpr uint32_t persistentIdMask = (1 << persistentIdLength) - 1;
3885         uint32_t assembledPersistentId = ((static_cast<uint32_t>(getpid()) & pidMask) << persistentIdLength) |
3886             (static_cast<uint32_t>(g_persistentId.load()) & persistentIdMask);
3887         persistentId_ = assembledPersistentId | 0x40000000;
3888     } else {
3889         persistentId_ = static_cast<uint32_t>(g_persistentId.load()) & 0x3fffffff;
3890     }
3891     g_persistentIdSet.insert(g_persistentId);
3892     TLOGI(WmsLogTag::WMS_LIFE,
3893         "persistentId: %{public}d, persistentId_: %{public}d", persistentId, persistentId_);
3894 }
3895 
GetScenePersistence() const3896 sptr<ScenePersistence> Session::GetScenePersistence() const
3897 {
3898     return scenePersistence_;
3899 }
3900 
CheckEmptyKeyboardAvoidAreaIfNeeded() const3901 bool Session::CheckEmptyKeyboardAvoidAreaIfNeeded() const
3902 {
3903     bool isMainFloating =
3904         GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && WindowHelper::IsMainWindow(GetWindowType());
3905     bool isParentFloating = SessionHelper::IsNonSecureToUIExtension(GetWindowType()) &&
3906         GetParentSession() != nullptr &&
3907         GetParentSession()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
3908     bool isMidScene = GetIsMidScene();
3909     bool isPhoneNotFreeMultiWindow = systemConfig_.IsPhoneWindow() && !systemConfig_.IsFreeMultiWindowMode();
3910     bool isPadNotFreeMultiWindow = systemConfig_.IsPadWindow() && !systemConfig_.IsFreeMultiWindowMode();
3911     bool isPhoneOrPadNotFreeMultiWindow = isPhoneNotFreeMultiWindow || isPadNotFreeMultiWindow;
3912     TLOGI(WmsLogTag::WMS_LIFE, "check keyboard avoid area, isPhoneNotFreeMultiWindow: %{public}d, "
3913         "isPadNotFreeMultiWindow: %{public}d", isPhoneNotFreeMultiWindow, isPadNotFreeMultiWindow);
3914     return (isMainFloating || isParentFloating) && !isMidScene && isPhoneOrPadNotFreeMultiWindow;
3915 }
3916 
SetKeyboardStateChangeListener(const NotifyKeyboardStateChangeFunc & func)3917 void Session::SetKeyboardStateChangeListener(const NotifyKeyboardStateChangeFunc& func)
3918 {
3919     PostTask([weakThis = wptr(this), func, where = __func__]() {
3920         auto session = weakThis.promote();
3921         if (session == nullptr || func == nullptr) {
3922             TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s session or func is null", where);
3923             return;
3924         }
3925         session->keyboardStateChangeFunc_ = func;
3926         auto newState = session->GetSessionState(); // read and write state should in one thread
3927         if (newState == SessionState::STATE_ACTIVE) {
3928             newState = SessionState::STATE_FOREGROUND;
3929         } else if (newState == SessionState::STATE_INACTIVE) {
3930             newState = SessionState::STATE_BACKGROUND;
3931         } else if (newState == SessionState::STATE_DISCONNECT) {
3932             return;
3933         }
3934         session->NotifySessionStateChange(newState);
3935         TLOGNI(WmsLogTag::WMS_KEYBOARD, "%{public}s id: %{public}d, state_: %{public}d, newState: %{public}d",
3936             where, session->GetPersistentId(), session->GetSessionState(), newState);
3937     }, __func__);
3938 }
3939 
NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,const std::shared_ptr<RSTransaction> & rsTransaction,const Rect & callingSessionRect,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)3940 void Session::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,
3941     const std::shared_ptr<RSTransaction>& rsTransaction, const Rect& callingSessionRect,
3942     const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
3943 {
3944     if (!sessionStage_) {
3945         TLOGD(WmsLogTag::WMS_KEYBOARD, "session stage is nullptr");
3946         return;
3947     }
3948     if (CheckEmptyKeyboardAvoidAreaIfNeeded()) {
3949         info = sptr<OccupiedAreaChangeInfo>::MakeSptr();
3950         TLOGD(WmsLogTag::WMS_KEYBOARD, "Occupied area needs to be empty when in floating mode");
3951     }
3952     if (info != nullptr) {
3953         TLOGI(WmsLogTag::WMS_KEYBOARD, "Calling id: %{public}d, callingSessionRect: %{public}s"
3954             ", safeRect: %{public}s, textFieldPositionY_: %{public}f, textFieldHeight_: %{public}f"
3955             ", size of avoidAreas: %{public}d", GetPersistentId(),
3956             callingSessionRect.ToString().c_str(), info->rect_.ToString().c_str(),
3957             info->textFieldPositionY_, info->textFieldHeight_, static_cast<int32_t>(avoidAreas.size()));
3958         for (const auto& [type, avoidArea] : avoidAreas) {
3959             TLOGI(WmsLogTag::WMS_KEYBOARD, "avoidAreaType: %{public}u, avoidArea: %{public}s",
3960                 type, avoidArea.ToString().c_str());
3961         }
3962     } else {
3963         TLOGI(WmsLogTag::WMS_KEYBOARD, "occupied area info is nullptr, id: %{public}d", GetPersistentId());
3964     }
3965     sessionStage_->NotifyOccupiedAreaChangeInfo(info, rsTransaction, callingSessionRect, avoidAreas);
3966 }
3967 
GetWindowMode() const3968 WindowMode Session::GetWindowMode() const
3969 {
3970     return GetSessionProperty()->GetWindowMode();
3971 }
3972 
UpdateMaximizeMode(bool isMaximize)3973 WSError Session::UpdateMaximizeMode(bool isMaximize)
3974 {
3975     WLOGFD("Session update maximize mode, isMaximize: %{public}d", isMaximize);
3976     if (!IsSessionValid()) {
3977         TLOGW(WmsLogTag::WMS_LAYOUT, "Session is invalid, id: %{public}d state: %{public}u",
3978             GetPersistentId(), GetSessionState());
3979         return WSError::WS_ERROR_INVALID_SESSION;
3980     }
3981     MaximizeMode mode = MaximizeMode::MODE_RECOVER;
3982     if (isMaximize) {
3983         mode = MaximizeMode::MODE_AVOID_SYSTEM_BAR;
3984     } else if (GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
3985         mode = MaximizeMode::MODE_FULL_FILL;
3986     }
3987     GetSessionProperty()->SetMaximizeMode(mode);
3988     if (!sessionStage_) {
3989         TLOGE(WmsLogTag::WMS_MAIN, "sessionStage_ is null");
3990         return WSError::WS_ERROR_NULLPTR;
3991     }
3992     return sessionStage_->UpdateMaximizeMode(mode);
3993 }
3994 
3995 /** @note @window.hierarchy */
SetZOrder(uint32_t zOrder)3996 void Session::SetZOrder(uint32_t zOrder)
3997 {
3998     lastZOrder_ = zOrder_;
3999     zOrder_ = zOrder;
4000     NotifySessionInfoChange();
4001 }
4002 
4003 /** @note @window.hierarchy */
GetZOrder() const4004 uint32_t Session::GetZOrder() const
4005 {
4006     return zOrder_;
4007 }
4008 
4009 /** @note @window.hierarchy */
GetLastZOrder() const4010 uint32_t Session::GetLastZOrder() const
4011 {
4012     return lastZOrder_;
4013 }
4014 
SetUINodeId(uint32_t uiNodeId)4015 void Session::SetUINodeId(uint32_t uiNodeId)
4016 {
4017     if (uiNodeId_ != 0 && uiNodeId != 0 && !IsSystemSession() && SessionPermission::IsBetaVersion()) {
4018         int32_t eventRet = HiSysEventWrite(
4019             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
4020             "REPEAT_SET_UI_NODE_ID",
4021             OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
4022             "PID", getpid(),
4023             "UID", getuid());
4024         TLOGE(WmsLogTag::WMS_LIFE, " SetUINodeId: Repeat set UINodeId ret:%{public}d", eventRet);
4025         return;
4026     }
4027     uiNodeId_ = uiNodeId;
4028 }
4029 
GetUINodeId() const4030 uint32_t Session::GetUINodeId() const
4031 {
4032     return uiNodeId_;
4033 }
4034 
SetShowRecent(bool showRecent)4035 void Session::SetShowRecent(bool showRecent)
4036 {
4037     TLOGI(WmsLogTag::WMS_MAIN, "in recents: %{public}d, id: %{public}d", showRecent, persistentId_);
4038     bool isAttach = GetAttachState();
4039     if (!IsSupportDetectWindow(isAttach) ||
4040         !ShouldCreateDetectTaskInRecent(showRecent, showRecent_, isAttach)) {
4041         showRecent_ = showRecent;
4042         return;
4043     }
4044     showRecent_ = showRecent;
4045     WindowMode windowMode = GetWindowMode();
4046     if (!showRecent_ && ShouldCreateDetectTask(isAttach, windowMode)) {
4047         CreateWindowStateDetectTask(isAttach, windowMode);
4048     }
4049 }
4050 
GetShowRecent() const4051 bool Session::GetShowRecent() const
4052 {
4053     return showRecent_;
4054 }
4055 
GetAttachState() const4056 bool Session::GetAttachState() const
4057 {
4058     return isAttach_;
4059 }
4060 
GetDetectTaskInfo() const4061 DetectTaskInfo Session::GetDetectTaskInfo() const
4062 {
4063     std::shared_lock<std::shared_mutex> lock(detectTaskInfoMutex_);
4064     return detectTaskInfo_;
4065 }
4066 
SetDetectTaskInfo(const DetectTaskInfo & detectTaskInfo)4067 void Session::SetDetectTaskInfo(const DetectTaskInfo& detectTaskInfo)
4068 {
4069     std::unique_lock<std::shared_mutex> lock(detectTaskInfoMutex_);
4070     detectTaskInfo_ = detectTaskInfo;
4071 }
4072 
IsStateMatch(bool isAttach) const4073 bool Session::IsStateMatch(bool isAttach) const
4074 {
4075     return isAttach ? ATTACH_MAP.at(GetSessionState()) : DETACH_MAP.at(GetSessionState());
4076 }
4077 
IsSupportDetectWindow(bool isAttach)4078 bool Session::IsSupportDetectWindow(bool isAttach)
4079 {
4080     if (!systemConfig_.IsPcWindow() && !systemConfig_.IsPhoneWindow()) {
4081         TLOGD(WmsLogTag::WMS_LIFE, "device type not support, id:%{public}d", persistentId_);
4082         return false;
4083     }
4084     if (isScreenLockedCallback_ && isScreenLockedCallback_()) {
4085         TLOGD(WmsLogTag::WMS_LIFE, "screen locked, id:%{public}d", persistentId_);
4086         return false;
4087     }
4088     if (!SessionHelper::IsMainWindow(GetWindowType())) {
4089         TLOGD(WmsLogTag::WMS_LIFE, "only support main window, id:%{public}d", persistentId_);
4090         return false;
4091     }
4092     // Only detecting cold start scenarios on PC
4093     if (systemConfig_.IsPcWindow() && (!isAttach || state_ != SessionState::STATE_DISCONNECT)) {
4094         TLOGD(WmsLogTag::WMS_LIFE, "pc only support cold start, id:%{public}d", persistentId_);
4095         RemoveWindowDetectTask();
4096         return false;
4097     }
4098     return true;
4099 }
4100 
RemoveWindowDetectTask()4101 void Session::RemoveWindowDetectTask()
4102 {
4103     if (handler_) {
4104         handler_->RemoveTask(GetWindowDetectTaskName());
4105     }
4106 }
4107 
ShouldCreateDetectTask(bool isAttach,WindowMode windowMode) const4108 bool Session::ShouldCreateDetectTask(bool isAttach, WindowMode windowMode) const
4109 {
4110     // Create detect task directy without pre-exiting tasks.
4111     if (GetDetectTaskInfo().taskState == DetectTaskState::NO_TASK) {
4112         return true;
4113     }
4114     // If the taskState matches the attach detach state, it will be create detect task directly.
4115     if ((GetDetectTaskInfo().taskState == DetectTaskState::ATTACH_TASK && isAttach) ||
4116         (GetDetectTaskInfo().taskState == DetectTaskState::DETACH_TASK && !isAttach)) {
4117         return true;
4118     } else {
4119         // Do not create detect task if the windowMode changes.
4120         return GetDetectTaskInfo().taskWindowMode == windowMode;
4121     }
4122 }
4123 
ShouldCreateDetectTaskInRecent(bool newShowRecent,bool oldShowRecent,bool isAttach) const4124 bool Session::ShouldCreateDetectTaskInRecent(bool newShowRecent, bool oldShowRecent, bool isAttach) const
4125 {
4126     if (newShowRecent) {
4127         return false;
4128     }
4129     return oldShowRecent ? isAttach : false;
4130 }
4131 
RegisterIsScreenLockedCallback(const std::function<bool ()> & callback)4132 void Session::RegisterIsScreenLockedCallback(const std::function<bool()>& callback)
4133 {
4134     isScreenLockedCallback_ = callback;
4135 }
4136 
GetWindowDetectTaskName() const4137 std::string Session::GetWindowDetectTaskName() const
4138 {
4139     return "wms:WindowStateDetect" + std::to_string(persistentId_);
4140 }
4141 
RecordWindowStateAttachExceptionEvent(bool isAttached)4142 void Session::RecordWindowStateAttachExceptionEvent(bool isAttached)
4143 {
4144     int32_t ret = HiSysEventWrite(
4145         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
4146         "WINDOW_STATE_ERROR",
4147         OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
4148         "TYPE", "WINDOW_STATE_ATTACH_EXCEPTION",
4149         "PERSISTENT_ID", GetPersistentId(),
4150         "WINDOW_NAME", GetWindowName().c_str(),
4151         "ATTACH_STATE", isAttached,
4152         "SESSION_STATE", static_cast<uint32_t>(GetSessionState()));
4153     if (ret != 0) {
4154         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
4155     }
4156 }
4157 
CreateWindowStateDetectTask(bool isAttach,WindowMode windowMode)4158 void Session::CreateWindowStateDetectTask(bool isAttach, WindowMode windowMode)
4159 {
4160     if (!handler_) {
4161         return;
4162     }
4163     std::string taskName = GetWindowDetectTaskName();
4164     RemoveWindowDetectTask();
4165     auto detectTask = [weakThis = wptr(this), isAttach]() {
4166         auto session = weakThis.promote();
4167         if (session == nullptr) {
4168             if (isAttach) {
4169                 TLOGNE(WmsLogTag::WMS_LIFE, "Window attach state and session"
4170                     "state mismatch, session is nullptr, attach:%{public}d", isAttach);
4171             }
4172             return;
4173         }
4174         // Skip state detect when screen locked.
4175         if (session->isScreenLockedCallback_ && !session->isScreenLockedCallback_()) {
4176             if (!session->IsStateMatch(isAttach)) {
4177                 TLOGNE(WmsLogTag::WMS_LIFE, "Window attach state and session state mismatch, "
4178                     "attach:%{public}d, sessioniState:%{public}d, persistenId:%{public}d, bundleName:%{public}s",
4179                     isAttach, static_cast<uint32_t>(session->GetSessionState()),
4180                     session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str());
4181                 session->RecordWindowStateAttachExceptionEvent(isAttach);
4182             }
4183         }
4184         DetectTaskInfo detectTaskInfo;
4185         session->SetDetectTaskInfo(detectTaskInfo);
4186     };
4187     handler_->PostTask(detectTask, taskName, STATE_DETECT_DELAYTIME);
4188     DetectTaskInfo detectTaskInfo;
4189     detectTaskInfo.taskWindowMode = windowMode;
4190     detectTaskInfo.taskState = isAttach ? DetectTaskState::ATTACH_TASK : DetectTaskState::DETACH_TASK;
4191     SetDetectTaskInfo(detectTaskInfo);
4192 }
4193 
SetBufferAvailable(bool bufferAvailable,bool startWindowInvisible)4194 void Session::SetBufferAvailable(bool bufferAvailable, bool startWindowInvisible)
4195 {
4196     TLOGD(WmsLogTag::DEFAULT, "Set:%{public}d %{public}d", bufferAvailable, startWindowInvisible);
4197     if (bufferAvailableChangeFunc_) {
4198         bufferAvailableChangeFunc_(bufferAvailable, startWindowInvisible);
4199     }
4200     bufferAvailable_ = bufferAvailable;
4201 }
4202 
GetBufferAvailable() const4203 bool Session::GetBufferAvailable() const
4204 {
4205     return bufferAvailable_;
4206 }
4207 
SetNeedSnapshot(bool needSnapshot)4208 void Session::SetNeedSnapshot(bool needSnapshot)
4209 {
4210     needSnapshot_ = needSnapshot;
4211 }
4212 
SetExitSplitOnBackground(bool isExitSplitOnBackground)4213 void Session::SetExitSplitOnBackground(bool isExitSplitOnBackground)
4214 {
4215     TLOGW(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, SetExitSplitOnBackground not implement", persistentId_);
4216 }
4217 
IsExitSplitOnBackground() const4218 bool Session::IsExitSplitOnBackground() const
4219 {
4220     TLOGW(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, IsExitSplitOnBackground not implement", persistentId_);
4221     return false;
4222 }
4223 
SetFloatingScale(float floatingScale)4224 void Session::SetFloatingScale(float floatingScale)
4225 {
4226     floatingScale_ = floatingScale;
4227 }
4228 
GetFloatingScale() const4229 float Session::GetFloatingScale() const
4230 {
4231     return floatingScale_;
4232 }
4233 
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)4234 void Session::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
4235 {
4236     layoutController_->SetScale(scaleX, scaleY, pivotX, pivotY);
4237 }
4238 
SetClientScale(float scaleX,float scaleY,float pivotX,float pivotY)4239 void Session::SetClientScale(float scaleX, float scaleY, float pivotX, float pivotY)
4240 {
4241     layoutController_->SetClientScale(scaleX, scaleY, pivotX, pivotY);
4242 }
4243 
GetScaleX() const4244 float Session::GetScaleX() const
4245 {
4246     return layoutController_->GetScaleX();
4247 }
4248 
GetScaleY() const4249 float Session::GetScaleY() const
4250 {
4251     return layoutController_->GetScaleY();
4252 }
4253 
GetPivotX() const4254 float Session::GetPivotX() const
4255 {
4256     return layoutController_->GetPivotX();
4257 }
4258 
GetPivotY() const4259 float Session::GetPivotY() const
4260 {
4261     return layoutController_->GetPivotY();
4262 }
4263 
SetSCBKeepKeyboard(bool scbKeepKeyboardFlag)4264 void Session::SetSCBKeepKeyboard(bool scbKeepKeyboardFlag)
4265 {
4266     scbKeepKeyboardFlag_ = scbKeepKeyboardFlag;
4267 }
4268 
GetSCBKeepKeyboardFlag() const4269 bool Session::GetSCBKeepKeyboardFlag() const
4270 {
4271     return scbKeepKeyboardFlag_;
4272 }
4273 
SetOffset(float x,float y)4274 void Session::SetOffset(float x, float y)
4275 {
4276     offsetX_ = x;
4277     offsetY_ = y;
4278     WSRect newRect {
4279         .posX_ = std::round(bounds_.posX_ + x),
4280         .posY_ = std::round(bounds_.posY_ + y),
4281         .width_ = std::round(bounds_.width_),
4282         .height_ = std::round(bounds_.height_),
4283     };
4284     if (newRect != GetSessionRect()) {
4285         UpdateRect(newRect, SizeChangeReason::UNDEFINED, "SetOffset");
4286     }
4287 }
4288 
GetOffsetX() const4289 float Session::GetOffsetX() const
4290 {
4291     return offsetX_;
4292 }
4293 
GetOffsetY() const4294 float Session::GetOffsetY() const
4295 {
4296     return offsetY_;
4297 }
4298 
SetBounds(const WSRectF & bounds)4299 void Session::SetBounds(const WSRectF& bounds)
4300 {
4301     bounds_ = bounds;
4302 }
4303 
GetBounds()4304 WSRectF Session::GetBounds()
4305 {
4306     return bounds_;
4307 }
4308 
SetRotation(Rotation rotation)4309 void Session::SetRotation(Rotation rotation)
4310 {
4311     rotation_ = rotation;
4312 }
4313 
GetRotation() const4314 Rotation Session::GetRotation() const
4315 {
4316     return rotation_;
4317 }
4318 
UpdateTitleInTargetPos(bool isShow,int32_t height)4319 WSError Session::UpdateTitleInTargetPos(bool isShow, int32_t height)
4320 {
4321     WLOGFD("Session update title in target position, id: %{public}d, isShow: %{public}d, height: %{public}d",
4322         GetPersistentId(), isShow, height);
4323     if (!IsSessionValid()) {
4324         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
4325             GetPersistentId(), GetSessionState());
4326         return WSError::WS_ERROR_INVALID_SESSION;
4327     }
4328     if (!sessionStage_) {
4329         TLOGE(WmsLogTag::WMS_MAIN, "sessionStage_ is null");
4330         return WSError::WS_ERROR_NULLPTR;
4331     }
4332     return sessionStage_->UpdateTitleInTargetPos(isShow, height);
4333 }
4334 
SetSessionInfoLockedStateChangeListener(const NotifySessionInfoLockedStateChangeFunc & func)4335 void Session::SetSessionInfoLockedStateChangeListener(const NotifySessionInfoLockedStateChangeFunc& func)
4336 {
4337     sessionInfoLockedStateChangeFunc_ = func;
4338 }
4339 
NotifySessionInfoLockedStateChange(bool lockedState)4340 void Session::NotifySessionInfoLockedStateChange(bool lockedState)
4341 {
4342     WLOGFD("Notify sessioninfo lockedstate change: %{public}u", lockedState);
4343     if (sessionInfoLockedStateChangeFunc_) {
4344         sessionInfoLockedStateChangeFunc_(lockedState);
4345     }
4346 }
4347 
ExtractSupportWindowModeFromMetaData(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)4348 std::vector<AppExecFwk::SupportWindowMode> Session::ExtractSupportWindowModeFromMetaData(
4349     const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
4350 {
4351     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
4352     if (abilityInfo == nullptr) {
4353         TLOGE(WmsLogTag::WMS_LAYOUT, "id: %{public}d, abilityInfo is nullptr", GetPersistentId());
4354         return updateWindowModes;
4355     }
4356     if (IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) {
4357         auto metadata = abilityInfo->metadata;
4358         for (const auto& item : metadata) {
4359             if (item.name == "ohos.ability.window.supportWindowModeInFreeMultiWindow") {
4360                 updateWindowModes = ParseWindowModeFromMetaData(item.value);
4361                 return updateWindowModes;
4362             }
4363         }
4364     }
4365     if (updateWindowModes.empty()) {
4366         updateWindowModes = abilityInfo->windowModes;
4367     }
4368     return updateWindowModes;
4369 }
4370 
ParseWindowModeFromMetaData(const std::string & supportModesInFreeMultiWindow)4371 std::vector<AppExecFwk::SupportWindowMode> Session::ParseWindowModeFromMetaData(
4372     const std::string& supportModesInFreeMultiWindow)
4373 {
4374     static const std::unordered_map<std::string, AppExecFwk::SupportWindowMode> modeMap = {
4375         {"fullscreen", AppExecFwk::SupportWindowMode::FULLSCREEN},
4376         {"split", AppExecFwk::SupportWindowMode::SPLIT},
4377         {"floating", AppExecFwk::SupportWindowMode::FLOATING}
4378     };
4379     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
4380     for (auto iter : modeMap) {
4381         if (supportModesInFreeMultiWindow.find(iter.first) != std::string::npos) {
4382             updateWindowModes.push_back(iter.second);
4383         }
4384     }
4385     return updateWindowModes;
4386 }
4387 
SwitchFreeMultiWindow(const SystemSessionConfig & config)4388 WSError Session::SwitchFreeMultiWindow(const SystemSessionConfig& config)
4389 {
4390     bool enable = config.freeMultiWindowEnable_;
4391     systemConfig_.defaultWindowMode_ = config.defaultWindowMode_;
4392     systemConfig_.freeMultiWindowEnable_ = enable;
4393     if (!IsSessionValid()) {
4394         TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Session is invalid, id: %{public}d state: %{public}u",
4395             GetPersistentId(), GetSessionState());
4396         return WSError::WS_ERROR_INVALID_SESSION;
4397     }
4398     if (!sessionStage_) {
4399         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionStage_ is null");
4400         return WSError::WS_ERROR_NULLPTR;
4401     }
4402     if (!UpdateWindowModeSupportType(sessionInfo_.abilityInfo)) {
4403         TLOGW(WmsLogTag::WMS_LAYOUT, "not update WindowModeSupportType");
4404     }
4405     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "windowId: %{public}d enable: %{public}d defaultWindowMode: %{public}d",
4406         GetPersistentId(), enable, systemConfig_.defaultWindowMode_);
4407     bool isUiExtSubWindow = WindowHelper::IsSubWindow(GetSessionProperty()->GetWindowType()) &&
4408         GetSessionProperty()->GetIsUIExtFirstSubWindow();
4409     if (WindowHelper::IsMainWindow(GetWindowType()) || isUiExtSubWindow) {
4410         return sessionStage_->SwitchFreeMultiWindow(enable);
4411     }
4412     return WSError::WS_OK;
4413 }
4414 
GetIsMidScene(bool & isMidScene)4415 WSError Session::GetIsMidScene(bool& isMidScene)
4416 {
4417     isMidScene = GetIsMidScene();
4418     return WSError::WS_OK;
4419 }
4420 
GetUIContentRemoteObj(sptr<IRemoteObject> & uiContentRemoteObj)4421 WSError Session::GetUIContentRemoteObj(sptr<IRemoteObject>& uiContentRemoteObj)
4422 {
4423     if (!IsSessionValid()) {
4424         TLOGE(WmsLogTag::DEFAULT, "session %{public}d is invalid. Failed to get UIContentRemoteObj", GetPersistentId());
4425         return WSError::WS_ERROR_INVALID_SESSION;
4426     }
4427     if (sessionStage_ == nullptr) {
4428         TLOGE(WmsLogTag::DEFAULT, "sessionStage_ is nullptr");
4429         return WSError::WS_ERROR_NULLPTR;
4430     }
4431     return sessionStage_->GetUIContentRemoteObj(uiContentRemoteObj);
4432 }
4433 
SetNotifySystemSessionPointerEventFunc(const NotifySystemSessionPointerEventFunc & func)4434 void Session::SetNotifySystemSessionPointerEventFunc(const NotifySystemSessionPointerEventFunc& func)
4435 {
4436     std::lock_guard<std::mutex> lock(pointerEventMutex_);
4437     systemSessionPointerEventFunc_ = func;
4438 }
4439 
SetNotifySystemSessionKeyEventFunc(const NotifySystemSessionKeyEventFunc & func)4440 void Session::SetNotifySystemSessionKeyEventFunc(const NotifySystemSessionKeyEventFunc& func)
4441 {
4442     std::unique_lock<std::shared_mutex> lock(keyEventMutex_);
4443     systemSessionKeyEventFunc_ = func;
4444 }
4445 
NotifySessionInfoChange()4446 void Session::NotifySessionInfoChange()
4447 {
4448     if (sessionInfoChangeNotifyManagerFunc_) {
4449         sessionInfoChangeNotifyManagerFunc_(GetPersistentId());
4450     } else {
4451         TLOGD(WmsLogTag::WMS_EVENT, "sessionInfoChangeNotifyManagerFunc is nullptr");
4452     }
4453 }
4454 
NotifySessionPropertyChange(WindowInfoKey windowInfoKey)4455 void Session::NotifySessionPropertyChange(WindowInfoKey windowInfoKey)
4456 {
4457     if (sessionPropertyChangeNotifyManagerFunc_) {
4458         sessionPropertyChangeNotifyManagerFunc_(GetPersistentId(), windowInfoKey);
4459     } else {
4460         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Func is invalid");
4461     }
4462 }
4463 
NotifyDisplayIdChanged(int32_t persistentId,uint64_t displayId)4464 void Session::NotifyDisplayIdChanged(int32_t persistentId, uint64_t displayId)
4465 {
4466     if (displayIdChangedNotifyManagerFunc_) {
4467         displayIdChangedNotifyManagerFunc_(persistentId, displayId);
4468     } else {
4469         TLOGE(WmsLogTag::WMS_KEYBOARD, "displayIdChangedNotifyManagerFunc is nullptr");
4470     }
4471 }
4472 
NeedCheckContextTransparent() const4473 bool Session::NeedCheckContextTransparent() const
4474 {
4475     return contextTransparentFunc_ != nullptr;
4476 }
4477 
SetContextTransparentFunc(const NotifyContextTransparentFunc & func)4478 void Session::SetContextTransparentFunc(const NotifyContextTransparentFunc& func)
4479 {
4480     contextTransparentFunc_ = func;
4481 }
4482 
NotifyContextTransparent()4483 void Session::NotifyContextTransparent()
4484 {
4485     if (contextTransparentFunc_) {
4486         int32_t eventRet = HiSysEventWrite(
4487             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
4488             "SESSION_IS_TRANSPARENT",
4489             OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
4490             "PERSISTENT_ID", GetPersistentId(),
4491             "BUNDLE_NAME", sessionInfo_.bundleName_);
4492         WLOGFE("Session context is transparent, persistentId:%{public}d, eventRet:%{public}d",
4493             GetPersistentId(), eventRet);
4494         contextTransparentFunc_();
4495     }
4496 }
4497 
IsSystemInput()4498 bool Session::IsSystemInput()
4499 {
4500     return sessionInfo_.sceneType_ == SceneType::INPUT_SCENE;
4501 }
4502 
SetIsMidScene(bool isMidScene)4503 void Session::SetIsMidScene(bool isMidScene)
4504 {
4505     PostTask([weakThis = wptr(this), isMidScene] {
4506         auto session = weakThis.promote();
4507         if (session == nullptr) {
4508             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "session is null");
4509             return;
4510         }
4511         if (session->isMidScene_ != isMidScene) {
4512             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "persistentId:%{public}d, isMidScene:%{public}d",
4513                 session->GetPersistentId(), isMidScene);
4514             session->isMidScene_ = isMidScene;
4515         }
4516     }, "SetIsMidScene");
4517 }
4518 
GetIsMidScene() const4519 bool Session::GetIsMidScene() const
4520 {
4521     return isMidScene_;
4522 }
4523 
SetTouchHotAreas(const std::vector<Rect> & touchHotAreas)4524 void Session::SetTouchHotAreas(const std::vector<Rect>& touchHotAreas)
4525 {
4526     std::vector<Rect> lastTouchHotAreas;
4527     GetSessionProperty()->GetTouchHotAreas(lastTouchHotAreas);
4528     if (touchHotAreas == lastTouchHotAreas) {
4529         return;
4530     }
4531 
4532     dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::TOUCH_HOT_AREA);
4533     std::string rectStr;
4534     for (const auto& rect : touchHotAreas) {
4535         rectStr = rectStr + " " + rect.ToString();
4536     }
4537     TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d hot:%{public}s", GetPersistentId(), rectStr.c_str());
4538     GetSessionProperty()->SetTouchHotAreas(touchHotAreas);
4539 }
4540 
GetSnapshotPixelMap(const float oriScale,const float newScale)4541 std::shared_ptr<Media::PixelMap> Session::GetSnapshotPixelMap(const float oriScale, const float newScale)
4542 {
4543     TLOGI(WmsLogTag::WMS_MAIN, "id %{public}d", GetPersistentId());
4544     if (scenePersistence_ == nullptr) {
4545         return nullptr;
4546     }
4547     auto key = GetWindowStatus();
4548     return scenePersistence_->IsSavingSnapshot(key, freeMultiWindow_.load()) ? GetSnapshot() :
4549         scenePersistence_->GetLocalSnapshotPixelMap(oriScale, newScale, key, freeMultiWindow_.load());
4550 }
4551 
IsVisibleForeground() const4552 bool Session::IsVisibleForeground() const
4553 {
4554     return isVisible_ && IsSessionForeground();
4555 }
4556 
IsVisibleNotBackground() const4557 bool Session::IsVisibleNotBackground() const
4558 {
4559     return isVisible_ && IsSessionNotBackground();
4560 }
4561 
SetIsStarting(bool isStarting)4562 void Session::SetIsStarting(bool isStarting)
4563 {
4564     isStarting_ = isStarting;
4565 }
4566 
ResetDirtyFlags()4567 void Session::ResetDirtyFlags()
4568 {
4569     if (!isVisible_) {
4570         dirtyFlags_ &= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
4571     } else {
4572         dirtyFlags_ = 0;
4573     }
4574 }
4575 
SetUIStateDirty(bool dirty)4576 void Session::SetUIStateDirty(bool dirty)
4577 {
4578     mainUIStateDirty_.store(dirty);
4579 }
4580 
GetUIStateDirty() const4581 bool Session::GetUIStateDirty() const
4582 {
4583     return mainUIStateDirty_.load();
4584 }
4585 
SetMainSessionUIStateDirty(bool dirty)4586 void Session::SetMainSessionUIStateDirty(bool dirty)
4587 {
4588     if (GetParentSession() && WindowHelper::IsMainWindow(GetParentSession()->GetWindowType())) {
4589         GetParentSession()->SetUIStateDirty(dirty);
4590     }
4591 }
4592 
IsScbCoreEnabled()4593 bool Session::IsScbCoreEnabled()
4594 {
4595     return isScbCoreEnabled_;
4596 }
4597 
SetScbCoreEnabled(bool enabled)4598 void Session::SetScbCoreEnabled(bool enabled)
4599 {
4600     TLOGI(WmsLogTag::WMS_PIPELINE, "%{public}d", enabled);
4601     isScbCoreEnabled_ = enabled;
4602 }
4603 
IsBackgroundUpdateRectNotifyEnabled()4604 bool Session::IsBackgroundUpdateRectNotifyEnabled()
4605 {
4606     return isBackgroundUpdateRectNotifyEnabled_;
4607 }
4608 
SetBackgroundUpdateRectNotifyEnabled(const bool enabled)4609 void Session::SetBackgroundUpdateRectNotifyEnabled(const bool enabled)
4610 {
4611     TLOGI(WmsLogTag::WMS_LAYOUT, "%{public}d", enabled);
4612     isBackgroundUpdateRectNotifyEnabled_ = enabled;
4613 }
4614 
IsVisible() const4615 bool Session::IsVisible() const
4616 {
4617     return isVisible_;
4618 }
4619 
GetEventHandler() const4620 std::shared_ptr<AppExecFwk::EventHandler> Session::GetEventHandler() const
4621 {
4622     return handler_;
4623 }
4624 
SetFreezeImmediately(float scale,bool isFreeze,float blur) const4625 std::shared_ptr<Media::PixelMap> Session::SetFreezeImmediately(float scale, bool isFreeze, float blur) const
4626 {
4627     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "GetSnapshotWithFreeze[%d][%s]",
4628         persistentId_, sessionInfo_.bundleName_.c_str());
4629     auto surfaceNode = GetSurfaceNode();
4630     if (!surfaceNode || !surfaceNode->IsBufferAvailable()) {
4631         return nullptr;
4632     }
4633     auto callback = std::make_shared<SurfaceCaptureFuture>();
4634     auto scaleValue = (!MathHelper::GreatNotEqual(scale, 0.0f) ||
4635         !MathHelper::GreatNotEqual(scale, std::numeric_limits<float>::min())) ? snapshotScale_ : scale;
4636     bool isNeedF16WindowShot = system::GetBoolParameter("persist.sys.graphic.scrgb.enabled", false);
4637     RSSurfaceCaptureConfig config = {
4638         .scaleX = scaleValue,
4639         .scaleY = scaleValue,
4640         .useDma = true,
4641         .useCurWindow = true,
4642         .isHdrCapture = true,
4643         .needF16WindowCaptureForScRGB = isNeedF16WindowShot,
4644     };
4645     bool ret = RSInterfaces::GetInstance().SetWindowFreezeImmediately(surfaceNode, isFreeze, callback, config, blur);
4646     if (!ret) {
4647         TLOGE(WmsLogTag::WMS_PATTERN, "failed");
4648         return nullptr;
4649     }
4650     if (isFreeze) {
4651         auto pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT_MS);
4652         TLOGI(WmsLogTag::WMS_PATTERN, "get result: %{public}d, id: %{public}d", pixelMap != nullptr, persistentId_);
4653         return pixelMap;
4654     }
4655     return nullptr;
4656 }
4657 
IsPcWindow() const4658 bool Session::IsPcWindow() const
4659 {
4660     return systemConfig_.IsPcWindow();
4661 }
4662 
GetWindowUIInfoForWindowInfo() const4663 WindowUIInfo Session::GetWindowUIInfoForWindowInfo() const
4664 {
4665     WindowUIInfo windowUIInfo;
4666     windowUIInfo.visibilityState = GetVisibilityState();
4667     return windowUIInfo;
4668 }
4669 
GetWindowDisplayInfoForWindowInfo() const4670 WindowDisplayInfo Session::GetWindowDisplayInfoForWindowInfo() const
4671 {
4672     WindowDisplayInfo windowDisplayInfo;
4673     if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(GetSessionProperty()->GetDisplayId())) {
4674         WSRect sessionGlobalRect = GetSessionGlobalRect();
4675         windowDisplayInfo.displayId = TransformGlobalRectToRelativeRect(sessionGlobalRect);
4676     } else {
4677         windowDisplayInfo.displayId = GetSessionProperty()->GetDisplayId();
4678     }
4679     return windowDisplayInfo;
4680 }
4681 
GetWindowLayoutInfoForWindowInfo() const4682 WindowLayoutInfo Session::GetWindowLayoutInfoForWindowInfo() const
4683 {
4684     WindowLayoutInfo windowLayoutInfo;
4685     WSRect sessionGlobalRect = GetSessionGlobalRect();
4686     sessionGlobalRect.width_ *= GetScaleX();
4687     sessionGlobalRect.height_ *= GetScaleY();
4688     if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(GetSessionProperty()->GetDisplayId())) {
4689         TransformGlobalRectToRelativeRect(sessionGlobalRect);
4690     }
4691     windowLayoutInfo.rect = { sessionGlobalRect.posX_, sessionGlobalRect.posY_,
4692                               sessionGlobalRect.width_, sessionGlobalRect.height_};
4693     windowLayoutInfo.zOrder = GetZOrder();
4694     return windowLayoutInfo;
4695 }
4696 
GetWindowMetaInfoForWindowInfo() const4697 WindowMetaInfo Session::GetWindowMetaInfoForWindowInfo() const
4698 {
4699     WindowMetaInfo windowMetaInfo;
4700     windowMetaInfo.windowId = GetWindowId();
4701     if (GetSessionInfo().isSystem_) {
4702         windowMetaInfo.windowName = GetSessionInfo().abilityName_;
4703     } else {
4704         windowMetaInfo.windowName = GetSessionProperty()->GetWindowName();
4705     }
4706     windowMetaInfo.bundleName = GetSessionInfo().bundleName_;
4707     windowMetaInfo.abilityName = GetSessionInfo().abilityName_;
4708     windowMetaInfo.appIndex = GetSessionInfo().appIndex_;
4709     windowMetaInfo.pid = GetCallingPid();
4710     windowMetaInfo.windowType = GetWindowType();
4711     windowMetaInfo.windowMode = GetWindowMode();
4712     windowMetaInfo.isMidScene = GetIsMidScene();
4713     windowMetaInfo.isFocused = IsFocused();
4714     if (auto parentSession = GetParentSession()) {
4715         windowMetaInfo.parentWindowId = static_cast<uint32_t>(parentSession->GetWindowId());
4716     }
4717     if (auto surfaceNode = GetSurfaceNode()) {
4718         windowMetaInfo.surfaceNodeId = static_cast<uint64_t>(surfaceNode->GetId());
4719     }
4720     if (auto leashWinSurfaceNode = GetLeashWinSurfaceNode()) {
4721         windowMetaInfo.leashWinSurfaceNodeId = static_cast<uint64_t>(leashWinSurfaceNode->GetId());
4722     }
4723     auto property = GetSessionProperty();
4724     windowMetaInfo.isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
4725     return windowMetaInfo;
4726 }
4727 
GetClientDisplayId() const4728 DisplayId Session::GetClientDisplayId() const
4729 {
4730     return clientDisplayId_;
4731 }
4732 
SetClientDisplayId(DisplayId displayid)4733 void Session::SetClientDisplayId(DisplayId displayid)
4734 {
4735     clientDisplayId_ = displayid;
4736 }
4737 
SetDragStart(bool isDragStart)4738 void Session::SetDragStart(bool isDragStart)
4739 {
4740     isDragStart_ = isDragStart;
4741 }
4742 
SetBorderUnoccupied(bool borderUnoccupied)4743 void Session::SetBorderUnoccupied(bool borderUnoccupied)
4744 {
4745     TLOGI(WmsLogTag::WMS_PATTERN, "borderUnoccupied: %{public}d", borderUnoccupied);
4746     borderUnoccupied_ = borderUnoccupied;
4747 }
4748 
GetBorderUnoccupied() const4749 bool Session::GetBorderUnoccupied() const
4750 {
4751     return borderUnoccupied_;
4752 }
4753 
SetWindowAnimationDuration(int32_t duration)4754 void Session::SetWindowAnimationDuration(int32_t duration)
4755 {
4756     windowAnimationDuration_ = duration;
4757 }
4758 
IsNeedReportTimeout() const4759 bool Session::IsNeedReportTimeout() const
4760 {
4761     WindowType type = GetWindowType();
4762     return WindowHelper::IsSubWindow(type) || (WindowHelper::IsAboveSystemWindow(type) &&
4763         type != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && type != WindowType::WINDOW_TYPE_PANEL);
4764 }
4765 
PostSpecificSessionLifeCycleTimeoutTask(const std::string & eventName)4766 void Session::PostSpecificSessionLifeCycleTimeoutTask(const std::string& eventName)
4767 {
4768     const int32_t THRESHOLD = 20;
4769     if (!IsNeedReportTimeout()) {
4770         TLOGD(WmsLogTag::DEFAULT, "not specific window");
4771         return;
4772     }
4773     // if configured animation, don't report
4774     if (windowAnimationDuration_) {
4775         TLOGD(WmsLogTag::DEFAULT, "window configured animation, don't report");
4776         return;
4777     }
4778     if (!handler_) {
4779         TLOGE(WmsLogTag::DEFAULT, "handler is null");
4780         return;
4781     }
4782     handler_->RemoveTask(eventName == ATTACH_EVENT_NAME ?
4783         DETACH_EVENT_NAME : ATTACH_EVENT_NAME);
4784     auto task = [weakThis = wptr(this), eventName, where = __func__]() {
4785         auto session = weakThis.promote();
4786         if (!session) {
4787             TLOGNI(WmsLogTag::DEFAULT, "%{public}s, session is null.", where);
4788             return;
4789         }
4790         bool isAttach = session->GetAttachState();
4791         if ((isAttach && eventName == ATTACH_EVENT_NAME) ||
4792             (!isAttach && eventName == DETACH_EVENT_NAME)) {
4793             TLOGND(WmsLogTag::DEFAULT, "%{public}s, detached or attached in time", where);
4794             return;
4795         }
4796         WindowLifeCycleReportInfo reportInfo {
4797             session->GetSessionInfo().bundleName_,
4798             static_cast<int32_t>(session->GetPersistentId()),
4799             static_cast<int32_t>(session->GetWindowType()),
4800             static_cast<int32_t>(session->GetWindowMode()),
4801             static_cast<int32_t>(session->GetSessionProperty()->GetWindowFlags()),
4802             eventName
4803         };
4804         TLOGNI(WmsLogTag::DEFAULT, "%{public}s report msg: %{public}s", where, reportInfo.ToString().c_str());
4805         WindowInfoReporter::GetInstance().ReportSpecWindowLifeCycleChange(reportInfo);
4806     };
4807     PostTask(task, eventName, THRESHOLD);
4808 }
4809 
DeletePersistentImageFit()4810 void Session::DeletePersistentImageFit()
4811 {
4812     auto isPersistentImageFit = Rosen::ScenePersistentStorage::HasKey(
4813         "SetImageForRecent_" + std::to_string(GetPersistentId()), Rosen::ScenePersistentStorageType::MAXIMIZE_STATE);
4814     if (isPersistentImageFit) {
4815         TLOGI(WmsLogTag::WMS_PATTERN, "delete persistent ImageFit");
4816         Rosen::ScenePersistentStorage::Delete("SetImageForRecent_" + std::to_string(GetPersistentId()),
4817             Rosen::ScenePersistentStorageType::MAXIMIZE_STATE);
4818     }
4819 }
4820 
SetGlobalDisplayRect(const WSRect & rect)4821 void Session::SetGlobalDisplayRect(const WSRect& rect)
4822 {
4823     TLOGD(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, rect: %{public}s", GetPersistentId(), rect.ToString().c_str());
4824     GetSessionProperty()->SetGlobalDisplayRect(SessionHelper::TransferToRect(rect));
4825 }
4826 
GetGlobalDisplayRect() const4827 WSRect Session::GetGlobalDisplayRect() const
4828 {
4829     WSRect rect = SessionHelper::TransferToWSRect(GetSessionProperty()->GetGlobalDisplayRect());
4830     TLOGD(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, rect: %{public}s", GetPersistentId(), rect.ToString().c_str());
4831     return rect;
4832 }
4833 
UpdateGlobalDisplayRect(const WSRect & rect,SizeChangeReason reason)4834 WSError Session::UpdateGlobalDisplayRect(const WSRect& rect, SizeChangeReason reason)
4835 {
4836     const int32_t windowId = GetWindowId();
4837     TLOGD(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, rect: %{public}s, reason: %{public}u",
4838         windowId, rect.ToString().c_str(), reason);
4839     if (rect == GetGlobalDisplayRect() && reason == globalDisplayRectSizeChangeReason_) {
4840         TLOGD(WmsLogTag::WMS_LAYOUT,
4841             "No change in rect or reason, windowId: %{public}d, rect: %{public}s, reason: %{public}u",
4842             windowId, rect.ToString().c_str(), reason);
4843         return WSError::WS_DO_NOTHING;
4844     }
4845     SetGlobalDisplayRect(rect);
4846     globalDisplayRectSizeChangeReason_ = reason;
4847     NotifyClientToUpdateGlobalDisplayRect(rect, reason);
4848     return WSError::WS_OK;
4849 }
4850 
NotifyClientToUpdateGlobalDisplayRect(const WSRect & rect,SizeChangeReason reason)4851 WSError Session::NotifyClientToUpdateGlobalDisplayRect(const WSRect& rect, SizeChangeReason reason)
4852 {
4853     // Skip notifying client when the window is not in the foreground to avoid waking up
4854     // the application via IPC, which may cause unnecessary power consumption.
4855     if (!sessionStage_ || !IsSessionForeground()) {
4856         return WSError::WS_DO_NOTHING;
4857     }
4858     return sessionStage_->UpdateGlobalDisplayRectFromServer(rect, reason);
4859 }
4860 
GetRSUIContext(const char * caller)4861 std::shared_ptr<RSUIContext> Session::GetRSUIContext(const char* caller)
4862 {
4863     RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(nullptr);
4864     auto screenId = GetScreenId();
4865     if (screenIdOfRSUIContext_ != screenId) {
4866         // Note: For the window corresponding to UIExtAbility, RSUIContext cannot be obtained
4867         // directly here because its server side is not SceneBoard. The acquisition of RSUIContext
4868         // is deferred to the UIExtensionPattern::OnConnect(ui_extension_pattern.cpp) method,
4869         // as ArkUI knows the host window for this type of window.
4870         rsUIContext_ = ScreenSessionManagerClient::GetInstance().GetRSUIContext(screenId);
4871         screenIdOfRSUIContext_ = screenId;
4872     }
4873     TLOGD(WmsLogTag::WMS_SCB, "%{public}s: %{public}s, sessionId: %{public}d, screenId:%{public}" PRIu64,
4874           caller, RSAdapterUtil::RSUIContextToStr(rsUIContext_).c_str(), GetPersistentId(), screenId);
4875     return rsUIContext_;
4876 }
4877 } // namespace OHOS::Rosen