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