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