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