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