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