• 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 "ability_info.h"
19 #include "ability_start_setting.h"
20 #include "input_manager.h"
21 #include "ipc_skeleton.h"
22 #include "key_event.h"
23 #include "pointer_event.h"
24 #include <transaction/rs_interfaces.h>
25 #include <transaction/rs_transaction.h>
26 #include <ui/rs_surface_node.h>
27 #include "proxy/include/window_info.h"
28 
29 #include "common/include/session_permission.h"
30 #include "anr_manager.h"
31 #include "session_helper.h"
32 #include "surface_capture_future.h"
33 #include "util.h"
34 #include "window_helper.h"
35 #include "window_manager_hilog.h"
36 #include "parameters.h"
37 #include <hisysevent.h>
38 #include "hitrace_meter.h"
39 #include "screen_session_manager/include/screen_session_manager_client.h"
40 #include "session/host/include/ws_ffrt_helper.h"
41 #include "singleton_container.h"
42 #include "perform_reporter.h"
43 
44 namespace OHOS::Rosen {
45 namespace {
46 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "Session" };
47 std::atomic<int32_t> g_persistentId = INVALID_SESSION_ID;
48 std::set<int32_t> g_persistentIdSet;
49 std::mutex g_persistentIdSetMutex;
50 constexpr float INNER_BORDER_VP = 5.0f;
51 constexpr float OUTSIDE_BORDER_VP = 4.0f;
52 constexpr float INNER_ANGLE_VP = 16.0f;
53 constexpr uint32_t MAX_LIFE_CYCLE_TASK_IN_QUEUE = 15;
54 constexpr int64_t LIFE_CYCLE_TASK_EXPIRED_TIME_LIMIT = 350;
55 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
56 constexpr int64_t STATE_DETECT_DELAYTIME = 3 * 1000;
57 const std::string SHELL_BUNDLE_NAME = "com.huawei.shell_assistant";
58 const std::string SHELL_APP_IDENTIFIER = "5765880207854632823";
59 const std::map<SessionState, bool> ATTACH_MAP = {
60     { SessionState::STATE_DISCONNECT, false },
61     { SessionState::STATE_CONNECT, false },
62     { SessionState::STATE_FOREGROUND, true },
63     { SessionState::STATE_ACTIVE, true },
64     { SessionState::STATE_INACTIVE, false },
65     { SessionState::STATE_BACKGROUND, false },
66 };
67 const std::map<SessionState, bool> DETACH_MAP = {
68     { SessionState::STATE_DISCONNECT, true },
69     { SessionState::STATE_CONNECT, false },
70     { SessionState::STATE_FOREGROUND, false },
71     { SessionState::STATE_ACTIVE, false },
72     { SessionState::STATE_INACTIVE, true },
73     { SessionState::STATE_BACKGROUND, true },
74 };
75 } // namespace
76 
77 std::shared_ptr<AppExecFwk::EventHandler> Session::mainHandler_;
78 bool Session::isScbCoreEnabled_ = false;
79 
Session(const SessionInfo & info)80 Session::Session(const SessionInfo& info) : sessionInfo_(info)
81 {
82     property_ = new WindowSessionProperty();
83     property_->SetWindowType(static_cast<WindowType>(info.windowType_));
84     if (!mainHandler_) {
85         auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
86         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
87     }
88     using type = std::underlying_type_t<MMI::WindowArea>;
89     for (type area = static_cast<type>(MMI::WindowArea::FOCUS_ON_TOP);
90         area <= static_cast<type>(MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT); ++area) {
91         auto ret = windowAreas_.insert(
92             std::pair<MMI::WindowArea, WSRectF>(static_cast<MMI::WindowArea>(area), WSRectF()));
93         if (!ret.second) {
94             WLOGFE("Failed to insert area:%{public}d", area);
95         }
96     }
97 
98     if (info.want != nullptr) {
99         auto focusedOnShow = info.want->GetBoolParam(AAFwk::Want::PARAM_RESV_WINDOW_FOCUSED, true);
100         TLOGI(WmsLogTag::WMS_FOCUS, "focusedOnShow:%{public}d", focusedOnShow);
101         SetFocusedOnShow(focusedOnShow);
102     }
103 }
104 
~Session()105 Session::~Session()
106 {
107     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d", GetPersistentId());
108     if (mainHandler_) {
109         mainHandler_->PostTask([surfaceNode = std::move(surfaceNode_)]() mutable {
110             // do nothing
111         });
112     }
113 }
114 
SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> & handler,const std::shared_ptr<AppExecFwk::EventHandler> & exportHandler)115 void Session::SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler>& handler,
116     const std::shared_ptr<AppExecFwk::EventHandler>& exportHandler)
117 {
118     handler_ = handler;
119     exportHandler_ = exportHandler;
120 }
121 
PostTask(Task && task,const std::string & name,int64_t delayTime)122 void Session::PostTask(Task&& task, const std::string& name, int64_t delayTime)
123 {
124     if (!handler_ || handler_->GetEventRunner()->IsCurrentRunnerThread()) {
125         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
126         return task();
127     }
128     auto localTask = [task, name]() {
129         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
130         task();
131     };
132     handler_->PostTask(std::move(localTask), "wms:" + name, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
133 }
134 
PostExportTask(Task && task,const std::string & name,int64_t delayTime)135 void Session::PostExportTask(Task&& task, const std::string& name, int64_t delayTime)
136 {
137     if (!exportHandler_ || exportHandler_->GetEventRunner()->IsCurrentRunnerThread()) {
138         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
139         return task();
140     }
141     auto localTask = [task, name]() {
142         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "s:%s", name.c_str());
143         task();
144     };
145     exportHandler_->PostTask(std::move(localTask), "wms:" + name, delayTime,
146         AppExecFwk::EventQueue::Priority::IMMEDIATE);
147 }
148 
GetPersistentId() const149 int32_t Session::GetPersistentId() const
150 {
151     return persistentId_;
152 }
153 
GetSurfaceNode() const154 std::shared_ptr<RSSurfaceNode> Session::GetSurfaceNode() const
155 {
156     return surfaceNode_;
157 }
158 
SetLeashWinSurfaceNode(std::shared_ptr<RSSurfaceNode> leashWinSurfaceNode)159 void Session::SetLeashWinSurfaceNode(std::shared_ptr<RSSurfaceNode> leashWinSurfaceNode)
160 {
161     if (g_enableForceUIFirst) {
162         auto rsTransaction = RSTransactionProxy::GetInstance();
163         if (rsTransaction) {
164             rsTransaction->Begin();
165         }
166         if (!leashWinSurfaceNode && leashWinSurfaceNode_) {
167             leashWinSurfaceNode_->SetForceUIFirst(false);
168         }
169         if (rsTransaction) {
170             rsTransaction->Commit();
171         }
172     }
173     std::lock_guard<std::mutex> lock(leashWinSurfaceNodeMutex_);
174     leashWinSurfaceNode_ = leashWinSurfaceNode;
175 }
176 
SetFrameLayoutFinishListener(const NotifyFrameLayoutFinishFunc & func)177 void Session::SetFrameLayoutFinishListener(const NotifyFrameLayoutFinishFunc &func)
178 {
179     frameLayoutFinishFunc_ = func;
180 }
181 
GetLeashWinSurfaceNode() const182 std::shared_ptr<RSSurfaceNode> Session::GetLeashWinSurfaceNode() const
183 {
184     std::lock_guard<std::mutex> lock(leashWinSurfaceNodeMutex_);
185     return leashWinSurfaceNode_;
186 }
187 
GetSnapshot() const188 std::shared_ptr<Media::PixelMap> Session::GetSnapshot() const
189 {
190     std::lock_guard<std::mutex> lock(snapshotMutex_);
191     return snapshot_;
192 }
193 
SetSessionInfoAncoSceneState(int32_t ancoSceneState)194 void Session::SetSessionInfoAncoSceneState(int32_t ancoSceneState)
195 {
196     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
197     sessionInfo_.ancoSceneState = ancoSceneState;
198 }
199 
SetSessionInfoTime(const std::string & time)200 void Session::SetSessionInfoTime(const std::string& time)
201 {
202     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
203     sessionInfo_.time = time;
204 }
205 
SetSessionInfoAbilityInfo(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)206 void Session::SetSessionInfoAbilityInfo(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
207 {
208     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
209     sessionInfo_.abilityInfo = abilityInfo;
210 }
211 
SetSessionInfoWant(const std::shared_ptr<AAFwk::Want> & want)212 void Session::SetSessionInfoWant(const std::shared_ptr<AAFwk::Want>& want)
213 {
214     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
215     sessionInfo_.want = want;
216 }
217 
SetSessionInfoProcessOptions(const std::shared_ptr<AAFwk::ProcessOptions> & processOptions)218 void Session::SetSessionInfoProcessOptions(const std::shared_ptr<AAFwk::ProcessOptions>& processOptions)
219 {
220     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
221     sessionInfo_.processOptions = processOptions;
222 }
223 
ResetSessionInfoResultCode()224 void Session::ResetSessionInfoResultCode()
225 {
226     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
227     sessionInfo_.resultCode = -1; // -1: initial result code
228 }
229 
SetSessionInfoPersistentId(int32_t persistentId)230 void Session::SetSessionInfoPersistentId(int32_t persistentId)
231 {
232     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
233     sessionInfo_.persistentId_ = persistentId;
234 }
235 
SetSessionInfoCallerPersistentId(int32_t callerPersistentId)236 void Session::SetSessionInfoCallerPersistentId(int32_t callerPersistentId)
237 {
238     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
239     sessionInfo_.callerPersistentId_ = callerPersistentId;
240 }
241 
SetSessionInfoContinueState(ContinueState state)242 void Session::SetSessionInfoContinueState(ContinueState state)
243 {
244     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
245     sessionInfo_.continueState = state;
246 }
247 
SetSessionInfoLockedState(bool lockedState)248 void Session::SetSessionInfoLockedState(bool lockedState)
249 {
250     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
251     sessionInfo_.lockedState = lockedState;
252     NotifySessionInfoLockedStateChange(lockedState);
253 }
254 
SetSessionInfoIsClearSession(bool isClearSession)255 void Session::SetSessionInfoIsClearSession(bool isClearSession)
256 {
257     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
258     sessionInfo_.isClearSession = isClearSession;
259 }
260 
SetSessionInfoAffinity(std::string affinity)261 void Session::SetSessionInfoAffinity(std::string affinity)
262 {
263     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
264     sessionInfo_.sessionAffinity = affinity;
265 }
266 
GetCloseAbilityWantAndClean(AAFwk::Want & outWant)267 void Session::GetCloseAbilityWantAndClean(AAFwk::Want& outWant)
268 {
269     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
270     if (sessionInfo_.closeAbilityWant != nullptr) {
271         outWant = *sessionInfo_.closeAbilityWant;
272         sessionInfo_.closeAbilityWant = nullptr;
273     }
274 }
275 
SetSessionInfo(const SessionInfo & info)276 void Session::SetSessionInfo(const SessionInfo& info)
277 {
278     std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
279     sessionInfo_.want = info.want;
280     sessionInfo_.callerToken_ = info.callerToken_;
281     sessionInfo_.requestCode = info.requestCode;
282     sessionInfo_.callerPersistentId_ = info.callerPersistentId_;
283     sessionInfo_.callingTokenId_ = info.callingTokenId_;
284     sessionInfo_.uiAbilityId_ = info.uiAbilityId_;
285     sessionInfo_.startSetting = info.startSetting;
286     sessionInfo_.continueSessionId_ = info.continueSessionId_;
287     sessionInfo_.isAtomicService_ = info.isAtomicService_;
288     sessionInfo_.callState_ = info.callState_;
289 }
290 
SetScreenId(uint64_t screenId)291 void Session::SetScreenId(uint64_t screenId)
292 {
293     sessionInfo_.screenId_ = screenId;
294     if (sessionStage_) {
295         sessionStage_->UpdateDisplayId(screenId);
296     }
297 }
298 
SetScreenIdOnServer(uint64_t screenId)299 void Session::SetScreenIdOnServer(uint64_t screenId)
300 {
301     sessionInfo_.screenId_ = screenId;
302 }
303 
GetSessionInfo() const304 const SessionInfo& Session::GetSessionInfo() const
305 {
306     return sessionInfo_;
307 }
308 
RegisterLifecycleListener(const std::shared_ptr<ILifecycleListener> & listener)309 bool Session::RegisterLifecycleListener(const std::shared_ptr<ILifecycleListener>& listener)
310 {
311     return RegisterListenerLocked(lifecycleListeners_, listener);
312 }
313 
UnregisterLifecycleListener(const std::shared_ptr<ILifecycleListener> & listener)314 bool Session::UnregisterLifecycleListener(const std::shared_ptr<ILifecycleListener>& listener)
315 {
316     return UnregisterListenerLocked(lifecycleListeners_, listener);
317 }
318 
319 template<typename T>
RegisterListenerLocked(std::vector<std::shared_ptr<T>> & holder,const std::shared_ptr<T> & listener)320 bool Session::RegisterListenerLocked(std::vector<std::shared_ptr<T>>& holder, const std::shared_ptr<T>& listener)
321 {
322     if (listener == nullptr) {
323         WLOGFE("listener is nullptr");
324         return false;
325     }
326     std::lock_guard<std::recursive_mutex> lock(lifecycleListenersMutex_);
327     if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
328         WLOGFE("Listener already registered");
329         return false;
330     }
331     holder.emplace_back(listener);
332     return true;
333 }
334 
335 template<typename T>
UnregisterListenerLocked(std::vector<std::shared_ptr<T>> & holder,const std::shared_ptr<T> & listener)336 bool Session::UnregisterListenerLocked(std::vector<std::shared_ptr<T>>& holder, const std::shared_ptr<T>& listener)
337 {
338     if (listener == nullptr) {
339         WLOGFE("listener could not be null");
340         return false;
341     }
342     std::lock_guard<std::recursive_mutex> lock(lifecycleListenersMutex_);
343     holder.erase(std::remove_if(holder.begin(), holder.end(),
344         [listener](std::shared_ptr<T> registeredListener) { return registeredListener == listener; }),
345         holder.end());
346     return true;
347 }
348 
NotifyActivation()349 void Session::NotifyActivation()
350 {
351     auto lifecycleListeners = GetListeners<ILifecycleListener>();
352     for (auto& listener : lifecycleListeners) {
353         if (auto listenerPtr = listener.lock()) {
354             listenerPtr->OnActivation();
355         }
356     }
357 }
358 
NotifyConnect()359 void Session::NotifyConnect()
360 {
361     auto lifecycleListeners = GetListeners<ILifecycleListener>();
362     for (auto& listener : lifecycleListeners) {
363         if (auto listenerPtr = listener.lock()) {
364             listenerPtr->OnConnect();
365         }
366     }
367 }
368 
NotifyForeground()369 void Session::NotifyForeground()
370 {
371     auto lifecycleListeners = GetListeners<ILifecycleListener>();
372     for (auto& listener : lifecycleListeners) {
373         if (auto listenerPtr = listener.lock()) {
374             listenerPtr->OnForeground();
375         }
376     }
377 }
378 
NotifyBackground()379 void Session::NotifyBackground()
380 {
381     auto lifecycleListeners = GetListeners<ILifecycleListener>();
382     for (auto& listener : lifecycleListeners) {
383         if (auto listenerPtr = listener.lock()) {
384             listenerPtr->OnBackground();
385         }
386     }
387 }
388 
NotifyDisconnect()389 void Session::NotifyDisconnect()
390 {
391     auto lifecycleListeners = GetListeners<ILifecycleListener>();
392     for (auto& listener : lifecycleListeners) {
393         if (auto listenerPtr = listener.lock()) {
394             listenerPtr->OnDisconnect();
395         }
396     }
397 }
398 
NotifyLayoutFinished()399 void Session::NotifyLayoutFinished()
400 {
401     auto lifecycleListeners = GetListeners<ILifecycleListener>();
402     for (auto& listener : lifecycleListeners) {
403         if (auto listenerPtr = listener.lock()) {
404             listenerPtr->OnLayoutFinished();
405         }
406     }
407 }
408 
NotifyRemoveBlank()409 void Session::NotifyRemoveBlank()
410 {
411     auto lifecycleListeners = GetListeners<ILifecycleListener>();
412     for (auto& listener : lifecycleListeners) {
413         if (auto listenerPtr = listener.lock()) {
414             listenerPtr->OnRemoveBlank();
415         }
416     }
417 }
418 
NotifyExtensionDied()419 void Session::NotifyExtensionDied()
420 {
421     if (!SessionPermission::IsSystemCalling()) {
422         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
423         return;
424     }
425     TLOGI(WmsLogTag::WMS_UIEXT, "NotifyExtensionDied called in session(persistentId:%{public}d).", persistentId_);
426     auto lifecycleListeners = GetListeners<ILifecycleListener>();
427     for (auto& listener : lifecycleListeners) {
428         if (auto listenerPtr = listener.lock()) {
429             listenerPtr->OnExtensionDied();
430         }
431     }
432 }
433 
NotifyExtensionTimeout(int32_t errorCode)434 void Session::NotifyExtensionTimeout(int32_t errorCode)
435 {
436     if (!SessionPermission::IsSystemCalling()) {
437         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
438         return;
439     }
440     TLOGI(WmsLogTag::WMS_UIEXT, "NotifyExtensionTimeout(errorCode:%{public}d) in session(persistentId:%{public}d).",
441         errorCode, persistentId_);
442     auto lifecycleListeners = GetListeners<ILifecycleListener>();
443     for (auto& listener : lifecycleListeners) {
444         if (auto listenerPtr = listener.lock()) {
445             listenerPtr->OnExtensionTimeout(errorCode);
446         }
447     }
448 }
449 
NotifyTransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionIdLevel)450 void Session::NotifyTransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
451     int64_t uiExtensionIdLevel)
452 {
453     auto lifecycleListeners = GetListeners<ILifecycleListener>();
454     for (auto& listener : lifecycleListeners) {
455         if (auto listenerPtr = listener.lock()) {
456             listenerPtr->OnAccessibilityEvent(info, uiExtensionIdLevel);
457         }
458     }
459 }
460 
GetAspectRatio() const461 float Session::GetAspectRatio() const
462 {
463     return aspectRatio_;
464 }
465 
SetAspectRatio(float ratio)466 WSError Session::SetAspectRatio(float ratio)
467 {
468     aspectRatio_ = ratio;
469     return WSError::WS_OK;
470 }
471 
GetSessionState() const472 SessionState Session::GetSessionState() const
473 {
474     return state_;
475 }
476 
SetSessionState(SessionState state)477 void Session::SetSessionState(SessionState state)
478 {
479     if (state < SessionState::STATE_DISCONNECT || state > SessionState::STATE_END) {
480         WLOGFD("Invalid session state: %{public}u", state);
481         return;
482     }
483     state_ = state;
484     SetMainSessionUIStateDirty(true);
485 }
486 
UpdateSessionState(SessionState state)487 void Session::UpdateSessionState(SessionState state)
488 {
489     // Remove unexecuted detection tasks when the window state changes to background or destroyed.
490     if (state == SessionState::STATE_DISCONNECT ||
491         state == SessionState::STATE_INACTIVE ||
492         state == SessionState::STATE_BACKGROUND) {
493         RemoveWindowDetectTask();
494     }
495     /* The state will be set background first when destroy keyboard, there is no need to notify scb if the state is
496      * already background, which may cause performance deterioration.
497      */
498     if (GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && state == state_ &&
499         state == SessionState::STATE_BACKGROUND) {
500         TLOGI(WmsLogTag::WMS_KEYBOARD, "Keyboard is already hide");
501         return;
502     }
503     state_ = state;
504     SetMainSessionUIStateDirty(true);
505     NotifySessionStateChange(state);
506 }
507 
UpdateSessionTouchable(bool touchable)508 void Session::UpdateSessionTouchable(bool touchable)
509 {
510     auto property = GetSessionProperty();
511     if (property == nullptr) {
512         TLOGE(WmsLogTag::WMS_EVENT, "property is null");
513         return;
514     }
515     property->SetTouchable(touchable);
516     NotifySessionTouchableChange(touchable);
517 }
518 
SetFocusable(bool isFocusable)519 WSError Session::SetFocusable(bool isFocusable)
520 {
521     WLOGFI("SetFocusable id: %{public}d, focusable: %{public}d", GetPersistentId(), isFocusable);
522     auto property = GetSessionProperty();
523     if (property == nullptr) {
524         TLOGE(WmsLogTag::WMS_EVENT, "property is null");
525         return WSError::WS_ERROR_NULLPTR;
526     }
527     property->SetFocusable(isFocusable);
528     if (isFocused_ && !GetFocusable()) {
529         FocusChangeReason reason = FocusChangeReason::FOCUSABLE;
530         NotifyRequestFocusStatusNotifyManager(false, true, reason);
531     }
532     return WSError::WS_OK;
533 }
534 
SetFocusableOnShow(bool isFocusableOnShow)535 WSError Session::SetFocusableOnShow(bool isFocusableOnShow)
536 {
537     auto task = [weakThis = wptr(this), isFocusableOnShow]() {
538         auto session = weakThis.promote();
539         if (session == nullptr) {
540             TLOGNE(WmsLogTag::WMS_FOCUS, "session is null");
541             return;
542         }
543         TLOGND(WmsLogTag::WMS_FOCUS, "id: %{public}d, focusableOnShow: %{public}d",
544             session->GetPersistentId(), isFocusableOnShow);
545         session->focusableOnShow_ = isFocusableOnShow;
546     };
547     PostTask(task, __func__);
548     return WSError::WS_OK;
549 }
550 
GetFocusable() const551 bool Session::GetFocusable() const
552 {
553     auto property = GetSessionProperty();
554     if (property) {
555         return property->GetFocusable();
556     }
557     WLOGFD("property is null");
558     return true;
559 }
560 
IsFocusableOnShow() const561 bool Session::IsFocusableOnShow() const
562 {
563     return focusableOnShow_;
564 }
565 
IsFocused() const566 bool Session::IsFocused() const
567 {
568     return isFocused_;
569 }
570 
SetNeedNotify(bool needNotify)571 void Session::SetNeedNotify(bool needNotify)
572 {
573     needNotify_ = needNotify;
574 }
575 
NeedNotify() const576 bool Session::NeedNotify() const
577 {
578     return needNotify_;
579 }
580 
SetFocusedOnShow(bool focusedOnShow)581 void Session::SetFocusedOnShow(bool focusedOnShow)
582 {
583     if (focusedOnShow == focusedOnShow_) {
584         return;
585     }
586     TLOGI(WmsLogTag::WMS_FOCUS, "SetFocusedOnShow:%{public}d, id: %{public}d", focusedOnShow, GetPersistentId());
587     focusedOnShow_ = focusedOnShow;
588 }
589 
IsFocusedOnShow() const590 bool Session::IsFocusedOnShow() const
591 {
592     TLOGD(WmsLogTag::WMS_FOCUS, "IsFocusedOnShow:%{public}d, id: %{public}d", focusedOnShow_, GetPersistentId());
593     return focusedOnShow_;
594 }
595 
SetStartingBeforeVisible(bool isStartingBeforeVisible)596 void Session::SetStartingBeforeVisible(bool isStartingBeforeVisible)
597 {
598     isStartingBeforeVisible_ = isStartingBeforeVisible;
599 }
600 
GetStartingBeforeVisible() const601 bool Session::GetStartingBeforeVisible() const
602 {
603     return isStartingBeforeVisible_;
604 }
605 
SetTouchable(bool touchable)606 WSError Session::SetTouchable(bool touchable)
607 {
608     SetSystemTouchable(touchable);
609     if (!IsSessionValid()) {
610         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
611             GetPersistentId(), GetSessionState());
612         return WSError::WS_ERROR_INVALID_SESSION;
613     }
614     if (touchable != GetSessionProperty()->GetTouchable()) {
615         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d touchable:%{public}d", GetPersistentId(),
616             static_cast<int>(touchable));
617     }
618     UpdateSessionTouchable(touchable);
619     return WSError::WS_OK;
620 }
621 
GetTouchable() const622 bool Session::GetTouchable() const
623 {
624     auto property = GetSessionProperty();
625     if (property) {
626         return property->GetTouchable();
627     }
628     TLOGE(WmsLogTag::WMS_EVENT, "property is null");
629     return true;
630 }
631 
SetForceTouchable(bool forceTouchable)632 void Session::SetForceTouchable(bool forceTouchable)
633 {
634     if (forceTouchable != forceTouchable_) {
635         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d forceTouchable:%{public}d", GetPersistentId(),
636             static_cast<int>(forceTouchable));
637     }
638     forceTouchable_ = forceTouchable;
639 }
640 
SetSystemTouchable(bool touchable)641 void Session::SetSystemTouchable(bool touchable)
642 {
643     if (touchable != systemTouchable_) {
644         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d systemTouchable_:%{public}d", GetPersistentId(),
645             static_cast<int>(touchable));
646     }
647     systemTouchable_ = touchable;
648     NotifySessionInfoChange();
649 }
650 
GetSystemTouchable() const651 bool Session::GetSystemTouchable() const
652 {
653     return forceTouchable_ && systemTouchable_ && GetTouchable();
654 }
655 
IsSystemActive() const656 bool Session::IsSystemActive() const
657 {
658     return isSystemActive_;
659 }
660 
SetSystemActive(bool systemActive)661 void Session::SetSystemActive(bool systemActive)
662 {
663     isSystemActive_ = systemActive;
664     NotifySessionInfoChange();
665 }
666 
SetRSVisible(bool isVisible)667 WSError Session::SetRSVisible(bool isVisible)
668 {
669     isRSVisible_ = isVisible;
670     return WSError::WS_OK;
671 }
672 
GetRSVisible() const673 bool Session::GetRSVisible() const
674 {
675     return isRSVisible_;
676 }
677 
GetFocused() const678 bool Session::GetFocused() const
679 {
680     return isFocused_;
681 }
682 
SetVisibilityState(WindowVisibilityState state)683 WSError Session::SetVisibilityState(WindowVisibilityState state)
684 {
685     visibilityState_ = state;
686     return WSError::WS_OK;
687 }
688 
GetVisibilityState() const689 WindowVisibilityState Session::GetVisibilityState() const
690 {
691     return visibilityState_;
692 }
693 
SetDrawingContentState(bool isRSDrawing)694 WSError Session::SetDrawingContentState(bool isRSDrawing)
695 {
696     isRSDrawing_ = isRSDrawing;
697     return WSError::WS_OK;
698 }
699 
GetDrawingContentState() const700 bool Session::GetDrawingContentState() const
701 {
702     return isRSDrawing_;
703 }
704 
GetWindowId() const705 int32_t Session::GetWindowId() const
706 {
707     return GetPersistentId();
708 }
709 
SetCallingPid(int32_t id)710 void Session::SetCallingPid(int32_t id)
711 {
712     TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, callingPid:%{public}u", persistentId_, id);
713     callingPid_ = id;
714 }
715 
SetCallingUid(int32_t id)716 void Session::SetCallingUid(int32_t id)
717 {
718     callingUid_ = id;
719 }
720 
GetCallingPid() const721 int32_t Session::GetCallingPid() const
722 {
723     return callingPid_;
724 }
725 
GetCallingUid() const726 int32_t Session::GetCallingUid() const
727 {
728     return callingUid_;
729 }
730 
SetAbilityToken(sptr<IRemoteObject> token)731 void Session::SetAbilityToken(sptr<IRemoteObject> token)
732 {
733     abilityToken_ = token;
734 }
735 
GetAbilityToken() const736 sptr<IRemoteObject> Session::GetAbilityToken() const
737 {
738     return abilityToken_;
739 }
740 
SetBrightness(float brightness)741 WSError Session::SetBrightness(float brightness)
742 {
743     auto property = GetSessionProperty();
744     if (!property) {
745         return WSError::WS_ERROR_NULLPTR;
746     }
747     property->SetBrightness(brightness);
748     return WSError::WS_OK;
749 }
750 
GetBrightness() const751 float Session::GetBrightness() const
752 {
753     auto property = GetSessionProperty();
754     if (!property) {
755         return UNDEFINED_BRIGHTNESS;
756     }
757     return property->GetBrightness();
758 }
759 
IsSessionValid() const760 bool Session::IsSessionValid() const
761 {
762     if (sessionInfo_.isSystem_) {
763         WLOGFD("session is system, id: %{public}d, name: %{public}s, state: %{public}u",
764             GetPersistentId(), sessionInfo_.bundleName_.c_str(), GetSessionState());
765         return false;
766     }
767     bool res = state_ > SessionState::STATE_DISCONNECT && state_ < SessionState::STATE_END;
768     return res;
769 }
770 
IsActive() const771 bool Session::IsActive() const
772 {
773     return isActive_;
774 }
775 
IsSystemSession() const776 bool Session::IsSystemSession() const
777 {
778     return sessionInfo_.isSystem_;
779 }
780 
IsTerminated() const781 bool Session::IsTerminated() const
782 {
783     return (GetSessionState() == SessionState::STATE_DISCONNECT || isTerminating_);
784 }
785 
IsSessionForeground() const786 bool Session::IsSessionForeground() const
787 {
788     return state_ == SessionState::STATE_FOREGROUND || state_ == SessionState::STATE_ACTIVE;
789 }
790 
SetPointerStyle(MMI::WindowArea area)791 WSError Session::SetPointerStyle(MMI::WindowArea area)
792 {
793     WLOGFI("Information to be set: pid:%{public}d, windowId:%{public}d, MMI::WindowArea:%{public}s",
794         callingPid_, persistentId_, DumpPointerWindowArea(area));
795     MMI::InputManager::GetInstance()->SetWindowPointerStyle(area, callingPid_, persistentId_);
796     return WSError::WS_OK;
797 }
798 
UpdateTopBottomArea(const WSRectF & rect,MMI::WindowArea area)799 WSRectF Session::UpdateTopBottomArea(const WSRectF& rect, MMI::WindowArea area)
800 {
801     const float innerBorder = INNER_BORDER_VP * vpr_;
802     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
803     const float innerAngle = INNER_ANGLE_VP * vpr_;
804     const float horizontalBorderLength = outsideBorder + innerAngle;
805     const float verticalBorderLength = outsideBorder + innerBorder;
806     const size_t innerAngleCount = 2;
807     WSRectF tbRect;
808     tbRect.posX_ = rect.posX_ + horizontalBorderLength;
809     tbRect.width_ = rect.width_ - horizontalBorderLength * innerAngleCount;
810     tbRect.height_ = verticalBorderLength;
811     if (area == MMI::WindowArea::FOCUS_ON_TOP) {
812         tbRect.posY_ = rect.posY_;
813     } else if (area == MMI::WindowArea::FOCUS_ON_BOTTOM) {
814         tbRect.posY_ = rect.posY_ + rect.height_ - verticalBorderLength;
815     } else {
816         return WSRectF();
817     }
818     return tbRect;
819 }
820 
UpdateLeftRightArea(const WSRectF & rect,MMI::WindowArea area)821 WSRectF Session::UpdateLeftRightArea(const WSRectF& rect, MMI::WindowArea area)
822 {
823     const float innerBorder = INNER_BORDER_VP * vpr_;
824     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
825     const float innerAngle = INNER_ANGLE_VP * vpr_;
826     const float verticalBorderLength = outsideBorder + innerAngle;
827     const float horizontalBorderLength = outsideBorder + innerBorder;
828     const size_t innerAngleCount = 2;
829     WSRectF lrRect;
830     lrRect.posY_ = rect.posY_ + verticalBorderLength;
831     lrRect.width_ = horizontalBorderLength;
832     lrRect.height_ = rect.height_ - verticalBorderLength * innerAngleCount;
833     if (area == MMI::WindowArea::FOCUS_ON_LEFT) {
834         lrRect.posX_ = rect.posX_;
835     } else if (area == MMI::WindowArea::FOCUS_ON_RIGHT) {
836         lrRect.posX_ = rect.posX_ + rect.width_ - horizontalBorderLength;
837     } else {
838         return WSRectF();
839     }
840     return lrRect;
841 }
842 
UpdateInnerAngleArea(const WSRectF & rect,MMI::WindowArea area)843 WSRectF Session::UpdateInnerAngleArea(const WSRectF& rect, MMI::WindowArea area)
844 {
845     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
846     const float innerAngle = INNER_ANGLE_VP * vpr_;
847     WSRectF iaRect;
848     iaRect.width_ = outsideBorder + innerAngle;
849     iaRect.height_ = outsideBorder + innerAngle;
850     if (area == MMI::WindowArea::FOCUS_ON_TOP_LEFT) {
851         iaRect.posX_ = rect.posX_;
852         iaRect.posY_ = rect.posY_;
853     } else if (area == MMI::WindowArea::FOCUS_ON_TOP_RIGHT) {
854         iaRect.posX_ = rect.posX_ + rect.width_ - iaRect.width_;
855         iaRect.posY_ = rect.posY_;
856     } else if (area == MMI::WindowArea::FOCUS_ON_BOTTOM_LEFT) {
857         iaRect.posX_ = rect.posX_;
858         iaRect.posY_ = rect.posY_ + rect.height_ - iaRect.height_;
859     } else if (area == MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT) {
860         iaRect.posX_ = rect.posX_ + rect.width_ - iaRect.width_;
861         iaRect.posY_ = rect.posY_ + rect.height_ - iaRect.height_;
862     } else {
863         return WSRectF();
864     }
865     return iaRect;
866 }
867 
UpdateHotRect(const WSRect & rect)868 WSRectF Session::UpdateHotRect(const WSRect& rect)
869 {
870     WSRectF newRect;
871     const float outsideBorder = OUTSIDE_BORDER_VP * vpr_;
872     const size_t outsideBorderCount = 2;
873     newRect.posX_ = rect.posX_ - outsideBorder;
874     newRect.posY_ = rect.posY_ - outsideBorder;
875     newRect.width_ = rect.width_ + outsideBorder * outsideBorderCount;
876     newRect.height_ = rect.height_ + outsideBorder * outsideBorderCount;
877     return newRect;
878 }
879 
UpdatePointerArea(const WSRect & rect)880 void Session::UpdatePointerArea(const WSRect& rect)
881 {
882     if (preRect_ == rect) {
883         WLOGFD("The window area does not change");
884         return;
885     }
886     WSRectF hotRect = UpdateHotRect(rect);
887     for (const auto &[area, _] : windowAreas_) {
888         if (area == MMI::WindowArea::FOCUS_ON_TOP || area == MMI::WindowArea::FOCUS_ON_BOTTOM) {
889             windowAreas_[area] = UpdateTopBottomArea(hotRect, area);
890         } else if (area == MMI::WindowArea::FOCUS_ON_RIGHT || area == MMI::WindowArea::FOCUS_ON_LEFT) {
891             windowAreas_[area] = UpdateLeftRightArea(hotRect, area);
892         } else if (area == MMI::WindowArea::FOCUS_ON_TOP_LEFT || area == MMI::WindowArea::FOCUS_ON_TOP_RIGHT ||
893             area == MMI::WindowArea::FOCUS_ON_BOTTOM_LEFT || area == MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT) {
894             windowAreas_[area] = UpdateInnerAngleArea(hotRect, area);
895         }
896     }
897     preRect_ = rect;
898 }
899 
UpdateSizeChangeReason(SizeChangeReason reason)900 WSError Session::UpdateSizeChangeReason(SizeChangeReason reason)
901 {
902     if (reason_ == reason) {
903         return WSError::WS_DO_NOTHING;
904     }
905     reason_ = reason;
906     return WSError::WS_OK;
907 }
908 
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::string & updateReason,const std::shared_ptr<RSTransaction> & rsTransaction)909 WSError Session::UpdateRect(const WSRect& rect, SizeChangeReason reason,
910     const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)
911 {
912     TLOGD(WmsLogTag::WMS_LAYOUT, "session update rect: id: %{public}d, rect:%{public}s, "
913         "reason:%{public}u %{public}s", GetPersistentId(), rect.ToString().c_str(), reason, updateReason.c_str());
914     if (!IsSessionValid()) {
915         winRect_ = rect;
916         TLOGD(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
917             GetPersistentId(), GetSessionState());
918         return WSError::WS_ERROR_INVALID_SESSION;
919     }
920     winRect_ = rect;
921     if (sessionStage_ != nullptr) {
922         int32_t rotateAnimationDuration = GetRotateAnimationDuration();
923         SceneAnimationConfig config { .rsTransaction_ = rsTransaction,
924             .animationDuration_ = rotateAnimationDuration };
925         sessionStage_->UpdateRect(rect, reason, config);
926         SetClientRect(rect);
927         RectCheckProcess();
928     } else {
929         WLOGFE("sessionStage_ is nullptr");
930     }
931     UpdatePointerArea(winRect_);
932     return WSError::WS_OK;
933 }
934 
UpdateDensity()935 WSError Session::UpdateDensity()
936 {
937     WLOGFI("session update density: id: %{public}d.", GetPersistentId());
938     if (!IsSessionValid()) {
939         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
940             GetPersistentId(), GetSessionState());
941         return WSError::WS_ERROR_INVALID_SESSION;
942     }
943     if (sessionStage_ != nullptr) {
944         sessionStage_->UpdateDensity();
945     } else {
946         WLOGFE("Session::UpdateDensity sessionStage_ is nullptr");
947         return WSError::WS_ERROR_NULLPTR;
948     }
949     return WSError::WS_OK;
950 }
951 
UpdateOrientation()952 WSError Session::UpdateOrientation()
953 {
954     TLOGD(WmsLogTag::DMS, "update orientation: id: %{public}d.", GetPersistentId());
955     if (!IsSessionValid()) {
956         TLOGE(WmsLogTag::DMS, "update orientation failed because of session is invalid, id = %{public}d.",
957             GetPersistentId());
958         return WSError::WS_ERROR_INVALID_SESSION;
959     }
960     if (sessionStage_ == nullptr) {
961         TLOGE(WmsLogTag::DMS, "update orientation failed because of sessionStage_ is nullptr, id = %{public}d.",
962             GetPersistentId());
963         return WSError::WS_ERROR_NULLPTR;
964     }
965     return sessionStage_->UpdateOrientation();
966 }
967 
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)968 __attribute__((no_sanitize("cfi"))) WSError Session::ConnectInner(const sptr<ISessionStage>& sessionStage,
969     const sptr<IWindowEventChannel>& eventChannel,
970     const std::shared_ptr<RSSurfaceNode>& surfaceNode,
971     SystemSessionConfig& systemConfig, sptr<WindowSessionProperty> property,
972     sptr<IRemoteObject> token, int32_t pid, int32_t uid, const std::string& identityToken)
973 {
974     TLOGI(WmsLogTag::WMS_LIFE, "ConnectInner session, id: %{public}d, state: %{public}u,"
975         "isTerminating:%{public}d, callingPid:%{public}d", GetPersistentId(),
976         static_cast<uint32_t>(GetSessionState()), isTerminating_, pid);
977     if (GetSessionState() != SessionState::STATE_DISCONNECT && !isTerminating_) {
978         TLOGE(WmsLogTag::WMS_LIFE, "state is not disconnect state:%{public}u id:%{public}u!",
979             GetSessionState(), GetPersistentId());
980         return WSError::WS_ERROR_INVALID_SESSION;
981     }
982     if (sessionStage == nullptr || eventChannel == nullptr) {
983         TLOGE(WmsLogTag::WMS_LIFE, "session stage or eventChannel is nullptr");
984         return WSError::WS_ERROR_NULLPTR;
985     }
986     sessionStage_ = sessionStage;
987     windowEventChannel_ = eventChannel;
988     surfaceNode_ = surfaceNode;
989     abilityToken_ = token;
990     systemConfig = systemConfig_;
991     SetWindowSessionProperty(property);
992     callingPid_ = pid;
993     callingUid_ = uid;
994     UpdateSessionState(SessionState::STATE_CONNECT);
995     WindowHelper::IsUIExtensionWindow(GetWindowType()) ? UpdateRect(winRect_, SizeChangeReason::UNDEFINED, "Connect") :
996         NotifyClientToUpdateRect("Connect", nullptr);
997     NotifyConnect();
998     callingBundleName_ = DelayedSingleton<ANRManager>::GetInstance()->GetBundleName(callingPid_, callingUid_);
999     DelayedSingleton<ANRManager>::GetInstance()->SetApplicationInfo(persistentId_, callingPid_, callingBundleName_);
1000     return WSError::WS_OK;
1001 }
1002 
SetWindowSessionProperty(const sptr<WindowSessionProperty> & property)1003 void Session::SetWindowSessionProperty(const sptr<WindowSessionProperty>& property)
1004 {
1005     if (property == nullptr) {
1006         return;
1007     }
1008     auto sessionProperty = GetSessionProperty();
1009     if (sessionProperty && sessionProperty->GetIsNeedUpdateWindowMode() && property) {
1010         property->SetIsNeedUpdateWindowMode(true);
1011         property->SetWindowMode(sessionProperty->GetWindowMode());
1012     }
1013     if (SessionHelper::IsMainWindow(GetWindowType()) &&
1014         GetSessionInfo().screenId_ != SCREEN_ID_INVALID && property) {
1015         property->SetDisplayId(GetSessionInfo().screenId_);
1016     }
1017     SetSessionProperty(property);
1018     if (property) {
1019         Rect rect = {winRect_.posX_, winRect_.posY_, static_cast<uint32_t>(winRect_.width_),
1020             static_cast<uint32_t>(winRect_.height_)};
1021         property->SetWindowRect(rect);
1022         property->SetPersistentId(GetPersistentId());
1023         property->SetFullScreenStart(GetSessionInfo().fullScreenStart_);
1024     }
1025     if (sessionProperty && property) {
1026         property->SetCompatibleModeInPc(sessionProperty->GetCompatibleModeInPc());
1027         property->SetIsSupportDragInPcCompatibleMode(sessionProperty->GetIsSupportDragInPcCompatibleMode());
1028         if (sessionProperty->GetCompatibleModeInPc()) {
1029             property->SetDragEnabled(sessionProperty->GetIsSupportDragInPcCompatibleMode());
1030         }
1031         property->SetCompatibleModeEnableInPad(sessionProperty->GetCompatibleModeEnableInPad());
1032         property->SetCompatibleWindowSizeInPc(sessionProperty->GetCompatibleInPcPortraitWidth(),
1033             sessionProperty->GetCompatibleInPcPortraitHeight(), sessionProperty->GetCompatibleInPcLandscapeWidth(),
1034             sessionProperty->GetCompatibleInPcLandscapeHeight());
1035         property->SetDragEnabled(sessionProperty->GetDragEnabled());
1036     }
1037     if (sessionProperty && SessionHelper::IsMainWindow(GetWindowType())) {
1038         property->SetIsPcAppInPad(sessionProperty->GetIsPcAppInPad());
1039     }
1040 }
1041 
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)1042 WSError Session::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
1043     const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
1044     int32_t pid, int32_t uid)
1045 {
1046     if (property == nullptr) {
1047         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
1048         return WSError::WS_ERROR_NULLPTR;
1049     }
1050     TLOGI(WmsLogTag::WMS_RECOVER, "id:%{public}d, state:%{public}u, pid:%{public}d",
1051         property->GetPersistentId(), static_cast<uint32_t>(property->GetWindowState()), pid);
1052     if (sessionStage == nullptr || eventChannel == nullptr) {
1053         TLOGE(WmsLogTag::WMS_RECOVER, "session stage or eventChannel is nullptr");
1054         return WSError::WS_ERROR_NULLPTR;
1055     }
1056     sessionStage_ = sessionStage;
1057     surfaceNode_ = surfaceNode;
1058     windowEventChannel_ = eventChannel;
1059     abilityToken_ = token;
1060     SetSessionProperty(property);
1061     persistentId_ = property->GetPersistentId();
1062     callingPid_ = pid;
1063     callingUid_ = uid;
1064     bufferAvailable_ = true;
1065     auto windowRect = property->GetWindowRect();
1066     layoutRect_ = { windowRect.posX_, windowRect.posY_,
1067         static_cast<int32_t>(windowRect.width_), static_cast<int32_t>(windowRect.height_) };
1068     UpdateSessionState(SessionState::STATE_CONNECT);
1069     return WSError::WS_OK;
1070 }
1071 
Foreground(sptr<WindowSessionProperty> property,bool isFromClient,const std::string & identityToken)1072 WSError Session::Foreground(sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)
1073 {
1074     HandleDialogForeground();
1075     SessionState state = GetSessionState();
1076     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, state:%{public}u, isTerminating:%{public}d",
1077         GetPersistentId(), static_cast<uint32_t>(state), isTerminating_);
1078     if (state != SessionState::STATE_CONNECT && state != SessionState::STATE_BACKGROUND &&
1079         state != SessionState::STATE_INACTIVE) {
1080         TLOGE(WmsLogTag::WMS_LIFE, "Foreground state invalid! state:%{public}u", state);
1081         return WSError::WS_ERROR_INVALID_SESSION;
1082     }
1083 
1084     UpdateSessionState(SessionState::STATE_FOREGROUND);
1085     if (!isActive_) {
1086         SetActive(true);
1087     }
1088     isStarting_ = false;
1089 
1090     NotifyForeground();
1091 
1092     isTerminating_ = false;
1093     isNeedSyncSessionRect_ = true;
1094     return WSError::WS_OK;
1095 }
1096 
HandleDialogBackground()1097 void Session::HandleDialogBackground()
1098 {
1099     const auto& type = GetWindowType();
1100     if (type < WindowType::APP_MAIN_WINDOW_BASE || type >= WindowType::APP_MAIN_WINDOW_END) {
1101         TLOGD(WmsLogTag::WMS_DIALOG, "Current session is not main window, id: %{public}d, type: %{public}d",
1102             GetPersistentId(), type);
1103         return;
1104     }
1105 
1106     auto dialogVec = GetDialogVector();
1107     for (const auto& dialog : dialogVec) {
1108         if (dialog == nullptr) {
1109             continue;
1110         }
1111         TLOGI(WmsLogTag::WMS_DIALOG, "Background dialog, id: %{public}d, dialogId: %{public}d",
1112             GetPersistentId(), dialog->GetPersistentId());
1113         if (!dialog->sessionStage_) {
1114             TLOGE(WmsLogTag::WMS_DIALOG, "dialog session stage is nullptr");
1115             return;
1116         }
1117         dialog->sessionStage_->NotifyDialogStateChange(false);
1118     }
1119 }
1120 
HandleDialogForeground()1121 void Session::HandleDialogForeground()
1122 {
1123     const auto& type = GetWindowType();
1124     if (type < WindowType::APP_MAIN_WINDOW_BASE || type >= WindowType::APP_MAIN_WINDOW_END) {
1125         TLOGD(WmsLogTag::WMS_DIALOG, "Current session is not main window, id: %{public}d, type: %{public}d",
1126             GetPersistentId(), type);
1127         return;
1128     }
1129 
1130     auto dialogVec = GetDialogVector();
1131     for (const auto& dialog : dialogVec) {
1132         if (dialog == nullptr) {
1133             continue;
1134         }
1135         TLOGI(WmsLogTag::WMS_DIALOG, "Foreground dialog, id: %{public}d, dialogId: %{public}d",
1136             GetPersistentId(), dialog->GetPersistentId());
1137         if (!dialog->sessionStage_) {
1138             TLOGE(WmsLogTag::WMS_DIALOG, "dialog session stage is nullptr");
1139             return;
1140         }
1141         dialog->sessionStage_->NotifyDialogStateChange(true);
1142     }
1143 }
1144 
Background(bool isFromClient,const std::string & identityToken)1145 WSError Session::Background(bool isFromClient, const std::string& identityToken)
1146 {
1147     HandleDialogBackground();
1148     SessionState state = GetSessionState();
1149     TLOGI(WmsLogTag::WMS_LIFE, "Background session, id: %{public}d, state: %{public}" PRIu32, GetPersistentId(),
1150         static_cast<uint32_t>(state));
1151     if (state == SessionState::STATE_ACTIVE && GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1152         UpdateSessionState(SessionState::STATE_INACTIVE);
1153         state = SessionState::STATE_INACTIVE;
1154         isActive_ = false;
1155     }
1156     isStarting_ = false;
1157     isStartingBeforeVisible_ = false;
1158     if (state != SessionState::STATE_INACTIVE) {
1159         TLOGW(WmsLogTag::WMS_LIFE, "Background state invalid! id: %{public}d, state: %{public}u",
1160             GetPersistentId(), state);
1161         return WSError::WS_ERROR_INVALID_SESSION;
1162     }
1163     UpdateSessionState(SessionState::STATE_BACKGROUND);
1164     NotifyBackground();
1165     DelayedSingleton<ANRManager>::GetInstance()->OnBackground(persistentId_);
1166     return WSError::WS_OK;
1167 }
1168 
ResetSessionConnectState()1169 void Session::ResetSessionConnectState()
1170 {
1171     TLOGI(WmsLogTag::WMS_LIFE, "ResetSessionState, id: %{public}d, state: %{public}u",
1172         GetPersistentId(), GetSessionState());
1173     SetSessionState(SessionState::STATE_DISCONNECT);
1174     SetCallingPid(-1);
1175 }
1176 
Disconnect(bool isFromClient,const std::string & identityToken)1177 WSError Session::Disconnect(bool isFromClient, const std::string& identityToken)
1178 {
1179     auto state = GetSessionState();
1180     TLOGI(WmsLogTag::WMS_LIFE, "Disconnect session, id: %{public}d, state: %{public}u", GetPersistentId(), state);
1181     isActive_ = false;
1182     isStarting_ = false;
1183     isStartingBeforeVisible_ = false;
1184     bufferAvailable_ = false;
1185     isNeedSyncSessionRect_ = true;
1186     if (mainHandler_) {
1187         mainHandler_->PostTask([surfaceNode = std::move(surfaceNode_)]() mutable {
1188             surfaceNode.reset();
1189         });
1190     }
1191     UpdateSessionState(SessionState::STATE_BACKGROUND);
1192     UpdateSessionState(SessionState::STATE_DISCONNECT);
1193     NotifyDisconnect();
1194     DelayedSingleton<ANRManager>::GetInstance()->OnSessionLost(persistentId_);
1195     return WSError::WS_OK;
1196 }
1197 
Show(sptr<WindowSessionProperty> property)1198 WSError Session::Show(sptr<WindowSessionProperty> property)
1199 {
1200     TLOGD(WmsLogTag::WMS_LIFE, "Show session, id: %{public}d", GetPersistentId());
1201     return WSError::WS_OK;
1202 }
1203 
Hide()1204 WSError Session::Hide()
1205 {
1206     TLOGD(WmsLogTag::WMS_LIFE, "Hide session, id: %{public}d", GetPersistentId());
1207     return WSError::WS_OK;
1208 }
1209 
DrawingCompleted()1210 WSError Session::DrawingCompleted()
1211 {
1212     TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
1213     if (!SessionPermission::IsSameAppAsCalling(SHELL_BUNDLE_NAME, SHELL_APP_IDENTIFIER)) {
1214         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
1215         return WSError::WS_ERROR_INVALID_PERMISSION;
1216     }
1217     auto lifecycleListeners = GetListeners<ILifecycleListener>();
1218     for (auto& listener : lifecycleListeners) {
1219         if (auto listenerPtr = listener.lock()) {
1220             listenerPtr->OnDrawingCompleted();
1221         }
1222     }
1223     return WSError::WS_OK;
1224 }
1225 
SetActive(bool active)1226 WSError Session::SetActive(bool active)
1227 {
1228     SessionState state = GetSessionState();
1229     TLOGI(WmsLogTag::WMS_LIFE, "new active:%{public}d, id:%{public}d, state:%{public}" PRIu32,
1230         active, GetPersistentId(), static_cast<uint32_t>(state));
1231     if (!IsSessionValid()) {
1232         TLOGW(WmsLogTag::WMS_LIFE, "Session is invalid, id: %{public}d state: %{public}u",
1233             GetPersistentId(), GetSessionState());
1234         return WSError::WS_ERROR_INVALID_SESSION;
1235     }
1236     if (active == isActive_) {
1237         TLOGD(WmsLogTag::WMS_LIFE, "Session active do not change: [%{public}d]", active);
1238         return WSError::WS_DO_NOTHING;
1239     }
1240     if (!sessionStage_) {
1241         TLOGE(WmsLogTag::WMS_LIFE, "session stage is nullptr");
1242         return WSError::WS_ERROR_NULLPTR;
1243     }
1244     if (active && GetSessionState() == SessionState::STATE_FOREGROUND) {
1245         sessionStage_->SetActive(true);
1246         UpdateSessionState(SessionState::STATE_ACTIVE);
1247         isActive_ = active;
1248     }
1249     if (!active && GetSessionState() == SessionState::STATE_ACTIVE) {
1250         sessionStage_->SetActive(false);
1251         UpdateSessionState(SessionState::STATE_INACTIVE);
1252         isActive_ = active;
1253     }
1254     return WSError::WS_OK;
1255 }
1256 
NotifyForegroundInteractiveStatus(bool interactive)1257 void Session::NotifyForegroundInteractiveStatus(bool interactive)
1258 {
1259     SetForegroundInteractiveStatus(interactive);
1260 }
1261 
SetForegroundInteractiveStatus(bool interactive)1262 void Session::SetForegroundInteractiveStatus(bool interactive)
1263 {
1264     if (interactive != GetForegroundInteractiveStatus()) {
1265         TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d interactive:%{public}d", GetPersistentId(),
1266             static_cast<int>(interactive));
1267     }
1268     foregroundInteractiveStatus_.store(interactive);
1269     if (Session::IsScbCoreEnabled()) {
1270         return;
1271     }
1272     NotifySessionInfoChange();
1273 }
1274 
GetForegroundInteractiveStatus() const1275 bool Session::GetForegroundInteractiveStatus() const
1276 {
1277     return foregroundInteractiveStatus_.load();
1278 }
1279 
IsActivatedAfterScreenLocked() const1280 bool Session::IsActivatedAfterScreenLocked() const
1281 {
1282     return isActivatedAfterScreenLocked_.load();
1283 }
1284 
SetIsActivatedAfterScreenLocked(bool isActivatedAfterScreenLocked)1285 void Session::SetIsActivatedAfterScreenLocked(bool isActivatedAfterScreenLocked)
1286 {
1287     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, isActivatedAfterScreenLocked:%{public}d",
1288           GetPersistentId(), isActivatedAfterScreenLocked);
1289     isActivatedAfterScreenLocked_.store(isActivatedAfterScreenLocked);
1290 }
1291 
SetAttachState(bool isAttach,WindowMode windowMode)1292 void Session::SetAttachState(bool isAttach, WindowMode windowMode)
1293 {
1294     isAttach_ = isAttach;
1295     auto task = [weakThis = wptr(this), isAttach]() {
1296         auto session = weakThis.promote();
1297         if (session == nullptr) {
1298             TLOGD(WmsLogTag::WMS_LIFE, "session is null");
1299             return;
1300         }
1301         TLOGD(WmsLogTag::WMS_LIFE, "isAttach:%{public}d persistentId:%{public}d", isAttach,
1302             session->GetPersistentId());
1303         if (!isAttach && session->detachCallback_ != nullptr) {
1304             TLOGI(WmsLogTag::WMS_LIFE, "Session detach, persistentId:%{public}d", session->GetPersistentId());
1305             session->detachCallback_->OnPatternDetach(session->GetPersistentId());
1306             session->detachCallback_ = nullptr;
1307         }
1308     };
1309     PostTask(task, "SetAttachState");
1310     CreateDetectStateTask(isAttach, windowMode);
1311 }
1312 
CreateDetectStateTask(bool isAttach,WindowMode windowMode)1313 void Session::CreateDetectStateTask(bool isAttach, WindowMode windowMode)
1314 {
1315     if (!IsSupportDetectWindow(isAttach)) {
1316         return;
1317     }
1318     if (showRecent_) {
1319         return;
1320     }
1321     if (!ShouldCreateDetectTask(isAttach, windowMode)) {
1322         RemoveWindowDetectTask();
1323         DetectTaskInfo detectTaskInfo;
1324         SetDetectTaskInfo(detectTaskInfo);
1325         return;
1326     }
1327     CreateWindowStateDetectTask(isAttach, windowMode);
1328 }
1329 
RegisterDetachCallback(const sptr<IPatternDetachCallback> & callback)1330 void Session::RegisterDetachCallback(const sptr<IPatternDetachCallback>& callback)
1331 {
1332     detachCallback_ = callback;
1333     if (!isAttach_ && detachCallback_ != nullptr) {
1334         TLOGI(WmsLogTag::WMS_LIFE, "Session detach before register, persistentId:%{public}d", GetPersistentId());
1335         detachCallback_->OnPatternDetach(GetPersistentId());
1336         detachCallback_ = nullptr;
1337     }
1338 }
1339 
SetChangeSessionVisibilityWithStatusBarEventListener(const NotifyChangeSessionVisibilityWithStatusBarFunc & func)1340 void Session::SetChangeSessionVisibilityWithStatusBarEventListener(
1341     const NotifyChangeSessionVisibilityWithStatusBarFunc& func)
1342 {
1343     changeSessionVisibilityWithStatusBarFunc_ = func;
1344 }
1345 
SetPendingSessionActivationEventListener(const NotifyPendingSessionActivationFunc & func)1346 void Session::SetPendingSessionActivationEventListener(const NotifyPendingSessionActivationFunc& func)
1347 {
1348     pendingSessionActivationFunc_ = func;
1349 }
1350 
SetBackPressedListenser(const NotifyBackPressedFunc & func)1351 void Session::SetBackPressedListenser(const NotifyBackPressedFunc& func)
1352 {
1353     backPressedFunc_ = func;
1354 }
1355 
SetTerminateSessionListener(const NotifyTerminateSessionFunc & func)1356 void Session::SetTerminateSessionListener(const NotifyTerminateSessionFunc& func)
1357 {
1358     terminateSessionFunc_ = func;
1359 }
1360 
RemoveLifeCycleTask(const LifeCycleTaskType & taskType)1361 void Session::RemoveLifeCycleTask(const LifeCycleTaskType& taskType)
1362 {
1363     std::lock_guard<std::mutex> lock(lifeCycleTaskQueueMutex_);
1364     if (lifeCycleTaskQueue_.empty()) {
1365         return;
1366     }
1367     sptr<SessionLifeCycleTask> currLifeCycleTask = lifeCycleTaskQueue_.front();
1368     if (currLifeCycleTask->type != taskType) {
1369         TLOGW(WmsLogTag::WMS_LIFE, "not match, current running taskName=%{public}s, PersistentId=%{public}d",
1370             currLifeCycleTask->name.c_str(), persistentId_);
1371         return;
1372     }
1373     TLOGI(WmsLogTag::WMS_LIFE, "Removed lifeCyleTask %{public}s. PersistentId=%{public}d",
1374         currLifeCycleTask->name.c_str(), persistentId_);
1375     lifeCycleTaskQueue_.pop_front();
1376     if (lifeCycleTaskQueue_.empty()) {
1377         return;
1378     }
1379     StartLifeCycleTask(lifeCycleTaskQueue_.front());
1380 }
1381 
PostLifeCycleTask(Task && task,const std::string & name,const LifeCycleTaskType & taskType)1382 void Session::PostLifeCycleTask(Task&& task, const std::string& name, const LifeCycleTaskType& taskType)
1383 {
1384     std::lock_guard<std::mutex> lock(lifeCycleTaskQueueMutex_);
1385     if (!lifeCycleTaskQueue_.empty()) {
1386         // remove current running task if expired
1387         sptr<SessionLifeCycleTask> currLifeCycleTask = lifeCycleTaskQueue_.front();
1388         std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();
1389         bool isCurrentTaskExpired =
1390             std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - currLifeCycleTask->startTime).count() >
1391             LIFE_CYCLE_TASK_EXPIRED_TIME_LIMIT;
1392         if (isCurrentTaskExpired) {
1393             WLOGFE("[WMSLife] Remove expired LifeCycleTask %{public}s. PersistentId=%{public}d",
1394                 currLifeCycleTask->name.c_str(), persistentId_);
1395             lifeCycleTaskQueue_.pop_front();
1396         }
1397     }
1398 
1399     if (lifeCycleTaskQueue_.size() == MAX_LIFE_CYCLE_TASK_IN_QUEUE) {
1400         TLOGE(WmsLogTag::WMS_LIFE, "Failed to add task %{public}s to life cycle queue", name.c_str());
1401         return;
1402     }
1403     sptr<SessionLifeCycleTask> lifeCycleTask = new SessionLifeCycleTask(std::move(task), name, taskType);
1404     lifeCycleTaskQueue_.push_back(lifeCycleTask);
1405     TLOGI(WmsLogTag::WMS_LIFE, "Add task %{public}s to life cycle queue, PersistentId=%{public}d",
1406         name.c_str(), persistentId_);
1407     if (lifeCycleTaskQueue_.size() == 1) {
1408         StartLifeCycleTask(lifeCycleTask);
1409         return;
1410     }
1411 
1412     StartLifeCycleTask(lifeCycleTaskQueue_.front());
1413 }
1414 
StartLifeCycleTask(sptr<SessionLifeCycleTask> lifeCycleTask)1415 void Session::StartLifeCycleTask(sptr<SessionLifeCycleTask> lifeCycleTask)
1416 {
1417     if (lifeCycleTask->running) {
1418         return;
1419     }
1420     TLOGI(WmsLogTag::WMS_LIFE, "Execute LifeCycleTask %{public}s. PersistentId: %{public}d",
1421         lifeCycleTask->name.c_str(), persistentId_);
1422     lifeCycleTask->running = true;
1423     lifeCycleTask->startTime = std::chrono::steady_clock::now();
1424     PostTask(std::move(lifeCycleTask->task), lifeCycleTask->name);
1425 }
1426 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool needStartCaller,bool isFromBroker)1427 WSError Session::TerminateSessionNew(
1428     const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needStartCaller, bool isFromBroker)
1429 {
1430     if (abilitySessionInfo == nullptr) {
1431         TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
1432         return WSError::WS_ERROR_INVALID_SESSION;
1433     }
1434     auto task = [this, abilitySessionInfo, needStartCaller, isFromBroker]() {
1435         isTerminating_ = true;
1436         SessionInfo info;
1437         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1438         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1439         info.callerToken_ = abilitySessionInfo->callerToken;
1440         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
1441         {
1442             std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
1443             sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1444             sessionInfo_.resultCode = abilitySessionInfo->resultCode;
1445         }
1446         if (terminateSessionFuncNew_) {
1447             terminateSessionFuncNew_(info, needStartCaller, isFromBroker);
1448         }
1449         TLOGI(WmsLogTag::WMS_LIFE,
1450             "TerminateSessionNew, id: %{public}d, needStartCaller: %{public}d, isFromBroker: %{public}d",
1451             GetPersistentId(), needStartCaller, isFromBroker);
1452     };
1453     PostLifeCycleTask(task, "TerminateSessionNew", LifeCycleTaskType::STOP);
1454     return WSError::WS_OK;
1455 }
1456 
SetTerminateSessionListenerNew(const NotifyTerminateSessionFuncNew & func)1457 void Session::SetTerminateSessionListenerNew(const NotifyTerminateSessionFuncNew& func)
1458 {
1459     terminateSessionFuncNew_ = func;
1460 }
1461 
TerminateSessionTotal(const sptr<AAFwk::SessionInfo> abilitySessionInfo,TerminateType terminateType)1462 WSError Session::TerminateSessionTotal(const sptr<AAFwk::SessionInfo> abilitySessionInfo, TerminateType terminateType)
1463 {
1464     if (abilitySessionInfo == nullptr) {
1465         TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
1466         return WSError::WS_ERROR_INVALID_SESSION;
1467     }
1468     if (isTerminating_) {
1469         TLOGE(WmsLogTag::WMS_LIFE, "is terminating, return!");
1470         return WSError::WS_ERROR_INVALID_OPERATION;
1471     }
1472     isTerminating_ = true;
1473     SessionInfo info;
1474     info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1475     info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1476     info.callerToken_ = abilitySessionInfo->callerToken;
1477     info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
1478     {
1479         std::lock_guard<std::recursive_mutex> lock(sessionInfoMutex_);
1480         sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1481         sessionInfo_.resultCode = abilitySessionInfo->resultCode;
1482     }
1483     if (terminateSessionFuncTotal_) {
1484         terminateSessionFuncTotal_(info, terminateType);
1485     }
1486     return WSError::WS_OK;
1487 }
1488 
SetTerminateSessionListenerTotal(const NotifyTerminateSessionFuncTotal & func)1489 void Session::SetTerminateSessionListenerTotal(const NotifyTerminateSessionFuncTotal& func)
1490 {
1491     terminateSessionFuncTotal_ = func;
1492 }
1493 
SetSessionLabel(const std::string & label)1494 WSError Session::SetSessionLabel(const std::string& label)
1495 {
1496     WLOGFI("run Session::SetSessionLabel");
1497     if (updateSessionLabelFunc_) {
1498         updateSessionLabelFunc_(label);
1499     }
1500     return WSError::WS_OK;
1501 }
1502 
SetUpdateSessionLabelListener(const NofitySessionLabelUpdatedFunc & func)1503 void Session::SetUpdateSessionLabelListener(const NofitySessionLabelUpdatedFunc& func)
1504 {
1505     updateSessionLabelFunc_ = func;
1506 }
1507 
SetSessionIcon(const std::shared_ptr<Media::PixelMap> & icon)1508 WSError Session::SetSessionIcon(const std::shared_ptr<Media::PixelMap>& icon)
1509 {
1510     WLOGFD("run Session::SetSessionIcon, id: %{public}d", GetPersistentId());
1511     if (scenePersistence_ == nullptr) {
1512         WLOGFE("scenePersistence_ is nullptr.");
1513         return WSError::WS_ERROR_INVALID_OPERATION;
1514     }
1515     scenePersistence_->SaveUpdatedIcon(icon);
1516     std::string updatedIconPath = scenePersistence_->GetUpdatedIconPath();
1517     if (updateSessionIconFunc_) {
1518         updateSessionIconFunc_(updatedIconPath);
1519     }
1520     return WSError::WS_OK;
1521 }
1522 
SetUpdateSessionIconListener(const NofitySessionIconUpdatedFunc & func)1523 void Session::SetUpdateSessionIconListener(const NofitySessionIconUpdatedFunc& func)
1524 {
1525     updateSessionIconFunc_ = func;
1526 }
1527 
Clear(bool needStartCaller)1528 WSError Session::Clear(bool needStartCaller)
1529 {
1530     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, needStartCaller:%{public}u", GetPersistentId(), needStartCaller);
1531     auto task = [weakThis = wptr(this), needStartCaller]() {
1532         auto session = weakThis.promote();
1533         if (session == nullptr) {
1534             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
1535             return;
1536         }
1537         session->isTerminating_ = true;
1538         SessionInfo info = session->GetSessionInfo();
1539         if (session->terminateSessionFuncNew_) {
1540             session->terminateSessionFuncNew_(info, needStartCaller, false);
1541         }
1542     };
1543     PostLifeCycleTask(task, "Clear", LifeCycleTaskType::STOP);
1544     return WSError::WS_OK;
1545 }
1546 
SetSessionExceptionListener(const NotifySessionExceptionFunc & func,bool fromJsScene)1547 void Session::SetSessionExceptionListener(const NotifySessionExceptionFunc& func, bool fromJsScene)
1548 {
1549     if (func == nullptr) {
1550         WLOGFE("func is nullptr");
1551         return;
1552     }
1553     std::shared_ptr<NotifySessionExceptionFunc> funcSptr = std::make_shared<NotifySessionExceptionFunc>(func);
1554     if (fromJsScene) {
1555         jsSceneSessionExceptionFunc_ = funcSptr;
1556     } else {
1557         sessionExceptionFunc_ = funcSptr;
1558     }
1559 }
1560 
SetSessionSnapshotListener(const NotifySessionSnapshotFunc & func)1561 void Session::SetSessionSnapshotListener(const NotifySessionSnapshotFunc& func)
1562 {
1563     if (func == nullptr) {
1564         WLOGFE("func is nullptr");
1565         return;
1566     }
1567     notifySessionSnapshotFunc_ = func;
1568 }
1569 
SetPendingSessionToForegroundListener(const NotifyPendingSessionToForegroundFunc & func)1570 void Session::SetPendingSessionToForegroundListener(const NotifyPendingSessionToForegroundFunc& func)
1571 {
1572     pendingSessionToForegroundFunc_ = func;
1573 }
1574 
PendingSessionToForeground()1575 WSError Session::PendingSessionToForeground()
1576 {
1577     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
1578     SessionInfo info = GetSessionInfo();
1579     if (pendingSessionActivationFunc_) {
1580         pendingSessionActivationFunc_(info);
1581     }
1582     return WSError::WS_OK;
1583 }
1584 
SetPendingSessionToBackgroundForDelegatorListener(const NotifyPendingSessionToBackgroundForDelegatorFunc & func)1585 void Session::SetPendingSessionToBackgroundForDelegatorListener(
1586     const NotifyPendingSessionToBackgroundForDelegatorFunc& func)
1587 {
1588     pendingSessionToBackgroundForDelegatorFunc_ = func;
1589 }
1590 
PendingSessionToBackgroundForDelegator(bool shouldBackToCaller)1591 WSError Session::PendingSessionToBackgroundForDelegator(bool shouldBackToCaller)
1592 {
1593     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d, shouldBackToCaller: %{public}d",
1594         GetPersistentId(), shouldBackToCaller);
1595     SessionInfo info = GetSessionInfo();
1596     if (pendingSessionToBackgroundForDelegatorFunc_) {
1597         pendingSessionToBackgroundForDelegatorFunc_(info, shouldBackToCaller);
1598     }
1599     return WSError::WS_OK;
1600 }
1601 
SetRaiseToAppTopForPointDownFunc(const NotifyRaiseToTopForPointDownFunc & func)1602 void Session::SetRaiseToAppTopForPointDownFunc(const NotifyRaiseToTopForPointDownFunc& func)
1603 {
1604     raiseToTopForPointDownFunc_ = func;
1605 }
1606 
NotifyScreenshot()1607 void Session::NotifyScreenshot()
1608 {
1609     if (!sessionStage_) {
1610         return;
1611     }
1612     sessionStage_->NotifyScreenshot();
1613 }
1614 
NotifyCloseExistPipWindow()1615 WSError Session::NotifyCloseExistPipWindow()
1616 {
1617     if (!sessionStage_) {
1618         return WSError::WS_ERROR_NULLPTR;
1619     }
1620     return sessionStage_->NotifyCloseExistPipWindow();
1621 }
1622 
NotifyDestroy()1623 WSError Session::NotifyDestroy()
1624 {
1625     if (!sessionStage_) {
1626         return WSError::WS_ERROR_NULLPTR;
1627     }
1628     return sessionStage_->NotifyDestroy();
1629 }
1630 
SetParentSession(const sptr<Session> & session)1631 void Session::SetParentSession(const sptr<Session>& session)
1632 {
1633     if (session == nullptr) {
1634         WLOGFW("Session is nullptr");
1635         return;
1636     }
1637     {
1638         std::unique_lock<std::shared_mutex> lock(parentSessionMutex_);
1639         parentSession_ = session;
1640     }
1641     TLOGD(WmsLogTag::WMS_SUB, "[WMSDialog][WMSSub]Set parent success, parentId: %{public}d, id: %{public}d",
1642         session->GetPersistentId(), GetPersistentId());
1643 }
1644 
GetParentSession() const1645 sptr<Session> Session::GetParentSession() const
1646 {
1647     std::shared_lock<std::shared_mutex> lock(parentSessionMutex_);
1648     return parentSession_;
1649 }
1650 
GetMainSession()1651 sptr<Session> Session::GetMainSession()
1652 {
1653     if (SessionHelper::IsMainWindow(GetWindowType())) {
1654         return this;
1655     } else if (parentSession_) {
1656         return parentSession_->GetMainSession();
1657     } else {
1658         return nullptr;
1659     }
1660 }
1661 
BindDialogToParentSession(const sptr<Session> & session)1662 void Session::BindDialogToParentSession(const sptr<Session>& session)
1663 {
1664     std::unique_lock<std::shared_mutex> lock(dialogVecMutex_);
1665     auto iter = std::find(dialogVec_.begin(), dialogVec_.end(), session);
1666     if (iter != dialogVec_.end()) {
1667         TLOGW(WmsLogTag::WMS_DIALOG, "Dialog is existed in parentVec, id: %{public}d, parentId: %{public}d",
1668             session->GetPersistentId(), GetPersistentId());
1669         return;
1670     }
1671     dialogVec_.push_back(session);
1672     TLOGD(WmsLogTag::WMS_DIALOG, "Bind dialog success, id: %{public}d, parentId: %{public}d",
1673         session->GetPersistentId(), GetPersistentId());
1674 }
1675 
RemoveDialogToParentSession(const sptr<Session> & session)1676 void Session::RemoveDialogToParentSession(const sptr<Session>& session)
1677 {
1678     std::unique_lock<std::shared_mutex> lock(dialogVecMutex_);
1679     auto iter = std::find(dialogVec_.begin(), dialogVec_.end(), session);
1680     if (iter != dialogVec_.end()) {
1681         TLOGD(WmsLogTag::WMS_DIALOG, "Remove dialog success, id: %{public}d, parentId: %{public}d",
1682             session->GetPersistentId(), GetPersistentId());
1683         dialogVec_.erase(iter);
1684     }
1685     TLOGW(WmsLogTag::WMS_DIALOG, "Remove dialog failed, id: %{public}d, parentId: %{public}d",
1686         session->GetPersistentId(), GetPersistentId());
1687 }
1688 
GetDialogVector() const1689 std::vector<sptr<Session>> Session::GetDialogVector() const
1690 {
1691     std::shared_lock<std::shared_mutex> lock(dialogVecMutex_);
1692     return dialogVec_;
1693 }
1694 
ClearDialogVector()1695 void Session::ClearDialogVector()
1696 {
1697     std::unique_lock<std::shared_mutex> lock(dialogVecMutex_);
1698     dialogVec_.clear();
1699     TLOGD(WmsLogTag::WMS_DIALOG, "parentId: %{public}d", GetPersistentId());
1700     return;
1701 }
1702 
CheckDialogOnForeground()1703 bool Session::CheckDialogOnForeground()
1704 {
1705     auto dialogVec = GetDialogVector();
1706     if (dialogVec.empty()) {
1707         TLOGD(WmsLogTag::WMS_DIALOG, "Dialog is empty, id: %{public}d", GetPersistentId());
1708         return false;
1709     }
1710     for (auto iter = dialogVec.rbegin(); iter != dialogVec.rend(); iter++) {
1711         auto dialogSession = *iter;
1712         if (dialogSession && (dialogSession->GetSessionState() == SessionState::STATE_ACTIVE ||
1713             dialogSession->GetSessionState() == SessionState::STATE_FOREGROUND)) {
1714             TLOGD(WmsLogTag::WMS_DIALOG, "Notify touch dialog window, id: %{public}d", GetPersistentId());
1715             return true;
1716         }
1717     }
1718     return false;
1719 }
1720 
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const1721 bool Session::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
1722 {
1723     return true;
1724 }
1725 
IsTopDialog() const1726 bool Session::IsTopDialog() const
1727 {
1728     int32_t currentPersistentId = GetPersistentId();
1729     auto parentSession = GetParentSession();
1730     if (parentSession == nullptr) {
1731         TLOGW(WmsLogTag::WMS_DIALOG, "Dialog's Parent is NULL. id: %{public}d", currentPersistentId);
1732         return false;
1733     }
1734     auto parentDialogVec = parentSession->GetDialogVector();
1735     if (parentDialogVec.size() <= 1) {
1736         return true;
1737     }
1738     for (auto iter = parentDialogVec.rbegin(); iter != parentDialogVec.rend(); iter++) {
1739         auto dialogSession = *iter;
1740         if (dialogSession && (dialogSession->GetSessionState() == SessionState::STATE_ACTIVE ||
1741             dialogSession->GetSessionState() == SessionState::STATE_FOREGROUND)) {
1742             WLOGFI("Dialog id: %{public}d, current dialog id: %{public}d", dialogSession->GetPersistentId(),
1743                 currentPersistentId);
1744             return dialogSession->GetPersistentId() == currentPersistentId;
1745         }
1746     }
1747     return false;
1748 }
1749 
DumpPointerWindowArea(MMI::WindowArea area) const1750 const char* Session::DumpPointerWindowArea(MMI::WindowArea area) const
1751 {
1752     const std::map<MMI::WindowArea, const char*> areaMap = {
1753         { MMI::WindowArea::FOCUS_ON_INNER, "FOCUS_ON_INNER" },
1754         { MMI::WindowArea::FOCUS_ON_TOP, "FOCUS_ON_TOP" },
1755         { MMI::WindowArea::FOCUS_ON_BOTTOM, "FOCUS_ON_BOTTOM" },
1756         { MMI::WindowArea::FOCUS_ON_LEFT, "FOCUS_ON_LEFT" },
1757         { MMI::WindowArea::FOCUS_ON_RIGHT, "FOCUS_ON_RIGHT" },
1758         { MMI::WindowArea::FOCUS_ON_BOTTOM_LEFT, "FOCUS_ON_BOTTOM_LEFT" },
1759         { MMI::WindowArea::FOCUS_ON_BOTTOM_RIGHT, "FOCUS_ON_BOTTOM_RIGHT" },
1760         { MMI::WindowArea::FOCUS_ON_TOP_LEFT, "FOCUS_ON_TOP_LEFT" },
1761         { MMI::WindowArea::FOCUS_ON_TOP_RIGHT, "FOCUS_ON_TOP_RIGHT" },
1762         { MMI::WindowArea::EXIT, "EXIT" }
1763     };
1764     auto iter = areaMap.find(area);
1765     if (iter == areaMap.end()) {
1766         return "UNKNOWN";
1767     }
1768     return iter->second;
1769 }
1770 
RaiseToAppTopForPointDown()1771 WSError Session::RaiseToAppTopForPointDown()
1772 {
1773     if (raiseToTopForPointDownFunc_) {
1774         raiseToTopForPointDownFunc_();
1775         WLOGFD("RaiseToAppTopForPointDown, id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
1776     }
1777     return WSError::WS_OK;
1778 }
1779 
PresentFocusIfPointDown()1780 void Session::PresentFocusIfPointDown()
1781 {
1782     WLOGFI("id: %{public}d,type: %{public}d", GetPersistentId(), GetWindowType());
1783     if (!isFocused_ && GetFocusable()) {
1784         FocusChangeReason reason = FocusChangeReason::CLICK;
1785         NotifyRequestFocusStatusNotifyManager(true, false, reason);
1786     }
1787     NotifyClick();
1788 }
1789 
HandlePointDownDialog()1790 void Session::HandlePointDownDialog()
1791 {
1792     sptr<Session> lastValidDialog = nullptr;
1793     auto dialogVec = GetDialogVector();
1794     for (auto dialog : dialogVec) {
1795         if (dialog && (dialog->GetSessionState() == SessionState::STATE_FOREGROUND ||
1796             dialog->GetSessionState() == SessionState::STATE_ACTIVE)) {
1797             dialog->RaiseToAppTopForPointDown();
1798             lastValidDialog = dialog;
1799             TLOGD(WmsLogTag::WMS_DIALOG, "Point main window, raise to top and dialog need focus, "
1800                 "id: %{public}d, dialogId: %{public}d", GetPersistentId(), dialog->GetPersistentId());
1801         }
1802     }
1803     if (lastValidDialog != nullptr) {
1804         lastValidDialog->PresentFocusIfPointDown();
1805     }
1806 }
1807 
HandleSubWindowClick(int32_t action)1808 WSError Session::HandleSubWindowClick(int32_t action)
1809 {
1810     auto parentSession = GetParentSession();
1811     if (parentSession && parentSession->CheckDialogOnForeground()) {
1812         TLOGD(WmsLogTag::WMS_DIALOG, "Its main window has dialog on foreground, id: %{public}d", GetPersistentId());
1813         return WSError::WS_ERROR_INVALID_PERMISSION;
1814     }
1815     auto property = GetSessionProperty();
1816     if (property == nullptr) {
1817         TLOGE(WmsLogTag::WMS_EVENT, "property is null");
1818         return WSError::WS_ERROR_NULLPTR;
1819     }
1820     bool raiseEnabled = property->GetRaiseEnabled() &&
1821         (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1822     if (raiseEnabled) {
1823         RaiseToAppTopForPointDown();
1824     } else if (parentSession) {
1825         // sub window is forbidden to raise to top after click, but its parent should raise
1826         parentSession->NotifyClick();
1827     }
1828     return WSError::WS_OK;
1829 }
1830 
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient)1831 WSError Session::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, bool needNotifyClient)
1832 {
1833     WLOGFD("Session TransferPointEvent, id: %{public}d", GetPersistentId());
1834     if (!IsSystemSession() && !IsSessionValid()) {
1835         return WSError::WS_ERROR_INVALID_SESSION;
1836     }
1837     if (pointerEvent == nullptr) {
1838         WLOGFE("PointerEvent is nullptr");
1839         return WSError::WS_ERROR_NULLPTR;
1840     }
1841     auto pointerAction = pointerEvent->GetPointerAction();
1842     bool isPointDown = (pointerAction == MMI::PointerEvent::POINTER_ACTION_DOWN) ||
1843         (pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1844     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1845         if (CheckDialogOnForeground() && isPointDown) {
1846             HandlePointDownDialog();
1847             return WSError::WS_ERROR_INVALID_PERMISSION;
1848         }
1849     } else if (GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
1850         WSError ret = HandleSubWindowClick(pointerAction);
1851         if (ret != WSError::WS_OK) {
1852             return ret;
1853         }
1854     } else if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
1855         auto parentSession = GetParentSession();
1856         if (parentSession && parentSession->CheckDialogOnForeground() && isPointDown) {
1857             parentSession->HandlePointDownDialog();
1858             if (!IsTopDialog()) {
1859                 TLOGI(WmsLogTag::WMS_DIALOG, "There is at least one active dialog upon this dialog, id: %{public}d",
1860                     GetPersistentId());
1861                 return WSError::WS_ERROR_INVALID_PERMISSION;
1862             }
1863         }
1864     }
1865     if (DelayedSingleton<ANRManager>::GetInstance()->IsANRTriggered(persistentId_)) {
1866         WLOGFW("InputTracking id:%{public}d, The pointerEvent does not report normally,"
1867             "bundleName:%{public}s not reponse, pid:%{public}d, persistentId:%{public}d",
1868             pointerEvent->GetId(), callingBundleName_.c_str(), callingPid_, persistentId_);
1869         return WSError::WS_DO_NOTHING;
1870     }
1871     PresentFoucusIfNeed(pointerAction);
1872     if (!windowEventChannel_) {
1873         if (!IsSystemSession()) {
1874             WLOGFE("windowEventChannel_ is null");
1875         }
1876         return WSError::WS_ERROR_NULLPTR;
1877     }
1878 
1879     if (needNotifyClient) {
1880         WSError ret = windowEventChannel_->TransferPointerEvent(pointerEvent);
1881         if (ret != WSError::WS_OK) {
1882             WLOGFE("InputTracking id:%{public}d, TransferPointer failed, ret:%{public}d ",
1883                 pointerEvent->GetId(), ret);
1884         }
1885         return ret;
1886     } else {
1887         pointerEvent->MarkProcessed();
1888     }
1889     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_MOVE ||
1890         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) {
1891         WLOGFD("Session TransferPointEvent, eventId:%{public}d, action:%{public}s, persistentId:%{public}d, "
1892             "bundleName:%{public}s, pid:%{public}d", pointerEvent->GetId(), pointerEvent->DumpPointerAction(),
1893             persistentId_, callingBundleName_.c_str(), callingPid_);
1894     } else {
1895         WLOGFI("Session TransferPointEvent, eventId:%{public}d, action:%{public}s, persistentId:%{public}d, "
1896             "bundleName:%{public}s, pid:%{public}d", pointerEvent->GetId(), pointerEvent->DumpPointerAction(),
1897             persistentId_, callingBundleName_.c_str(), callingPid_);
1898     }
1899     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW ||
1900         pointerAction == MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW ||
1901         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
1902         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
1903         WLOGFD("Action:%{public}s, eventId:%{public}d, report without timer",
1904             pointerEvent->DumpPointerAction(), pointerEvent->GetId());
1905     }
1906     return WSError::WS_OK;
1907 }
1908 
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)1909 WSError Session::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
1910 {
1911     WLOGFD("Session TransferKeyEvent eventId:%{public}d persistentId:%{public}d bundleName:%{public}s pid:%{public}d",
1912         keyEvent->GetId(), persistentId_, callingBundleName_.c_str(), callingPid_);
1913     if (DelayedSingleton<ANRManager>::GetInstance()->IsANRTriggered(persistentId_)) {
1914         WLOGFD("The keyEvent does not report normally, "
1915             "bundleName:%{public}s not response, pid:%{public}d, persistentId:%{public}d",
1916             callingBundleName_.c_str(), callingPid_, persistentId_);
1917         return WSError::WS_DO_NOTHING;
1918     }
1919     if (!windowEventChannel_) {
1920         WLOGFE("windowEventChannel_ is null");
1921         return WSError::WS_ERROR_NULLPTR;
1922     }
1923     WLOGD("TransferKeyEvent, id: %{public}d", persistentId_);
1924     WSError ret = windowEventChannel_->TransferKeyEvent(keyEvent);
1925     if (ret != WSError::WS_OK) {
1926         WLOGFE("TransferKeyEvent failed, ret:%{public}d", ret);
1927         return ret;
1928     }
1929     return WSError::WS_OK;
1930 }
1931 
TransferBackPressedEventForConsumed(bool & isConsumed)1932 WSError Session::TransferBackPressedEventForConsumed(bool& isConsumed)
1933 {
1934     if (!windowEventChannel_) {
1935         WLOGFE("windowEventChannel_ is null");
1936         return WSError::WS_ERROR_NULLPTR;
1937     }
1938     return windowEventChannel_->TransferBackpressedEventForConsumed(isConsumed);
1939 }
1940 
TransferKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed,bool isPreImeEvent)1941 WSError Session::TransferKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed,
1942     bool isPreImeEvent)
1943 {
1944     if (!windowEventChannel_) {
1945         WLOGFE("windowEventChannel_ is null");
1946         return WSError::WS_ERROR_NULLPTR;
1947     }
1948     if (keyEvent == nullptr) {
1949         WLOGFE("KeyEvent is nullptr");
1950         return WSError::WS_ERROR_NULLPTR;
1951     }
1952     return windowEventChannel_->TransferKeyEventForConsumed(keyEvent, isConsumed, isPreImeEvent);
1953 }
1954 
TransferFocusActiveEvent(bool isFocusActive)1955 WSError Session::TransferFocusActiveEvent(bool isFocusActive)
1956 {
1957     if (!windowEventChannel_) {
1958         WLOGFE("windowEventChannel_ is null");
1959         return WSError::WS_ERROR_NULLPTR;
1960     }
1961     return windowEventChannel_->TransferFocusActiveEvent(isFocusActive);
1962 }
1963 
TransferFocusStateEvent(bool focusState)1964 WSError Session::TransferFocusStateEvent(bool focusState)
1965 {
1966     if (!windowEventChannel_) {
1967         if (!IsSystemSession()) {
1968             WLOGFW("windowEventChannel_ is null");
1969         }
1970         return WSError::WS_ERROR_NULLPTR;
1971     }
1972     return windowEventChannel_->TransferFocusState(focusState);
1973 }
1974 
Snapshot(bool runInFfrt,const float scaleParam) const1975 std::shared_ptr<Media::PixelMap> Session::Snapshot(bool runInFfrt, const float scaleParam) const
1976 {
1977     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Snapshot[%d][%s]", persistentId_, sessionInfo_.bundleName_.c_str());
1978     if (scenePersistence_ == nullptr) {
1979         return nullptr;
1980     }
1981     if (!surfaceNode_ || !surfaceNode_->IsBufferAvailable()) {
1982         scenePersistence_->SetHasSnapshot(false);
1983         return nullptr;
1984     }
1985     scenePersistence_->SetHasSnapshot(true);
1986     auto callback = std::make_shared<SurfaceCaptureFuture>();
1987     auto scaleValue = scaleParam == 0.0f ? snapshotScale_ : scaleParam;
1988     RSSurfaceCaptureConfig config = {
1989         .scaleX = scaleValue,
1990         .scaleY = scaleValue,
1991         .useDma = true,
1992         .useCurWindow = false,
1993     };
1994     bool ret = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback, config);
1995     if (!ret) {
1996         TLOGE(WmsLogTag::WMS_MAIN, "TakeSurfaceCapture failed");
1997         return nullptr;
1998     }
1999     constexpr int32_t FFRT_SNAPSHOT_TIMEOUT_MS = 5000;
2000     auto pixelMap = callback->GetResult(runInFfrt ? FFRT_SNAPSHOT_TIMEOUT_MS : SNAPSHOT_TIMEOUT_MS);
2001     if (pixelMap != nullptr) {
2002         TLOGI(WmsLogTag::WMS_MAIN, "Save snapshot WxH = %{public}dx%{public}d, id: %{public}d",
2003             pixelMap->GetWidth(), pixelMap->GetHeight(), persistentId_);
2004         if (notifySessionSnapshotFunc_) {
2005             notifySessionSnapshotFunc_(persistentId_);
2006         }
2007         return pixelMap;
2008     }
2009     TLOGE(WmsLogTag::WMS_MAIN, "Save snapshot failed, id: %{public}d", persistentId_);
2010     return nullptr;
2011 }
2012 
SaveSnapshot(bool useFfrt)2013 void Session::SaveSnapshot(bool useFfrt)
2014 {
2015     if (scenePersistence_ == nullptr) {
2016         return;
2017     }
2018     auto task = [weakThis = wptr(this), runInFfrt = useFfrt]() {
2019         auto session = weakThis.promote();
2020         if (session == nullptr) {
2021             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
2022             return;
2023         }
2024         session->lastLayoutRect_ = session->layoutRect_;
2025         auto pixelMap = session->Snapshot(runInFfrt);
2026         if (pixelMap == nullptr) {
2027             return;
2028         }
2029         {
2030             std::lock_guard<std::mutex> lock(session->snapshotMutex_);
2031             session->snapshot_ = pixelMap;
2032         }
2033         std::function<void()> func = [weakThis]() {
2034             if (auto session = weakThis.promote()) {
2035                 TLOGI(WmsLogTag::WMS_MAIN, "reset snapshot id: %{public}d", session->GetPersistentId());
2036                 std::lock_guard<std::mutex> lock(session->snapshotMutex_);
2037                 session->snapshot_ = nullptr;
2038             }
2039         };
2040         session->scenePersistence_->SaveSnapshot(pixelMap, func);
2041     };
2042     if (!useFfrt) {
2043         task();
2044         return;
2045     }
2046     auto snapshotFfrtHelper = scenePersistence_->GetSnapshotFfrtHelper();
2047     std::string taskName = "Session::SaveSnapshot" + std::to_string(persistentId_);
2048     snapshotFfrtHelper->CancelTask(taskName);
2049     snapshotFfrtHelper->SubmitTask(std::move(task), taskName);
2050 }
2051 
SetSessionStateChangeListenser(const NotifySessionStateChangeFunc & func)2052 void Session::SetSessionStateChangeListenser(const NotifySessionStateChangeFunc& func)
2053 {
2054     auto task = [weakThis = wptr(this), func]() {
2055         auto session = weakThis.promote();
2056         if (session == nullptr) {
2057             WLOGFE("session is null");
2058             return;
2059         }
2060         session->sessionStateChangeFunc_ = func;
2061         auto changedState = session->GetSessionState(); // read and write state should in one thread
2062         if (changedState == SessionState::STATE_ACTIVE) {
2063             changedState = SessionState::STATE_FOREGROUND;
2064         } else if (changedState == SessionState::STATE_INACTIVE) {
2065             changedState = SessionState::STATE_BACKGROUND;
2066         } else if (changedState == SessionState::STATE_DISCONNECT) {
2067             return;
2068         }
2069         session->NotifySessionStateChange(changedState);
2070         TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d, state_: %{public}d, changedState: %{public}d",
2071             session->GetPersistentId(), session->GetSessionState(), changedState);
2072     };
2073     PostTask(task, "SetSessionStateChangeListenser");
2074 }
2075 
SetBufferAvailableChangeListener(const NotifyBufferAvailableChangeFunc & func)2076 void Session::SetBufferAvailableChangeListener(const NotifyBufferAvailableChangeFunc& func)
2077 {
2078     bufferAvailableChangeFunc_ = func;
2079     if (bufferAvailable_ && bufferAvailableChangeFunc_ != nullptr) {
2080         bufferAvailableChangeFunc_(bufferAvailable_);
2081     }
2082     WLOGFD("SetBufferAvailableChangeListener, id: %{public}d", GetPersistentId());
2083 }
2084 
SetAcquireRotateAnimationConfigFunc(const AcquireRotateAnimationConfigFunc & func)2085 void Session::SetAcquireRotateAnimationConfigFunc(const AcquireRotateAnimationConfigFunc& func)
2086 {
2087     if (func == nullptr) {
2088         TLOGI(WmsLogTag::DEFAULT, "func is nullptr");
2089         return;
2090     }
2091     acquireRotateAnimationConfigFunc_ = func;
2092 }
2093 
GetRotateAnimationDuration()2094 int32_t Session::GetRotateAnimationDuration()
2095 {
2096     if (acquireRotateAnimationConfigFunc_) {
2097         RotateAnimationConfig rotateAnimationConfig;
2098         acquireRotateAnimationConfigFunc_(rotateAnimationConfig);
2099         return rotateAnimationConfig.duration_;
2100     }
2101     return ROTATE_ANIMATION_DURATION;
2102 }
2103 
UnregisterSessionChangeListeners()2104 void Session::UnregisterSessionChangeListeners()
2105 {
2106     sessionStateChangeFunc_ = nullptr;
2107     sessionFocusableChangeFunc_ = nullptr;
2108     sessionTouchableChangeFunc_ = nullptr;
2109     clickFunc_ = nullptr;
2110     jsSceneSessionExceptionFunc_ = nullptr;
2111     sessionExceptionFunc_ = nullptr;
2112     terminateSessionFunc_ = nullptr;
2113     pendingSessionActivationFunc_ = nullptr;
2114     changeSessionVisibilityWithStatusBarFunc_ = nullptr;
2115     bufferAvailableChangeFunc_ = nullptr;
2116     backPressedFunc_ = nullptr;
2117     terminateSessionFuncNew_ = nullptr;
2118     terminateSessionFuncTotal_ = nullptr;
2119     updateSessionLabelFunc_ = nullptr;
2120     updateSessionIconFunc_ = nullptr;
2121     pendingSessionToForegroundFunc_ = nullptr;
2122     pendingSessionToBackgroundForDelegatorFunc_ = nullptr;
2123     raiseToTopForPointDownFunc_ = nullptr;
2124     sessionInfoLockedStateChangeFunc_ = nullptr;
2125     contextTransparentFunc_ = nullptr;
2126     sessionRectChangeFunc_ = nullptr;
2127     acquireRotateAnimationConfigFunc_ = nullptr;
2128     WLOGFD("UnregisterSessionChangeListenser, id: %{public}d", GetPersistentId());
2129 }
2130 
SetSessionStateChangeNotifyManagerListener(const NotifySessionStateChangeNotifyManagerFunc & func)2131 void Session::SetSessionStateChangeNotifyManagerListener(const NotifySessionStateChangeNotifyManagerFunc& func)
2132 {
2133     sessionStateChangeNotifyManagerFunc_ = func;
2134     if (state_ == SessionState::STATE_DISCONNECT) {
2135         return;
2136     }
2137     NotifySessionStateChange(state_);
2138 }
2139 
SetSessionInfoChangeNotifyManagerListener(const NotifySessionInfoChangeNotifyManagerFunc & func)2140 void Session::SetSessionInfoChangeNotifyManagerListener(const NotifySessionInfoChangeNotifyManagerFunc& func)
2141 {
2142     sessionInfoChangeNotifyManagerFunc_ = func;
2143 }
2144 
SetRequestFocusStatusNotifyManagerListener(const NotifyRequestFocusStatusNotifyManagerFunc & func)2145 void Session::SetRequestFocusStatusNotifyManagerListener(const NotifyRequestFocusStatusNotifyManagerFunc& func)
2146 {
2147     requestFocusStatusNotifyManagerFunc_ = func;
2148 }
2149 
SetNotifyUIRequestFocusFunc(const NotifyUIRequestFocusFunc & func)2150 void Session::SetNotifyUIRequestFocusFunc(const NotifyUIRequestFocusFunc& func)
2151 {
2152     std::unique_lock<std::shared_mutex> lock(uiRequestFocusMutex_);
2153     requestFocusFunc_ = func;
2154 }
2155 
SetNotifyUILostFocusFunc(const NotifyUILostFocusFunc & func)2156 void Session::SetNotifyUILostFocusFunc(const NotifyUILostFocusFunc& func)
2157 {
2158     std::unique_lock<std::shared_mutex> lock(uiLostFocusMutex_);
2159     lostFocusFunc_ = func;
2160 }
2161 
SetGetStateFromManagerListener(const GetStateFromManagerFunc & func)2162 void Session::SetGetStateFromManagerListener(const GetStateFromManagerFunc& func)
2163 {
2164     getStateFromManagerFunc_ = func;
2165 }
2166 
NotifySessionStateChange(const SessionState & state)2167 void Session::NotifySessionStateChange(const SessionState& state)
2168 {
2169     auto task = [weakThis = wptr(this), state]() {
2170         auto session = weakThis.promote();
2171         if (session == nullptr) {
2172             WLOGFE("session is null");
2173             return;
2174         }
2175         TLOGI(WmsLogTag::WMS_LIFE, "NotifySessionStateChange, [state: %{public}u, persistent: %{public}d]",
2176             static_cast<uint32_t>(state), session->GetPersistentId());
2177         if (session->sessionStateChangeFunc_) {
2178             session->sessionStateChangeFunc_(state);
2179         }
2180 
2181         if (session->sessionStateChangeNotifyManagerFunc_) {
2182             session->sessionStateChangeNotifyManagerFunc_(session->GetPersistentId(), state);
2183         }
2184     };
2185     PostTask(task, "NotifySessionStateChange");
2186 }
2187 
SetSessionFocusableChangeListener(const NotifySessionFocusableChangeFunc & func)2188 void Session::SetSessionFocusableChangeListener(const NotifySessionFocusableChangeFunc& func)
2189 {
2190     sessionFocusableChangeFunc_ = func;
2191     NotifySessionFocusableChange(GetFocusable());
2192 }
2193 
SetSessionTouchableChangeListener(const NotifySessionTouchableChangeFunc & func)2194 void Session::SetSessionTouchableChangeListener(const NotifySessionTouchableChangeFunc& func)
2195 {
2196     sessionTouchableChangeFunc_ = func;
2197     sessionTouchableChangeFunc_(GetTouchable());
2198 }
2199 
SetClickListener(const NotifyClickFunc & func)2200 void Session::SetClickListener(const NotifyClickFunc& func)
2201 {
2202     clickFunc_ = func;
2203 }
2204 
NotifySessionFocusableChange(bool isFocusable)2205 void Session::NotifySessionFocusableChange(bool isFocusable)
2206 {
2207     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, focusable: %{public}u", GetPersistentId(), isFocusable);
2208     if (sessionFocusableChangeFunc_) {
2209         sessionFocusableChangeFunc_(isFocusable);
2210     }
2211 }
2212 
NotifySessionTouchableChange(bool touchable)2213 void Session::NotifySessionTouchableChange(bool touchable)
2214 {
2215     WLOGFD("Notify session touchable change: %{public}d", touchable);
2216     if (sessionTouchableChangeFunc_) {
2217         sessionTouchableChangeFunc_(touchable);
2218     }
2219 }
2220 
NotifyClick()2221 void Session::NotifyClick()
2222 {
2223     WLOGFD("Notify click");
2224     if (clickFunc_) {
2225         clickFunc_();
2226     }
2227 }
2228 
NotifyRequestFocusStatusNotifyManager(bool isFocused,bool byForeground,FocusChangeReason reason)2229 void Session::NotifyRequestFocusStatusNotifyManager(bool isFocused, bool byForeground, FocusChangeReason reason)
2230 {
2231     TLOGD(WmsLogTag::WMS_FOCUS, "NotifyRequestFocusStatusNotifyManager id: %{public}d, focused: %{public}d,\
2232         reason:  %{public}d", GetPersistentId(), isFocused, reason);
2233     if (requestFocusStatusNotifyManagerFunc_) {
2234         requestFocusStatusNotifyManagerFunc_(GetPersistentId(), isFocused, byForeground, reason);
2235     }
2236 }
2237 
GetStateFromManager(const ManagerState key)2238 bool Session::GetStateFromManager(const ManagerState key)
2239 {
2240     if (getStateFromManagerFunc_) {
2241         return getStateFromManagerFunc_(key);
2242     }
2243     switch (key)
2244     {
2245     case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
2246         return false;
2247         break;
2248     default:
2249         return false;
2250     }
2251 }
2252 
NotifyUIRequestFocus()2253 void Session::NotifyUIRequestFocus()
2254 {
2255     WLOGFD("NotifyUIRequestFocus id: %{public}d", GetPersistentId());
2256     std::shared_lock<std::shared_mutex> lock(uiRequestFocusMutex_);
2257     if (requestFocusFunc_) {
2258         requestFocusFunc_();
2259     }
2260 }
2261 
NotifyUILostFocus()2262 void Session::NotifyUILostFocus()
2263 {
2264     WLOGFD("NotifyUILostFocus id: %{public}d", GetPersistentId());
2265     std::shared_lock<std::shared_mutex> lock(uiLostFocusMutex_);
2266     if (lostFocusFunc_) {
2267         lostFocusFunc_();
2268     }
2269 }
2270 
PresentFoucusIfNeed(int32_t pointerAction)2271 void Session::PresentFoucusIfNeed(int32_t pointerAction)
2272 {
2273     WLOGFD("OnClick down, id: %{public}d", GetPersistentId());
2274     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_DOWN ||
2275         pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
2276         if (!isFocused_ && GetFocusable()) {
2277             FocusChangeReason reason = FocusChangeReason::CLICK;
2278             NotifyRequestFocusStatusNotifyManager(true, false, reason);
2279         }
2280         NotifyClick();
2281     }
2282 }
2283 
UpdateFocus(bool isFocused)2284 WSError Session::UpdateFocus(bool isFocused)
2285 {
2286     if (isFocused_ == isFocused) {
2287         TLOGD(WmsLogTag::WMS_FOCUS, "Session focus do not change");
2288         return WSError::WS_DO_NOTHING;
2289     }
2290     isFocused_ = isFocused;
2291     UpdateGestureBackEnabled();
2292     // notify scb arkui focus
2293     if (!isFocused) {
2294         NotifyUILostFocus();
2295     }
2296     return WSError::WS_OK;
2297 }
2298 
NotifyFocusStatus(bool isFocused)2299 WSError Session::NotifyFocusStatus(bool isFocused)
2300 {
2301     if (!IsSessionValid()) {
2302         TLOGW(WmsLogTag::WMS_FOCUS, "Session is invalid, id: %{public}d state: %{public}u",
2303             GetPersistentId(), GetSessionState());
2304         return WSError::WS_ERROR_INVALID_SESSION;
2305     }
2306     if (!sessionStage_) {
2307         return WSError::WS_ERROR_NULLPTR;
2308     }
2309     sessionStage_->UpdateFocus(isFocused);
2310 
2311     return WSError::WS_OK;
2312 }
2313 
RequestFocus(bool isFocused)2314 WSError Session::RequestFocus(bool isFocused)
2315 {
2316     if (!SessionPermission::IsSystemCalling()) {
2317         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
2318         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2319     }
2320     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
2321     NotifyRequestFocusStatusNotifyManager(isFocused, false, reason);
2322     return WSError::WS_OK;
2323 }
2324 
SetCompatibleModeInPc(bool enable,bool isSupportDragInPcCompatibleMode)2325 WSError Session::SetCompatibleModeInPc(bool enable, bool isSupportDragInPcCompatibleMode)
2326 {
2327     TLOGI(WmsLogTag::WMS_SCB, "SetCompatibleModeInPc enable: %{public}d, isSupportDragInPcCompatibleMode: %{public}d",
2328         enable, isSupportDragInPcCompatibleMode);
2329     auto property = GetSessionProperty();
2330     if (property == nullptr) {
2331         TLOGE(WmsLogTag::WMS_SCB, "id: %{public}d property is nullptr", persistentId_);
2332         return WSError::WS_ERROR_NULLPTR;
2333     }
2334 
2335     property->SetCompatibleModeInPc(enable);
2336     property->SetIsSupportDragInPcCompatibleMode(isSupportDragInPcCompatibleMode);
2337     if (enable) {
2338         property->SetDragEnabled(isSupportDragInPcCompatibleMode);
2339     }
2340     return WSError::WS_OK;
2341 }
2342 
SetCompatibleModeEnableInPad(bool enable)2343 WSError Session::SetCompatibleModeEnableInPad(bool enable)
2344 {
2345     TLOGI(WmsLogTag::WMS_SCB, "id: %{public}d, enable: %{public}d", persistentId_, enable);
2346     if (!IsSessionValid()) {
2347         TLOGW(WmsLogTag::WMS_SCB, "Session is invalid, id: %{public}d state: %{public}u",
2348             GetPersistentId(), GetSessionState());
2349         return WSError::WS_ERROR_INVALID_SESSION;
2350     }
2351     auto property = GetSessionProperty();
2352     if (!property) {
2353         TLOGE(WmsLogTag::WMS_SCB, "id: %{public}d property is nullptr", persistentId_);
2354         return WSError::WS_ERROR_NULLPTR;
2355     }
2356     property->SetCompatibleModeEnableInPad(enable);
2357 
2358     if (!sessionStage_) {
2359         TLOGE(WmsLogTag::WMS_SCB, "sessionStage is null");
2360         return WSError::WS_ERROR_NULLPTR;
2361     }
2362     return sessionStage_->NotifyCompatibleModeEnableInPad(enable);
2363 }
2364 
SetCompatibleWindowSizeInPc(int32_t portraitWidth,int32_t portraitHeight,int32_t landscapeWidth,int32_t landscapeHeight)2365 WSError Session::SetCompatibleWindowSizeInPc(int32_t portraitWidth, int32_t portraitHeight,
2366     int32_t landscapeWidth, int32_t landscapeHeight)
2367 {
2368     TLOGI(WmsLogTag::WMS_SCB, "compatible size: [%{public}d, %{public}d, %{public}d, %{public}d]",
2369         portraitWidth, portraitHeight, landscapeWidth, landscapeHeight);
2370     auto property = GetSessionProperty();
2371     if (property == nullptr) {
2372         TLOGE(WmsLogTag::WMS_SCB, "id: %{public}d property is nullptr", persistentId_);
2373         return WSError::WS_ERROR_NULLPTR;
2374     }
2375     property->SetCompatibleWindowSizeInPc(portraitWidth, portraitHeight, landscapeWidth, landscapeHeight);
2376     return WSError::WS_OK;
2377 }
2378 
SetIsPcAppInPad(bool enable)2379 WSError Session::SetIsPcAppInPad(bool enable)
2380 {
2381     TLOGI(WmsLogTag::WMS_SCB, "SetIsPcAppInPad enable: %{public}d", enable);
2382     auto property = GetSessionProperty();
2383     if (property == nullptr) {
2384         TLOGE(WmsLogTag::WMS_SCB, "id: %{public}d property is nullptr", persistentId_);
2385         return WSError::WS_ERROR_NULLPTR;
2386     }
2387     property->SetIsPcAppInPad(enable);
2388     return WSError::WS_OK;
2389 }
2390 
UpdateWindowMode(WindowMode mode)2391 WSError Session::UpdateWindowMode(WindowMode mode)
2392 {
2393     WLOGFD("Session update window mode, id: %{public}d, mode: %{public}d", GetPersistentId(),
2394         static_cast<int32_t>(mode));
2395     auto property = GetSessionProperty();
2396     if (property == nullptr) {
2397         WLOGFD("id: %{public}d property is nullptr", persistentId_);
2398         return WSError::WS_ERROR_NULLPTR;
2399     }
2400     if (state_ == SessionState::STATE_END) {
2401         WLOGFI("session is already destroyed or property is nullptr! id: %{public}d state: %{public}u",
2402             GetPersistentId(), GetSessionState());
2403         return WSError::WS_ERROR_INVALID_SESSION;
2404     } else if (state_ == SessionState::STATE_DISCONNECT) {
2405         property->SetWindowMode(mode);
2406         property->SetIsNeedUpdateWindowMode(true);
2407         UpdateGestureBackEnabled();
2408     } else {
2409         property->SetWindowMode(mode);
2410         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
2411             property->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
2412             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
2413                 surfaceNode_->MarkUifirstNode(false);
2414             }
2415         } else {
2416             surfaceNode_->MarkUifirstNode(true);
2417         }
2418         UpdateGestureBackEnabled();
2419         UpdateGravityWhenUpdateWindowMode(mode);
2420         if (!sessionStage_) {
2421             return WSError::WS_ERROR_NULLPTR;
2422         }
2423         return sessionStage_->UpdateWindowMode(mode);
2424     }
2425     return WSError::WS_OK;
2426 }
2427 
UpdateGravityWhenUpdateWindowMode(WindowMode mode)2428 void Session::UpdateGravityWhenUpdateWindowMode(WindowMode mode)
2429 {
2430     if ((systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.IsFreeMultiWindowMode()) && surfaceNode_ != nullptr) {
2431         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
2432             surfaceNode_->SetFrameGravity(Gravity::LEFT);
2433         } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
2434             surfaceNode_->SetFrameGravity(Gravity::RIGHT);
2435         } else if (mode == WindowMode::WINDOW_MODE_FLOATING || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2436             surfaceNode_->SetFrameGravity(Gravity::RESIZE);
2437         }
2438     }
2439 }
2440 
SetSystemSceneBlockingFocus(bool blocking)2441 WSError Session::SetSystemSceneBlockingFocus(bool blocking)
2442 {
2443     TLOGW(WmsLogTag::WMS_FOCUS, "Session set blocking focus, id: %{public}d, mode: %{public}d, Session is not system.",
2444         GetPersistentId(), blocking);
2445     return WSError::WS_ERROR_INVALID_SESSION;
2446 }
2447 
GetBlockingFocus() const2448 bool Session::GetBlockingFocus() const
2449 {
2450     return blockingFocus_;
2451 }
2452 
SetSessionProperty(const sptr<WindowSessionProperty> & property)2453 WSError Session::SetSessionProperty(const sptr<WindowSessionProperty>& property)
2454 {
2455     {
2456         std::unique_lock<std::shared_mutex> lock(propertyMutex_);
2457         property_ = property;
2458     }
2459     NotifySessionInfoChange();
2460     if (property == nullptr) {
2461         return WSError::WS_OK;
2462     }
2463     auto hotAreasChangeCallback = [weakThis = wptr(this)]() {
2464         auto session = weakThis.promote();
2465         if (session == nullptr) {
2466             WLOGFE("session is nullptr");
2467             return;
2468         }
2469         session->NotifySessionInfoChange();
2470     };
2471     property->SetSessionPropertyChangeCallback(hotAreasChangeCallback);
2472     return WSError::WS_OK;
2473 }
2474 
GetSessionProperty() const2475 sptr<WindowSessionProperty> Session::GetSessionProperty() const
2476 {
2477     std::shared_lock<std::shared_mutex> lock(propertyMutex_);
2478     return property_;
2479 }
2480 
RectSizeCheckProcess(uint32_t curWidth,uint32_t curHeight,uint32_t minWidth,uint32_t minHeight,uint32_t maxFloatingWindowSize)2481 void Session::RectSizeCheckProcess(uint32_t curWidth, uint32_t curHeight, uint32_t minWidth,
2482     uint32_t minHeight, uint32_t maxFloatingWindowSize)
2483 {
2484     if ((curWidth < minWidth) || (curWidth > maxFloatingWindowSize) ||
2485         (curHeight < minHeight) || (curHeight > maxFloatingWindowSize)) {
2486         TLOGE(WmsLogTag::WMS_LAYOUT, "RectCheck err sessionID: %{public}d rect %{public}s",
2487             GetPersistentId(), GetSessionRect().ToString().c_str());
2488         std::ostringstream oss;
2489         oss << " RectCheck err size ";
2490         oss << " cur persistentId: " << GetPersistentId() << ",";
2491         oss << " windowType: " << static_cast<uint32_t>(GetWindowType()) << ",";
2492         auto property = GetSessionProperty();
2493         if (property) {
2494             oss << " windowName: " << property->GetWindowName() << ",";
2495             oss << " windowState: " << static_cast<uint32_t>(property->GetWindowState()) << ",";
2496         }
2497         oss << " curWidth: " << curWidth << ",";
2498         oss << " curHeight: " << curHeight << ",";
2499         oss << " minWidth: " << minWidth << ",";
2500         oss << " minHeight: " << minHeight << ",";
2501         oss << " maxFloatingWindowSize: " << maxFloatingWindowSize << ",";
2502         oss << " sessionRect: " << GetSessionRect().ToString() << ";";
2503         WindowInfoReporter::GetInstance().ReportWindowException(
2504             static_cast<int32_t>(WindowDFXHelperType::WINDOW_RECT_CHECK), getpid(), oss.str());
2505     }
2506 }
2507 
RectCheckProcess()2508 void Session::RectCheckProcess()
2509 {
2510     if (!(IsSessionForeground() || isVisible_)) {
2511         return;
2512     }
2513     auto property = GetSessionProperty();
2514     if (!property) {
2515         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2516         return;
2517     }
2518     auto displayId = property->GetDisplayId();
2519     std::map<ScreenId, ScreenProperty> screensProperties =
2520         Rosen::ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
2521     if (screensProperties.find(displayId) == screensProperties.end()) {
2522         return;
2523     }
2524     auto screenProperty = screensProperties[displayId];
2525     float density = screenProperty.GetDensity();
2526     if (!NearZero(density) && !NearZero(GetSessionRect().height_)) {
2527         float curWidth = GetSessionRect().width_ / density;
2528         float curHeight = GetSessionRect().height_ / density;
2529         float ratio = GetAspectRatio();
2530         float actRatio = curWidth / curHeight;
2531         if ((ratio != 0) && !NearEqual(ratio, actRatio)) {
2532             TLOGE(WmsLogTag::WMS_LAYOUT, "RectCheck err ratio %{public}f != actRatio: %{public}f", ratio, actRatio);
2533             std::ostringstream oss;
2534             oss << " RectCheck err ratio ";
2535             oss << " cur persistentId: " << GetPersistentId() << ",";
2536             oss << " windowType: " << static_cast<uint32_t>(GetWindowType()) << ",";
2537             oss << " windowName: " << property->GetWindowName() << ",";
2538             oss << " windowState: " << static_cast<uint32_t>(property->GetWindowState()) << ",";
2539             oss << " curWidth: " << curWidth << ",";
2540             oss << " curHeight: " << curHeight << ",";
2541             oss << " setting ratio: " << ratio << ",";
2542             oss << " sessionRect: " << GetSessionRect().ToString() << ";";
2543             WindowInfoReporter::GetInstance().ReportWindowException(
2544                 static_cast<int32_t>(WindowDFXHelperType::WINDOW_RECT_CHECK), getpid(), oss.str());
2545         }
2546         RectCheck(curWidth, curHeight);
2547     }
2548 }
2549 
SetSessionRect(const WSRect & rect)2550 void Session::SetSessionRect(const WSRect& rect)
2551 {
2552     if (winRect_ == rect) {
2553         WLOGFW("id: %{public}d skip same rect", persistentId_);
2554         return;
2555     }
2556     winRect_ = rect;
2557     dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
2558     RectCheckProcess();
2559 }
2560 
GetSessionRect() const2561 WSRect Session::GetSessionRect() const
2562 {
2563     return winRect_;
2564 }
2565 
2566 /** @note @window.layout */
GetGlobalScaledRect(Rect & globalScaledRect)2567 WMError Session::GetGlobalScaledRect(Rect& globalScaledRect)
2568 {
2569     auto task = [weakThis = wptr(this), &globalScaledRect] {
2570         auto session = weakThis.promote();
2571         if (!session) {
2572             TLOGNE(WmsLogTag::WMS_LAYOUT, "session is null");
2573             return WMError::WM_ERROR_DESTROYED_OBJECT;
2574         }
2575         WSRect scaledRect = session->GetSessionGlobalRect();
2576         scaledRect.width_ *= session->scaleX_;
2577         scaledRect.height_ *= session->scaleY_;
2578         globalScaledRect = { scaledRect.posX_, scaledRect.posY_, scaledRect.width_, scaledRect.height_ };
2579         TLOGNI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d globalScaledRect:%{public}s",
2580             session->GetPersistentId(), globalScaledRect.ToString().c_str());
2581         return WMError::WM_OK;
2582     };
2583     return PostSyncTask(task, __func__);
2584 }
2585 
GetSessionGlobalRect() const2586 WSRect Session::GetSessionGlobalRect() const
2587 {
2588     if (IsScbCoreEnabled()) {
2589         std::lock_guard<std::mutex> lock(globalRectMutex_);
2590         return globalRect_;
2591     }
2592     return winRect_;
2593 }
2594 
2595 /** @note @window.layout */
SetSessionGlobalRect(const WSRect & rect)2596 void Session::SetSessionGlobalRect(const WSRect& rect)
2597 {
2598     std::lock_guard<std::mutex> lock(globalRectMutex_);
2599     if (globalRect_ != rect) {
2600         dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::GLOBAL_RECT);
2601     }
2602     globalRect_ = rect;
2603 }
2604 
2605 /** @note @window.layout */
GetLastLayoutRect() const2606 WSRect Session::GetLastLayoutRect() const
2607 {
2608     return lastLayoutRect_;
2609 }
2610 
GetLayoutRect() const2611 WSRect Session::GetLayoutRect() const
2612 {
2613     return layoutRect_;
2614 }
2615 
SetSessionRequestRect(const WSRect & rect)2616 void Session::SetSessionRequestRect(const WSRect& rect)
2617 {
2618     auto property = GetSessionProperty();
2619     if (property == nullptr) {
2620         WLOGFD("id: %{public}d property is nullptr", persistentId_);
2621         return;
2622     }
2623     property->SetRequestRect(SessionHelper::TransferToRect(rect));
2624     WLOGFD("is: %{public}d, rect: [%{public}d, %{public}d, %{public}u, %{public}u]", persistentId_,
2625         rect.posX_, rect.posY_, rect.width_, rect.height_);
2626 }
2627 
GetSessionRequestRect() const2628 WSRect Session::GetSessionRequestRect() const
2629 {
2630     WSRect rect;
2631     auto property = GetSessionProperty();
2632     if (property == nullptr) {
2633         WLOGFD("id: %{public}d property is nullptr", persistentId_);
2634         return rect;
2635     }
2636     rect = SessionHelper::TransferToWSRect(property->GetRequestRect());
2637     WLOGFD("id: %{public}d, rect: %{public}s", persistentId_, rect.ToString().c_str());
2638     return rect;
2639 }
2640 
2641 /** @note @window.layout */
SetClientRect(const WSRect & rect)2642 void Session::SetClientRect(const WSRect& rect)
2643 {
2644     clientRect_ = rect;
2645     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, update client rect:%{public}s",
2646         GetPersistentId(), rect.ToString().c_str());
2647 }
2648 
2649 /** @note @window.layout */
GetClientRect() const2650 WSRect Session::GetClientRect() const
2651 {
2652     return clientRect_;
2653 }
2654 
SetUseStartingWindowAboveLocked(bool useStartingWindowAboveLocked)2655 void Session::SetUseStartingWindowAboveLocked(bool useStartingWindowAboveLocked)
2656 {
2657     useStartingWindowAboveLocked_ = useStartingWindowAboveLocked;
2658 }
2659 
UseStartingWindowAboveLocked() const2660 bool Session::UseStartingWindowAboveLocked() const
2661 {
2662     return useStartingWindowAboveLocked_;
2663 }
2664 
GetWindowType() const2665 WindowType Session::GetWindowType() const
2666 {
2667     auto property = GetSessionProperty();
2668     if (property) {
2669         return property->GetWindowType();
2670     }
2671     return WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
2672 }
2673 
GetWindowName() const2674 std::string Session::GetWindowName() const
2675 {
2676     if (GetSessionInfo().isSystem_) {
2677         return GetSessionInfo().abilityName_;
2678     } else {
2679         auto property = GetSessionProperty();
2680         return property ? property->GetWindowName() : "";
2681     }
2682 }
2683 
SetSystemConfig(const SystemSessionConfig & systemConfig)2684 void Session::SetSystemConfig(const SystemSessionConfig& systemConfig)
2685 {
2686     systemConfig_ = systemConfig;
2687 }
2688 
GetSystemConfig() const2689 SystemSessionConfig Session::GetSystemConfig() const
2690 {
2691     return systemConfig_;
2692 }
2693 
SetSnapshotScale(const float snapshotScale)2694 void Session::SetSnapshotScale(const float snapshotScale)
2695 {
2696     snapshotScale_ = snapshotScale;
2697 }
2698 
ProcessBackEvent()2699 WSError Session::ProcessBackEvent()
2700 {
2701     if (!IsSessionValid()) {
2702         TLOGW(WmsLogTag::WMS_EVENT, "Session is invalid, id: %{public}d state: %{public}u",
2703             GetPersistentId(), GetSessionState());
2704         return WSError::WS_ERROR_INVALID_SESSION;
2705     }
2706     if (!sessionStage_) {
2707         TLOGE(WmsLogTag::WMS_EVENT, "session stage is nullptr");
2708         return WSError::WS_ERROR_NULLPTR;
2709     }
2710     return sessionStage_->HandleBackEvent();
2711 }
2712 
MarkProcessed(int32_t eventId)2713 WSError Session::MarkProcessed(int32_t eventId)
2714 {
2715     int32_t persistentId = GetPersistentId();
2716     WLOGFI("InputTracking persistentId:%{public}d, eventId:%{public}d", persistentId, eventId);
2717     DelayedSingleton<ANRManager>::GetInstance()->MarkProcessed(eventId, persistentId);
2718     return WSError::WS_OK;
2719 }
2720 
GeneratePersistentId(bool isExtension,int32_t persistentId)2721 void Session::GeneratePersistentId(bool isExtension, int32_t persistentId)
2722 {
2723     std::lock_guard lock(g_persistentIdSetMutex);
2724     if (persistentId != INVALID_SESSION_ID  && !g_persistentIdSet.count(persistentId)) {
2725         g_persistentIdSet.insert(persistentId);
2726         persistentId_ = persistentId;
2727         return;
2728     }
2729 
2730     if (g_persistentId == INVALID_SESSION_ID) {
2731         g_persistentId++; // init non system session id from 2
2732     }
2733 
2734     g_persistentId++;
2735     while (g_persistentIdSet.count(g_persistentId)) {
2736         g_persistentId++;
2737     }
2738     if (isExtension) {
2739         constexpr uint32_t pidLength = 18;
2740         constexpr uint32_t pidMask = (1 << pidLength) - 1;
2741         constexpr uint32_t persistentIdLength = 12;
2742         constexpr uint32_t persistentIdMask = (1 << persistentIdLength) - 1;
2743         uint32_t assembledPersistentId = ((static_cast<uint32_t>(getpid()) & pidMask) << persistentIdLength) |
2744             (static_cast<uint32_t>(g_persistentId.load()) & persistentIdMask);
2745         persistentId_ = assembledPersistentId | 0x40000000;
2746     } else {
2747         persistentId_ = static_cast<uint32_t>(g_persistentId.load()) & 0x3fffffff;
2748     }
2749     g_persistentIdSet.insert(g_persistentId);
2750     TLOGI(WmsLogTag::WMS_LIFE,
2751           "persistentId: %{public}d, persistentId_: %{public}d", persistentId, persistentId_);
2752 }
2753 
GetScenePersistence() const2754 sptr<ScenePersistence> Session::GetScenePersistence() const
2755 {
2756     return scenePersistence_;
2757 }
2758 
CheckEmptyKeyboardAvoidAreaIfNeeded() const2759 bool Session::CheckEmptyKeyboardAvoidAreaIfNeeded() const
2760 {
2761     bool isMainFloating =
2762         GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && WindowHelper::IsMainWindow(GetWindowType());
2763     bool isParentFloating = WindowHelper::IsSubWindow(GetWindowType()) && GetParentSession() != nullptr &&
2764         GetParentSession()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
2765     bool isMidScene = GetIsMidScene();
2766     bool isPhoneOrPadNotFreeMultiWindow =
2767         systemConfig_.uiType_ == UI_TYPE_PHONE || (systemConfig_.uiType_ == UI_TYPE_PAD &&
2768                                                    !systemConfig_.IsFreeMultiWindowMode());
2769     return (isMainFloating || isParentFloating) && !isMidScene && isPhoneOrPadNotFreeMultiWindow;
2770 }
2771 
NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,const std::shared_ptr<RSTransaction> & rsTransaction)2772 void Session::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,
2773                                            const std::shared_ptr<RSTransaction>& rsTransaction)
2774 {
2775     if (!sessionStage_) {
2776         TLOGD(WmsLogTag::WMS_KEYBOARD, "session stage is nullptr");
2777         return;
2778     }
2779     if (CheckEmptyKeyboardAvoidAreaIfNeeded()) {
2780         info = sptr<OccupiedAreaChangeInfo>::MakeSptr();
2781         TLOGD(WmsLogTag::WMS_KEYBOARD, "Occupied area needs to be empty when in floating mode");
2782     }
2783     sessionStage_->NotifyOccupiedAreaChangeInfo(info, rsTransaction);
2784 }
2785 
GetWindowMode() const2786 WindowMode Session::GetWindowMode() const
2787 {
2788     auto property = GetSessionProperty();
2789     if (property == nullptr) {
2790         WLOGFW("null property.");
2791         return WindowMode::WINDOW_MODE_UNDEFINED;
2792     }
2793     return property->GetWindowMode();
2794 }
2795 
UpdateMaximizeMode(bool isMaximize)2796 WSError Session::UpdateMaximizeMode(bool isMaximize)
2797 {
2798     WLOGFD("Session update maximize mode, isMaximize: %{public}d", isMaximize);
2799     if (!IsSessionValid()) {
2800         TLOGW(WmsLogTag::WMS_LAYOUT, "Session is invalid, id: %{public}d state: %{public}u",
2801             GetPersistentId(), GetSessionState());
2802         return WSError::WS_ERROR_INVALID_SESSION;
2803     }
2804     MaximizeMode mode = MaximizeMode::MODE_RECOVER;
2805     if (isMaximize) {
2806         mode = MaximizeMode::MODE_AVOID_SYSTEM_BAR;
2807     } else if (GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
2808         mode = MaximizeMode::MODE_FULL_FILL;
2809     }
2810     auto property = GetSessionProperty();
2811     if (property == nullptr) {
2812         TLOGE(WmsLogTag::WMS_EVENT, "property is null");
2813         return WSError::WS_ERROR_NULLPTR;
2814     }
2815     property->SetMaximizeMode(mode);
2816     if (!sessionStage_) {
2817         TLOGE(WmsLogTag::WMS_MAIN, "sessionStage_ is null");
2818         return WSError::WS_ERROR_NULLPTR;
2819     }
2820     return sessionStage_->UpdateMaximizeMode(mode);
2821 }
2822 
2823 /** @note @window.hierarchy */
SetZOrder(uint32_t zOrder)2824 void Session::SetZOrder(uint32_t zOrder)
2825 {
2826     lastZOrder_ = zOrder_;
2827     zOrder_ = zOrder;
2828     NotifySessionInfoChange();
2829 }
2830 
2831 /** @note @window.hierarchy */
GetZOrder() const2832 uint32_t Session::GetZOrder() const
2833 {
2834     return zOrder_;
2835 }
2836 
2837 /** @note @window.hierarchy */
GetLastZOrder() const2838 uint32_t Session::GetLastZOrder() const
2839 {
2840     return lastZOrder_;
2841 }
2842 
SetUINodeId(uint32_t uiNodeId)2843 void Session::SetUINodeId(uint32_t uiNodeId)
2844 {
2845     if (uiNodeId_ != 0 && uiNodeId != 0 && !IsSystemSession() && SessionPermission::IsBetaVersion()) {
2846         int32_t eventRet = HiSysEventWrite(
2847             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
2848             "REPEAT_SET_UI_NODE_ID",
2849             OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
2850             "PID", getpid(),
2851             "UID", getuid());
2852         TLOGE(WmsLogTag::WMS_LIFE, " SetUINodeId: Repeat set UINodeId ret:%{public}d", eventRet);
2853         return;
2854     }
2855     uiNodeId_ = uiNodeId;
2856 }
2857 
GetUINodeId() const2858 uint32_t Session::GetUINodeId() const
2859 {
2860     return uiNodeId_;
2861 }
2862 
SetShowRecent(bool showRecent)2863 void Session::SetShowRecent(bool showRecent)
2864 {
2865     TLOGI(WmsLogTag::WMS_MAIN, "in recents: %{public}d, id: %{public}d", showRecent, persistentId_);
2866     bool isAttach = GetAttachState();
2867     if (!IsSupportDetectWindow(isAttach) ||
2868         !ShouldCreateDetectTaskInRecent(showRecent, showRecent_, isAttach)) {
2869         showRecent_ = showRecent;
2870         return;
2871     }
2872     showRecent_ = showRecent;
2873     WindowMode windowMode = GetWindowMode();
2874     if (!showRecent_ && ShouldCreateDetectTask(isAttach, windowMode)) {
2875         CreateWindowStateDetectTask(isAttach, windowMode);
2876     }
2877 }
2878 
GetShowRecent() const2879 bool Session::GetShowRecent() const
2880 {
2881     return showRecent_;
2882 }
2883 
GetAttachState() const2884 bool Session::GetAttachState() const
2885 {
2886     return isAttach_;
2887 }
2888 
GetDetectTaskInfo() const2889 DetectTaskInfo Session::GetDetectTaskInfo() const
2890 {
2891     std::shared_lock<std::shared_mutex> lock(detectTaskInfoMutex_);
2892     return detectTaskInfo_;
2893 }
2894 
SetDetectTaskInfo(const DetectTaskInfo & detectTaskInfo)2895 void Session::SetDetectTaskInfo(const DetectTaskInfo& detectTaskInfo)
2896 {
2897     std::unique_lock<std::shared_mutex> lock(detectTaskInfoMutex_);
2898     detectTaskInfo_ = detectTaskInfo;
2899 }
2900 
IsStateMatch(bool isAttach) const2901 bool Session::IsStateMatch(bool isAttach) const
2902 {
2903     return isAttach ? ATTACH_MAP.at(GetSessionState()) : DETACH_MAP.at(GetSessionState());
2904 }
2905 
IsSupportDetectWindow(bool isAttach)2906 bool Session::IsSupportDetectWindow(bool isAttach)
2907 {
2908     bool isPc = systemConfig_.uiType_ == UI_TYPE_PC;
2909     bool isPhone = systemConfig_.uiType_ == UI_TYPE_PHONE;
2910     if (!isPc && !isPhone) {
2911         TLOGI(WmsLogTag::WMS_LIFE, "device type not support, id:%{public}d", persistentId_);
2912         return false;
2913     }
2914     if (isScreenLockedCallback_ && isScreenLockedCallback_()) {
2915         TLOGI(WmsLogTag::WMS_LIFE, "screen locked, id:%{public}d", persistentId_);
2916         return false;
2917     }
2918     if (!SessionHelper::IsMainWindow(GetWindowType())) {
2919         TLOGI(WmsLogTag::WMS_LIFE, "only support main window, id:%{public}d", persistentId_);
2920         return false;
2921     }
2922     // Only detecting cold start scenarios on PC
2923     if (isPc && (!isAttach || state_ != SessionState::STATE_DISCONNECT)) {
2924         TLOGI(WmsLogTag::WMS_LIFE, "pc only support cold start, id:%{public}d", persistentId_);
2925         RemoveWindowDetectTask();
2926         return false;
2927     }
2928     return true;
2929 }
2930 
RemoveWindowDetectTask()2931 void Session::RemoveWindowDetectTask()
2932 {
2933     if (handler_) {
2934         handler_->RemoveTask(GetWindowDetectTaskName());
2935     }
2936 }
2937 
ShouldCreateDetectTask(bool isAttach,WindowMode windowMode) const2938 bool Session::ShouldCreateDetectTask(bool isAttach, WindowMode windowMode) const
2939 {
2940     // Create detect task directy without pre-exiting tasks.
2941     if (GetDetectTaskInfo().taskState == DetectTaskState::NO_TASK) {
2942         return true;
2943     }
2944     // If the taskState matches the attach detach state, it will be create detect task directly.
2945     if ((GetDetectTaskInfo().taskState == DetectTaskState::ATTACH_TASK && isAttach) ||
2946         (GetDetectTaskInfo().taskState == DetectTaskState::DETACH_TASK && !isAttach)) {
2947         return true;
2948     } else {
2949         // Do not create detect task if the windowMode changes.
2950         return GetDetectTaskInfo().taskWindowMode == windowMode;
2951     }
2952 }
2953 
ShouldCreateDetectTaskInRecent(bool newShowRecent,bool oldShowRecent,bool isAttach) const2954 bool Session::ShouldCreateDetectTaskInRecent(bool newShowRecent, bool oldShowRecent, bool isAttach) const
2955 {
2956     if (newShowRecent) {
2957         return false;
2958     }
2959     return oldShowRecent ? isAttach : false;
2960 }
2961 
RegisterIsScreenLockedCallback(const std::function<bool ()> & callback)2962 void Session::RegisterIsScreenLockedCallback(const std::function<bool()>& callback)
2963 {
2964     isScreenLockedCallback_ = callback;
2965 }
2966 
GetWindowDetectTaskName() const2967 std::string Session::GetWindowDetectTaskName() const
2968 {
2969     return "wms:WindowStateDetect" + std::to_string(persistentId_);
2970 }
2971 
CreateWindowStateDetectTask(bool isAttach,WindowMode windowMode)2972 void Session::CreateWindowStateDetectTask(bool isAttach, WindowMode windowMode)
2973 {
2974     if (!handler_) {
2975         return;
2976     }
2977     std::string taskName = GetWindowDetectTaskName();
2978     RemoveWindowDetectTask();
2979     auto detectTask = [weakThis = wptr(this), isAttach]() {
2980         auto session = weakThis.promote();
2981         if (session == nullptr) {
2982             if (isAttach) {
2983                 TLOGE(WmsLogTag::WMS_LIFE, "Window attach state and session"
2984                     "state mismatch, session is nullptr, attach:%{public}d", isAttach);
2985             }
2986             return;
2987         }
2988         // Skip state detect when screen locked.
2989         if (session->isScreenLockedCallback_ && !session->isScreenLockedCallback_()) {
2990             if (!session->IsStateMatch(isAttach)) {
2991                 TLOGE(WmsLogTag::WMS_LIFE, "Window attach state and session state mismatch, "
2992                     "attach:%{public}d, sessioniState:%{public}d, persistenId:%{public}d, bundleName:%{public}s",
2993                     isAttach, static_cast<uint32_t>(session->GetSessionState()),
2994                     session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str());
2995             }
2996         }
2997         DetectTaskInfo detectTaskInfo;
2998         session->SetDetectTaskInfo(detectTaskInfo);
2999     };
3000     handler_->PostTask(detectTask, taskName, STATE_DETECT_DELAYTIME);
3001     DetectTaskInfo detectTaskInfo;
3002     detectTaskInfo.taskWindowMode = windowMode;
3003     detectTaskInfo.taskState = isAttach ? DetectTaskState::ATTACH_TASK : DetectTaskState::DETACH_TASK;
3004     SetDetectTaskInfo(detectTaskInfo);
3005 }
3006 
SetBufferAvailable(bool bufferAvailable)3007 void Session::SetBufferAvailable(bool bufferAvailable)
3008 {
3009     WLOGFI("SetBufferAvailable: %{public}d", bufferAvailable);
3010     if (bufferAvailableChangeFunc_) {
3011         bufferAvailableChangeFunc_(bufferAvailable);
3012     }
3013     bufferAvailable_ = bufferAvailable;
3014 }
3015 
GetBufferAvailable() const3016 bool Session::GetBufferAvailable() const
3017 {
3018     return bufferAvailable_;
3019 }
3020 
SetNeedSnapshot(bool needSnapshot)3021 void Session::SetNeedSnapshot(bool needSnapshot)
3022 {
3023     needSnapshot_ = needSnapshot;
3024 }
3025 
SetExitSplitOnBackground(bool isExitSplitOnBackground)3026 void Session::SetExitSplitOnBackground(bool isExitSplitOnBackground)
3027 {
3028     TLOGW(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, SetExitSplitOnBackground not implement", persistentId_);
3029 }
3030 
IsExitSplitOnBackground() const3031 bool Session::IsExitSplitOnBackground() const
3032 {
3033     TLOGW(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, IsExitSplitOnBackground not implement", persistentId_);
3034     return false;
3035 }
3036 
SetFloatingScale(float floatingScale)3037 void Session::SetFloatingScale(float floatingScale)
3038 {
3039     floatingScale_ = floatingScale;
3040 }
3041 
GetFloatingScale() const3042 float Session::GetFloatingScale() const
3043 {
3044     return floatingScale_;
3045 }
3046 
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)3047 void Session::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
3048 {
3049     scaleX_ = scaleX;
3050     scaleY_ = scaleY;
3051     pivotX_ = pivotX;
3052     pivotY_ = pivotY;
3053 }
3054 
SetClientScale(float scaleX,float scaleY,float pivotX,float pivotY)3055 void Session::SetClientScale(float scaleX, float scaleY, float pivotX, float pivotY)
3056 {
3057     TLOGD(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, preScaleX:%{public}f, preScaleY:%{public}f, "
3058         "newScaleX:%{public}f, newScaleY:%{public}f", GetPersistentId(), clientScaleX_, clientScaleY_, scaleX, scaleY);
3059     clientScaleX_ = scaleX;
3060     clientScaleY_ = scaleY;
3061     clientPivotX_ = pivotX;
3062     clientPivotY_ = pivotY;
3063 }
3064 
GetScaleX() const3065 float Session::GetScaleX() const
3066 {
3067     return scaleX_;
3068 }
3069 
GetScaleY() const3070 float Session::GetScaleY() const
3071 {
3072     return scaleY_;
3073 }
3074 
GetPivotX() const3075 float Session::GetPivotX() const
3076 {
3077     return pivotX_;
3078 }
3079 
GetPivotY() const3080 float Session::GetPivotY() const
3081 {
3082     return pivotY_;
3083 }
3084 
SetSCBKeepKeyboard(bool scbKeepKeyboardFlag)3085 void Session::SetSCBKeepKeyboard(bool scbKeepKeyboardFlag)
3086 {
3087     scbKeepKeyboardFlag_ = scbKeepKeyboardFlag;
3088 }
3089 
GetSCBKeepKeyboardFlag() const3090 bool Session::GetSCBKeepKeyboardFlag() const
3091 {
3092     return scbKeepKeyboardFlag_;
3093 }
3094 
SetOffset(float x,float y)3095 void Session::SetOffset(float x, float y)
3096 {
3097     offsetX_ = x;
3098     offsetY_ = y;
3099     WSRect newRect {
3100         .posX_ = std::round(bounds_.posX_ + x),
3101         .posY_ = std::round(bounds_.posY_ + y),
3102         .width_ = std::round(bounds_.width_),
3103         .height_ = std::round(bounds_.height_),
3104     };
3105     if (newRect != winRect_) {
3106         UpdateRect(newRect, SizeChangeReason::UNDEFINED, "SetOffset");
3107     }
3108 }
3109 
GetOffsetX() const3110 float Session::GetOffsetX() const
3111 {
3112     return offsetX_;
3113 }
3114 
GetOffsetY() const3115 float Session::GetOffsetY() const
3116 {
3117     return offsetY_;
3118 }
3119 
SetBounds(const WSRectF & bounds)3120 void Session::SetBounds(const WSRectF& bounds)
3121 {
3122     bounds_ = bounds;
3123 }
3124 
GetBounds()3125 WSRectF Session::GetBounds()
3126 {
3127     return bounds_;
3128 }
3129 
SetRotation(Rotation rotation)3130 void Session::SetRotation(Rotation rotation)
3131 {
3132     rotation_ = rotation;
3133 }
3134 
GetRotation() const3135 Rotation Session::GetRotation() const
3136 {
3137     return rotation_;
3138 }
3139 
UpdateTitleInTargetPos(bool isShow,int32_t height)3140 WSError Session::UpdateTitleInTargetPos(bool isShow, int32_t height)
3141 {
3142     WLOGFD("Session update title in target position, id: %{public}d, isShow: %{public}d, height: %{public}d",
3143         GetPersistentId(), isShow, height);
3144     if (!IsSessionValid()) {
3145         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
3146             GetPersistentId(), GetSessionState());
3147         return WSError::WS_ERROR_INVALID_SESSION;
3148     }
3149     if (!sessionStage_) {
3150         TLOGE(WmsLogTag::WMS_MAIN, "sessionStage_ is null");
3151         return WSError::WS_ERROR_NULLPTR;
3152     }
3153     return sessionStage_->UpdateTitleInTargetPos(isShow, height);
3154 }
3155 
SetSessionInfoLockedStateChangeListener(const NotifySessionInfoLockedStateChangeFunc & func)3156 void Session::SetSessionInfoLockedStateChangeListener(const NotifySessionInfoLockedStateChangeFunc& func)
3157 {
3158     sessionInfoLockedStateChangeFunc_ = func;
3159 }
3160 
NotifySessionInfoLockedStateChange(bool lockedState)3161 void Session::NotifySessionInfoLockedStateChange(bool lockedState)
3162 {
3163     WLOGFD("Notify sessioninfo lockedstate change: %{public}u", lockedState);
3164     if (sessionInfoLockedStateChangeFunc_) {
3165         sessionInfoLockedStateChangeFunc_(lockedState);
3166     }
3167 }
3168 
SwitchFreeMultiWindow(bool enable)3169 WSError Session::SwitchFreeMultiWindow(bool enable)
3170 {
3171     TLOGD(WmsLogTag::WMS_LAYOUT, "windowId:%{public}d enable: %{public}d", GetPersistentId(), enable);
3172     systemConfig_.freeMultiWindowEnable_ = enable;
3173     if (!IsSessionValid()) {
3174         TLOGD(WmsLogTag::WMS_LAYOUT, "Session is invalid, id: %{public}d state: %{public}u",
3175             GetPersistentId(), GetSessionState());
3176         return WSError::WS_ERROR_INVALID_SESSION;
3177     }
3178     if (!sessionStage_) {
3179         TLOGE(WmsLogTag::WMS_MAIN, "sessionStage_ is null");
3180         return WSError::WS_ERROR_NULLPTR;
3181     }
3182     return sessionStage_->SwitchFreeMultiWindow(enable);
3183 }
3184 
GetUIContentRemoteObj(sptr<IRemoteObject> & uiContentRemoteObj)3185 WSError Session::GetUIContentRemoteObj(sptr<IRemoteObject>& uiContentRemoteObj)
3186 {
3187     if (!IsSessionValid()) {
3188         TLOGE(WmsLogTag::DEFAULT, "session %{public}d is invalid. Failed to get UIContentRemoteObj", GetPersistentId());
3189         return WSError::WS_ERROR_INVALID_SESSION;
3190     }
3191     if (sessionStage_ == nullptr) {
3192         TLOGE(WmsLogTag::DEFAULT, "sessionStage_ is nullptr");
3193         return WSError::WS_ERROR_NULLPTR;
3194     }
3195     return sessionStage_->GetUIContentRemoteObj(uiContentRemoteObj);
3196 }
3197 
SetNotifySystemSessionPointerEventFunc(const NotifySystemSessionPointerEventFunc & func)3198 void Session::SetNotifySystemSessionPointerEventFunc(const NotifySystemSessionPointerEventFunc& func)
3199 {
3200     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3201     systemSessionPointerEventFunc_ = func;
3202 }
3203 
SetNotifySystemSessionKeyEventFunc(const NotifySystemSessionKeyEventFunc & func)3204 void Session::SetNotifySystemSessionKeyEventFunc(const NotifySystemSessionKeyEventFunc& func)
3205 {
3206     std::unique_lock<std::shared_mutex> lock(keyEventMutex_);
3207     systemSessionKeyEventFunc_ = func;
3208 }
3209 
NotifySessionInfoChange()3210 void Session::NotifySessionInfoChange()
3211 {
3212     if (sessionInfoChangeNotifyManagerFunc_) {
3213         sessionInfoChangeNotifyManagerFunc_(GetPersistentId());
3214     }
3215 }
3216 
NeedCheckContextTransparent() const3217 bool Session::NeedCheckContextTransparent() const
3218 {
3219     return contextTransparentFunc_ != nullptr;
3220 }
3221 
SetContextTransparentFunc(const NotifyContextTransparentFunc & func)3222 void Session::SetContextTransparentFunc(const NotifyContextTransparentFunc& func)
3223 {
3224     contextTransparentFunc_ = func;
3225 }
3226 
NotifyContextTransparent()3227 void Session::NotifyContextTransparent()
3228 {
3229     if (contextTransparentFunc_) {
3230         int32_t eventRet = HiSysEventWrite(
3231             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
3232             "SESSION_IS_TRANSPARENT",
3233             OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
3234             "PERSISTENT_ID", GetPersistentId(),
3235             "BUNDLE_NAME", sessionInfo_.bundleName_);
3236         WLOGFE("Session context is transparent, persistentId:%{public}d, eventRet:%{public}d",
3237             GetPersistentId(), eventRet);
3238         contextTransparentFunc_();
3239     }
3240 }
3241 
IsSystemInput()3242 bool Session::IsSystemInput()
3243 {
3244     return sessionInfo_.sceneType_ == SceneType::INPUT_SCENE;
3245 }
3246 
SetIsMidScene(bool isMidScene)3247 void Session::SetIsMidScene(bool isMidScene)
3248 {
3249     auto task = [weakThis = wptr(this), isMidScene] {
3250         auto session = weakThis.promote();
3251         if (session == nullptr) {
3252             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "session is null");
3253             return;
3254         }
3255         if (session->isMidScene_ != isMidScene) {
3256             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "persistentId:%{public}d, isMidScene:%{public}d",
3257                 session->GetPersistentId(), isMidScene);
3258             session->isMidScene_ = isMidScene;
3259         }
3260     };
3261     PostTask(task, "SetIsMidScene");
3262 }
3263 
GetIsMidScene() const3264 bool Session::GetIsMidScene() const
3265 {
3266     return isMidScene_;
3267 }
3268 
SetTouchHotAreas(const std::vector<Rect> & touchHotAreas)3269 void Session::SetTouchHotAreas(const std::vector<Rect>& touchHotAreas)
3270 {
3271     auto property = GetSessionProperty();
3272     if (property == nullptr) {
3273         return;
3274     }
3275     std::vector<Rect> lastTouchHotAreas;
3276     property->GetTouchHotAreas(lastTouchHotAreas);
3277     if (touchHotAreas == lastTouchHotAreas) {
3278         return;
3279     }
3280 
3281     dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::TOUCH_HOT_AREA);
3282     std::string rectStr;
3283     for (const auto& rect : touchHotAreas) {
3284         rectStr = rectStr + " hot : " + rect.ToString();
3285     }
3286     TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d rects:%{public}s", GetPersistentId(), rectStr.c_str());
3287     property->SetTouchHotAreas(touchHotAreas);
3288 }
3289 
GetSnapshotPixelMap(const float oriScale,const float newScale)3290 std::shared_ptr<Media::PixelMap> Session::GetSnapshotPixelMap(const float oriScale, const float newScale)
3291 {
3292     TLOGI(WmsLogTag::WMS_MAIN, "id %{public}d", GetPersistentId());
3293     if (scenePersistence_ == nullptr) {
3294         return nullptr;
3295     }
3296     return scenePersistence_->IsSavingSnapshot() ? GetSnapshot() :
3297         scenePersistence_->GetLocalSnapshotPixelMap(oriScale, newScale);
3298 }
3299 
IsVisibleForeground() const3300 bool Session::IsVisibleForeground() const
3301 {
3302     return isVisible_ && IsSessionForeground();
3303 }
3304 
SetIsStarting(bool isStarting)3305 void Session::SetIsStarting(bool isStarting)
3306 {
3307     isStarting_ = isStarting;
3308 }
3309 
ResetDirtyFlags()3310 void Session::ResetDirtyFlags()
3311 {
3312     if (!isVisible_) {
3313         dirtyFlags_ &= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
3314     } else {
3315         dirtyFlags_ = 0;
3316     }
3317 }
3318 
SetUIStateDirty(bool dirty)3319 void Session::SetUIStateDirty(bool dirty)
3320 {
3321     mainUIStateDirty_.store(dirty);
3322 }
3323 
GetUIStateDirty() const3324 bool Session::GetUIStateDirty() const
3325 {
3326     return mainUIStateDirty_.load();
3327 }
3328 
SetMainSessionUIStateDirty(bool dirty)3329 void Session::SetMainSessionUIStateDirty(bool dirty)
3330 {
3331     if (GetParentSession() && WindowHelper::IsMainWindow(GetParentSession()->GetWindowType())) {
3332         GetParentSession()->SetUIStateDirty(dirty);
3333     }
3334 }
3335 
IsScbCoreEnabled()3336 bool Session::IsScbCoreEnabled()
3337 {
3338     return isScbCoreEnabled_;
3339 }
3340 
SetScbCoreEnabled(bool enabled)3341 void Session::SetScbCoreEnabled(bool enabled)
3342 {
3343     TLOGI(WmsLogTag::WMS_PIPELINE, "%{public}d", enabled);
3344     isScbCoreEnabled_ = enabled;
3345 }
3346 } // namespace OHOS::Rosen
3347