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/scene_session.h"
17 #include <parameters.h>
18 
19 #include <ability_manager_client.h>
20 #include <algorithm>
21 #include <climits>
22 #include <hitrace_meter.h>
23 #include <type_traits>
24 #ifdef IMF_ENABLE
25 #include <input_method_controller.h>
26 #endif // IMF_ENABLE
27 #include <ipc_skeleton.h>
28 #include <pointer_event.h>
29 #include <transaction/rs_sync_transaction_controller.h>
30 #include <transaction/rs_transaction.h>
31 #include <ui/rs_surface_node.h>
32 
33 #include "proxy/include/window_info.h"
34 
35 #include "common/include/session_permission.h"
36 #ifdef DEVICE_STATUS_ENABLE
37 #include "interaction_manager.h"
38 #endif // DEVICE_STATUS_ENABLE
39 #include "interfaces/include/ws_common.h"
40 #include "pixel_map.h"
41 #include "session/screen/include/screen_session.h"
42 #include "screen_session_manager_client/include/screen_session_manager_client.h"
43 #include "session/host/include/scene_persistent_storage.h"
44 #include "session/host/include/session_utils.h"
45 #include "display_manager.h"
46 #include "session_helper.h"
47 #include "window_helper.h"
48 #include "window_manager_hilog.h"
49 #include "wm_math.h"
50 #include <running_lock.h>
51 #include "screen_manager.h"
52 #include "screen.h"
53 #include "singleton_container.h"
54 #include "fold_screen_state_internel.h"
55 #include "session/host/include/multi_instance_manager.h"
56 
57 #ifdef POWER_MANAGER_ENABLE
58 #include <power_mgr_client.h>
59 #endif
60 
61 namespace OHOS::Rosen {
62 namespace {
63 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSession" };
64 const std::string DLP_INDEX = "ohos.dlp.params.index";
65 constexpr const char* APP_CLONE_INDEX = "ohos.extra.param.key.appCloneIndex";
66 constexpr float MOVE_DRAG_POSITION_Z = 100.5f;
67 
CheckIfRectElementIsTooLarge(const WSRect& rect)68 bool CheckIfRectElementIsTooLarge(const WSRect& rect)
69 {
70     int32_t largeNumber = static_cast<int32_t>(SHRT_MAX);
71     if (rect.posX_ >= largeNumber || rect.posY_ >= largeNumber ||
72         rect.width_ >= largeNumber || rect.height_ >= largeNumber) {
73         return true;
74     }
75     return false;
76 }
77 } // namespace
78 
79 MaximizeMode SceneSession::maximizeMode_ = MaximizeMode::MODE_RECOVER;
80 wptr<SceneSession> SceneSession::enterSession_ = nullptr;
81 std::mutex SceneSession::enterSessionMutex_;
82 std::shared_mutex SceneSession::windowDragHotAreaMutex_;
83 std::map<uint64_t, std::map<uint32_t, WSRect>> SceneSession::windowDragHotAreaMap_;
84 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
85 
SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)86 SceneSession::SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
87     : Session(info)
88 {
89     GeneratePersistentId(false, info.persistentId_);
90     specificCallback_ = specificCallback;
91     SetCollaboratorType(info.collaboratorType_);
92     TLOGI(WmsLogTag::WMS_LIFE, "Create session, id: %{public}d", GetPersistentId());
93 }
94 
~SceneSession()95 SceneSession::~SceneSession()
96 {
97     TLOGI(WmsLogTag::WMS_LIFE, "~SceneSession, id: %{public}d", GetPersistentId());
98 }
99 
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)100 WSError SceneSession::ConnectInner(const sptr<ISessionStage>& sessionStage,
101     const sptr<IWindowEventChannel>& eventChannel,
102     const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
103     sptr<WindowSessionProperty> property, sptr<IRemoteObject> token, int32_t pid, int32_t uid,
104     const std::string& identityToken)
105 {
106     auto task = [weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, &systemConfig, property, token, pid,
107         uid, identityToken]() {
108         auto session = weakThis.promote();
109         if (!session) {
110             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
111             return WSError::WS_ERROR_DESTROYED_OBJECT;
112         }
113         if (SessionHelper::IsMainWindow(session->GetWindowType())) {
114             if (!session->CheckIdentityTokenIfMatched(identityToken)) {
115                 TLOGNW(WmsLogTag::WMS_LIFE, "check failed");
116                 return WSError::WS_OK;
117             }
118         }
119         if (property) {
120             property->SetCollaboratorType(session->GetCollaboratorType());
121             property->SetAppInstanceKey(session->GetAppInstanceKey());
122         }
123         auto ret = session->Session::ConnectInner(
124             sessionStage, eventChannel, surfaceNode, systemConfig, property, token, pid, uid);
125         if (ret != WSError::WS_OK) {
126             return ret;
127         }
128         session->NotifyPropertyWhenConnect();
129         session->isStatusBarVisible_ = true;
130         return ret;
131     };
132     return PostSyncTask(task, "ConnectInner");
133 }
134 
Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token, const std::string& identityToken)135 WSError SceneSession::Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
136     const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
137     sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
138     const std::string& identityToken)
139 {
140     // Get pid and uid before posting task.
141     int32_t pid = IPCSkeleton::GetCallingRealPid();
142     int32_t uid = IPCSkeleton::GetCallingUid();
143     return ConnectInner(sessionStage, eventChannel, surfaceNode, systemConfig,
144         property, token, pid, uid, identityToken);
145 }
146 
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)147 WSError SceneSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
148     const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
149     int32_t pid, int32_t uid)
150 {
151     return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
152         auto session = weakThis.promote();
153         if (!session) {
154             WLOGFE("session is null");
155             return WSError::WS_ERROR_DESTROYED_OBJECT;
156         }
157         WSError ret = session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
158         if (ret != WSError::WS_OK) {
159             return ret;
160         }
161         return session->ReconnectInner(property);
162     });
163 }
164 
ReconnectInner(sptr<WindowSessionProperty> property)165 WSError SceneSession::ReconnectInner(sptr<WindowSessionProperty> property)
166 {
167     if (property == nullptr) {
168         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
169         return WSError::WS_ERROR_NULLPTR;
170     }
171     WindowState windowState = property->GetWindowState();
172     TLOGI(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, windowState: %{public}d ", GetPersistentId(), windowState);
173     WSError ret = WSError::WS_OK;
174     switch (windowState) {
175         case WindowState::STATE_INITIAL: {
176             TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: STATE_INITIAL",
177                 GetPersistentId());
178             ret = WSError::WS_ERROR_INVALID_PARAM;
179             break;
180         }
181         case WindowState::STATE_CREATED:
182             break;
183         case WindowState::STATE_SHOWN: {
184             UpdateSessionState(SessionState::STATE_FOREGROUND);
185             UpdateActiveStatus(true);
186             break;
187         }
188         case WindowState::STATE_HIDDEN: {
189             UpdateSessionState(SessionState::STATE_BACKGROUND);
190             break;
191         }
192         default:
193             TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: %{public}u",
194                 GetPersistentId(), windowState);
195             ret = WSError::WS_ERROR_INVALID_PARAM;
196             break;
197     }
198     if (ret != WSError::WS_OK) {
199         Session::Disconnect(false);
200     }
201     return ret;
202 }
203 
Foreground( sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)204 WSError SceneSession::Foreground(
205     sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)
206 {
207     if (!CheckPermissionWithPropertyAnimation(property)) {
208         return WSError::WS_ERROR_NOT_SYSTEM_APP;
209     }
210 
211     // return when screen is locked and show without ShowWhenLocked flag
212     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
213     auto sessionProperty = GetSessionProperty();
214     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
215         GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED) &&
216         (sessionProperty != nullptr && defaultScreenId == sessionProperty->GetDisplayId()) &&
217         !IsShowWhenLocked()) {
218         if (!SessionPermission::IsSystemAppCall()) {
219             TLOGW(WmsLogTag::WMS_LIFE, "failed: screen is locked, session %{public}d show without ShowWhenLocked flag",
220                 GetPersistentId());
221             return WSError::WS_ERROR_INVALID_SESSION;
222         }
223     }
224 
225     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
226         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
227             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
228             return WSError::WS_OK;
229         }
230     }
231     return ForegroundTask(property);
232 }
233 
ForegroundTask(const sptr<WindowSessionProperty>& property)234 WSError SceneSession::ForegroundTask(const sptr<WindowSessionProperty>& property)
235 {
236     auto task = [weakThis = wptr(this), property]() {
237         auto session = weakThis.promote();
238         if (!session) {
239             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
240             return WSError::WS_ERROR_DESTROYED_OBJECT;
241         }
242         auto sessionProperty = session->GetSessionProperty();
243         if (property && sessionProperty) {
244             sessionProperty->SetWindowMode(property->GetWindowMode());
245             sessionProperty->SetDecorEnable(property->IsDecorEnable());
246         }
247         int32_t persistentId = session->GetPersistentId();
248         auto ret = session->Session::Foreground(property);
249         if (ret != WSError::WS_OK) {
250             TLOGE(WmsLogTag::WMS_LIFE, "session foreground failed, ret=%{public}d persistentId=%{public}d",
251                 ret, persistentId);
252             return ret;
253         }
254         auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
255         if (leashWinSurfaceNode && sessionProperty) {
256             bool lastPrivacyMode = sessionProperty->GetPrivacyMode() || sessionProperty->GetSystemPrivacyMode();
257             leashWinSurfaceNode->SetSecurityLayer(lastPrivacyMode);
258         }
259         if (session->specificCallback_ != nullptr) {
260             if (Session::IsScbCoreEnabled()) {
261                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
262             } else {
263                 session->specificCallback_->onUpdateAvoidArea_(persistentId);
264             }
265             session->specificCallback_->onWindowInfoUpdate_(
266                 persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
267             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
268             session->UpdateGestureBackEnabled();
269         } else {
270             TLOGI(WmsLogTag::WMS_LIFE, "foreground specific callback does not take effect, callback function null");
271         }
272         return WSError::WS_OK;
273     };
274     PostTask(task, "Foreground");
275     return WSError::WS_OK;
276 }
277 
Background(bool isFromClient, const std::string& identityToken)278 WSError SceneSession::Background(bool isFromClient, const std::string& identityToken)
279 {
280     if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
281         return WSError::WS_ERROR_NOT_SYSTEM_APP;
282     }
283 
284     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
285         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
286             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
287             return WSError::WS_OK;
288         }
289     }
290     return BackgroundTask(true);
291 }
292 
NotifyFrameLayoutFinishFromApp(bool notifyListener, const WSRect& rect)293 WSError SceneSession::NotifyFrameLayoutFinishFromApp(bool notifyListener, const WSRect& rect)
294 {
295     TLOGI(WmsLogTag::WMS_LAYOUT, "%{public}d, %{public}s", notifyListener, rect.ToString().c_str());
296     auto task = [weakThis = wptr(this), notifyListener, rect]() {
297         auto session = weakThis.promote();
298         if (!session) {
299             TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "session is null");
300             return WSError::WS_ERROR_DESTROYED_OBJECT;
301         }
302         session->layoutRect_ = rect;
303         session->NotifyLayoutFinished();
304         if (notifyListener && session->frameLayoutFinishFunc_) {
305             TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d", session->GetPersistentId());
306             session->frameLayoutFinishFunc_();
307         }
308         return WSError::WS_OK;
309     };
310     PostTask(task, "NotifyFrameLayoutFinishFromApp");
311     return WSError::WS_OK;
312 }
313 
BackgroundTask(const bool isSaveSnapshot)314 WSError SceneSession::BackgroundTask(const bool isSaveSnapshot)
315 {
316     auto task = [weakThis = wptr(this), isSaveSnapshot]() {
317         auto session = weakThis.promote();
318         if (!session) {
319             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
320             return WSError::WS_ERROR_DESTROYED_OBJECT;
321         }
322         auto state = session->GetSessionState();
323         if (state == SessionState::STATE_BACKGROUND) {
324             return WSError::WS_OK;
325         }
326         auto ret = session->Session::Background();
327         if (ret != WSError::WS_OK) {
328             return ret;
329         }
330         if (WindowHelper::IsMainWindow(session->GetWindowType()) && isSaveSnapshot) {
331             session->SaveSnapshot(true);
332         }
333         if (session->specificCallback_ != nullptr) {
334             if (Session::IsScbCoreEnabled()) {
335                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
336             } else {
337                 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
338             }
339             session->specificCallback_->onWindowInfoUpdate_(
340                 session->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
341             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
342             session->UpdateGestureBackEnabled();
343         }
344         return WSError::WS_OK;
345     };
346     PostTask(task, "Background");
347     return WSError::WS_OK;
348 }
349 
ClearSpecificSessionCbMap()350 void SceneSession::ClearSpecificSessionCbMap()
351 {
352     const char* const where = __func__;
353     auto task = [weakThis = wptr(this), where] {
354         auto session = weakThis.promote();
355         if (!session) {
356             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s: session is null", where);
357             return;
358         }
359         session->ClearJsSceneSessionCbMap(true);
360     };
361     PostTask(task, __func__);
362 }
363 
ClearJsSceneSessionCbMap(bool needRemove)364 void SceneSession::ClearJsSceneSessionCbMap(bool needRemove)
365 {
366     if (sessionChangeCallback_ && sessionChangeCallback_->clearCallbackFunc_) {
367         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, needRemove: %{public}d", GetPersistentId(), needRemove);
368         sessionChangeCallback_->clearCallbackFunc_(needRemove);
369     } else {
370         TLOGE(WmsLogTag::WMS_LIFE, "get callback failed, id: %{public}d", GetPersistentId());
371     }
372 }
373 
Disconnect(bool isFromClient, const std::string& identityToken)374 WSError SceneSession::Disconnect(bool isFromClient, const std::string& identityToken)
375 {
376     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
377         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
378             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
379             return WSError::WS_OK;
380         }
381     }
382     return DisconnectTask(isFromClient, true);
383 }
384 
DisconnectTask(bool isFromClient, bool isSaveSnapshot)385 WSError SceneSession::DisconnectTask(bool isFromClient, bool isSaveSnapshot)
386 {
387     PostTask([weakThis = wptr(this), isFromClient, isSaveSnapshot]() {
388         auto session = weakThis.promote();
389         if (!session) {
390             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
391             return WSError::WS_ERROR_DESTROYED_OBJECT;
392         }
393         if (isFromClient) {
394             TLOGI(WmsLogTag::WMS_LIFE, "Client need notify destroy session, id: %{public}d",
395                 session->GetPersistentId());
396             session->SetSessionState(SessionState::STATE_DISCONNECT);
397             return WSError::WS_OK;
398         }
399         auto state = session->GetSessionState();
400         auto isMainWindow = SessionHelper::IsMainWindow(session->GetWindowType());
401         if ((session->needSnapshot_ || (state == SessionState::STATE_ACTIVE && isMainWindow)) && isSaveSnapshot) {
402             session->SaveSnapshot(false);
403         }
404         session->Session::Disconnect(isFromClient);
405         session->isTerminating_ = false;
406         if (session->specificCallback_ != nullptr) {
407             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
408             session->UpdateGestureBackEnabled();
409         }
410         return WSError::WS_OK;
411     },
412         "Disconnect");
413     return WSError::WS_OK;
414 }
415 
UpdateActiveStatus(bool isActive)416 WSError SceneSession::UpdateActiveStatus(bool isActive)
417 {
418     auto task = [weakThis = wptr(this), isActive]() {
419         auto session = weakThis.promote();
420         if (!session) {
421             WLOGFE("[WMSCom] session is null");
422             return WSError::WS_ERROR_DESTROYED_OBJECT;
423         }
424         if (!session->IsSessionValid()) {
425             TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
426                 session->GetPersistentId(), session->GetSessionState());
427             return WSError::WS_ERROR_INVALID_SESSION;
428         }
429         if (isActive == session->isActive_) {
430             WLOGFD("[WMSCom] Session active do not change: %{public}d", isActive);
431             return WSError::WS_DO_NOTHING;
432         }
433 
434         WSError ret = WSError::WS_DO_NOTHING;
435         if (isActive && session->GetSessionState() == SessionState::STATE_FOREGROUND) {
436             session->UpdateSessionState(SessionState::STATE_ACTIVE);
437             session->isActive_ = isActive;
438             ret = WSError::WS_OK;
439         }
440         if (!isActive && session->GetSessionState() == SessionState::STATE_ACTIVE) {
441             session->UpdateSessionState(SessionState::STATE_INACTIVE);
442             session->isActive_ = isActive;
443             ret = WSError::WS_OK;
444         }
445         WLOGFI("[WMSCom] isActive: %{public}d, state: %{public}u",
446             session->isActive_, session->GetSessionState());
447         return ret;
448     };
449     PostTask(task, "UpdateActiveStatus:" + std::to_string(isActive));
450     return WSError::WS_OK;
451 }
452 
OnSessionEvent(SessionEvent event)453 WSError SceneSession::OnSessionEvent(SessionEvent event)
454 {
455     auto task = [weakThis = wptr(this), event]() {
456         auto session = weakThis.promote();
457         if (!session) {
458             WLOGFE("[WMSCom] session is null");
459             return WSError::WS_ERROR_DESTROYED_OBJECT;
460         }
461         WLOGFI("[WMSCom] event: %{public}d", static_cast<int32_t>(event));
462         if (event == SessionEvent::EVENT_START_MOVE) {
463             if (!session->IsMovable()) {
464                 return WSError::WS_OK;
465             }
466             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::StartMove");
467             session->InitializeCrossMoveDrag();
468             session->moveDragController_->InitMoveDragProperty();
469             if (session->IsFullScreenMovable()) {
470                 WSRect rect = session->moveDragController_->GetFullScreenToFloatingRect(session->winRect_,
471                     session->GetSessionRequestRect());
472                 session->Session::UpdateRect(rect, SizeChangeReason::RECOVER, "OnSessionEvent", nullptr);
473                 session->moveDragController_->SetStartMoveFlag(true);
474                 session->moveDragController_->CalcFirstMoveTargetRect(rect, true);
475             } else {
476                 session->moveDragController_->SetStartMoveFlag(true);
477                 session->moveDragController_->CalcFirstMoveTargetRect(session->winRect_, false);
478             }
479             session->SetSessionEventParam({session->moveDragController_->GetOriginalPointerPosX(),
480                 session->moveDragController_->GetOriginalPointerPosY()});
481         }
482         if (session->moveDragController_ && event == SessionEvent::EVENT_DRAG) {
483             WSRect rect = session->moveDragController_->GetTargetRect();
484             session->SetSessionEventParam({rect.posX_, rect.posY_, rect.width_, rect.height_});
485         }
486         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->OnSessionEvent_) {
487             session->sessionChangeCallback_->OnSessionEvent_(static_cast<uint32_t>(event), session->sessionEventParam_);
488         }
489         return WSError::WS_OK;
490     };
491     PostTask(task, "OnSessionEvent:" + std::to_string(static_cast<uint32_t>(event)));
492     return WSError::WS_OK;
493 }
494 
OnSystemSessionEvent(SessionEvent event)495 WSError SceneSession::OnSystemSessionEvent(SessionEvent event)
496 {
497     if (event != SessionEvent::EVENT_START_MOVE) {
498         TLOGE(WmsLogTag::WMS_SYSTEM, "This is not start move event, eventId = %{public}d", event);
499         return WSError::WS_ERROR_NULLPTR;
500     }
501     if (!SessionPermission::IsSystemCalling()) {
502         TLOGW(WmsLogTag::WMS_SYSTEM, "This is not system window, permission denied!");
503         return WSError::WS_ERROR_NOT_SYSTEM_APP;
504     }
505     auto task = [weakThis = wptr(this), event]() {
506         auto session = weakThis.promote();
507         if (!session || !session->moveDragController_) {
508             TLOGNW(WmsLogTag::WMS_SYSTEM, "IPC communicate failed since hostSession is nullptr");
509             return WSError::WS_ERROR_NULLPTR;
510         }
511         if (session->moveDragController_->GetStartMoveFlag()) {
512             TLOGNW(WmsLogTag::WMS_SYSTEM, "Repeat operation,system window is moving");
513             return WSError::WS_ERROR_REPEAT_OPERATION;
514         }
515         session->OnSessionEvent(event);
516         return WSError::WS_OK;
517     };
518     return PostSyncTask(task, "OnSystemSessionEvent");
519 }
520 
GetWindowDragHotAreaType(DisplayId displayId, uint32_t type, int32_t pointerX, int32_t pointerY)521 uint32_t SceneSession::GetWindowDragHotAreaType(DisplayId displayId, uint32_t type, int32_t pointerX, int32_t pointerY)
522 {
523     std::shared_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
524     if (windowDragHotAreaMap_.find(displayId) == windowDragHotAreaMap_.end()) {
525         TLOGW(WmsLogTag::WMS_LAYOUT, "Display is invalid.");
526         return type;
527     }
528     for (const auto& [key, rect] : windowDragHotAreaMap_[displayId]) {
529         if (rect.IsInRegion(pointerX, pointerY)) {
530             type |= key;
531         }
532     }
533     return type;
534 }
535 
AddOrUpdateWindowDragHotArea(DisplayId displayId, uint32_t type, const WSRect& area)536 void SceneSession::AddOrUpdateWindowDragHotArea(DisplayId displayId, uint32_t type, const WSRect& area)
537 {
538     std::unique_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
539     windowDragHotAreaMap_[displayId].insert_or_assign(type, area);
540 }
541 
OnSessionModalTypeChange(SubWindowModalType subWindowModalType)542 WSError SceneSession::OnSessionModalTypeChange(SubWindowModalType subWindowModalType)
543 {
544     const char* const where = __func__;
545     auto task = [weakThis = wptr(this), subWindowModalType, where]() {
546         auto session = weakThis.promote();
547         if (!session) {
548             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
549             return WSError::WS_ERROR_DESTROYED_OBJECT;
550         }
551         TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s subWindowModalType: %{public}u",
552             where, static_cast<uint32_t>(subWindowModalType));
553         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onSessionModalTypeChange_) {
554             session->sessionChangeCallback_->onSessionModalTypeChange_(subWindowModalType);
555         }
556         return WSError::WS_OK;
557     };
558     PostTask(task, "OnSessionModalTypeChange");
559     return WSError::WS_OK;
560 }
561 
SetSessionModalTypeChangeCallback(const NotifySessionModalTypeChangeFunc& func)562 void SceneSession::SetSessionModalTypeChangeCallback(const NotifySessionModalTypeChangeFunc& func)
563 {
564     const char* const where = __func__;
565     auto task = [weakThis = wptr(this), func, where]() {
566         auto session = weakThis.promote();
567         if (!session || !func) {
568             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session or SessionModalTypeChangeFunc is null", where);
569             return WSError::WS_ERROR_DESTROYED_OBJECT;
570         }
571         if (session->sessionChangeCallback_) {
572             session->sessionChangeCallback_->onSessionModalTypeChange_ = func;
573         }
574         TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s SessionModalTypeChange id: %{public}d",
575             where, session->GetPersistentId());
576         return WSError::WS_OK;
577     };
578     PostTask(task, "SetSessionModalTypeChangeCallback");
579 }
580 
GetSubWindowModalType() const581 SubWindowModalType SceneSession::GetSubWindowModalType() const
582 {
583     SubWindowModalType modalType = SubWindowModalType::TYPE_UNDEFINED;
584     auto property = GetSessionProperty();
585     if (property == nullptr) {
586         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
587         return modalType;
588     }
589     auto windowType = property->GetWindowType();
590     if (WindowHelper::IsToastSubWindow(windowType, property->GetWindowFlags())) {
591         return SubWindowModalType::TYPE_TOAST;
592     }
593     if (WindowHelper::IsDialogWindow(windowType)) {
594         modalType = SubWindowModalType::TYPE_DIALOG;
595     } else if (WindowHelper::IsModalSubWindow(windowType, property->GetWindowFlags())) {
596         if (WindowHelper::IsApplicationModalSubWindow(windowType, property->GetWindowFlags())) {
597             modalType = SubWindowModalType::TYPE_APPLICATION_MODALITY;
598         } else {
599             modalType = SubWindowModalType::TYPE_WINDOW_MODALITY;
600         }
601     } else if (WindowHelper::IsSubWindow(windowType)) {
602         modalType = SubWindowModalType::TYPE_NORMAL;
603     }
604     return modalType;
605 }
606 
SetSessionEventParam(SessionEventParam param)607 void SceneSession::SetSessionEventParam(SessionEventParam param)
608 {
609     sessionEventParam_ = param;
610 }
611 
RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback>& sessionChangeCallback)612 void SceneSession::RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback>&
613     sessionChangeCallback)
614 {
615     std::lock_guard<std::mutex> guard(sessionChangeCbMutex_);
616     sessionChangeCallback_ = sessionChangeCallback;
617 }
618 
RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc&& callback)619 void SceneSession::RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc&& callback)
620 {
621     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
622         auto session = weakThis.promote();
623         if (!session) {
624             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
625             return WSError::WS_ERROR_DESTROYED_OBJECT;
626         }
627         if (session->sessionChangeCallback_) {
628             session->sessionChangeCallback_->onWindowAnimationFlagChange_ = std::move(callback);
629             session->sessionChangeCallback_->onWindowAnimationFlagChange_(session->IsNeedDefaultAnimation());
630         }
631         return WSError::WS_OK;
632     };
633     PostTask(task, "RegisterDefaultAnimationFlagChangeCallback");
634 }
635 
RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc&& callback)636 void SceneSession::RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc&& callback)
637 {
638     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
639         auto session = weakThis.promote();
640         if (!session) {
641             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
642             return;
643         }
644         session->onSystemBarPropertyChange_ = std::move(callback);
645     };
646     PostTask(task, __func__);
647 }
648 
SetGlobalMaximizeMode(MaximizeMode mode)649 WSError SceneSession::SetGlobalMaximizeMode(MaximizeMode mode)
650 {
651     auto task = [weakThis = wptr(this), mode]() {
652         auto session = weakThis.promote();
653         if (!session) {
654             WLOGFE("[WMSCom] session is null");
655             return WSError::WS_ERROR_DESTROYED_OBJECT;
656         }
657         WLOGFD("[WMSCom] mode: %{public}u", static_cast<uint32_t>(mode));
658         session->maximizeMode_ = mode;
659         ScenePersistentStorage::Insert("maximize_state", static_cast<int32_t>(session->maximizeMode_),
660             ScenePersistentStorageType::MAXIMIZE_STATE);
661         return WSError::WS_OK;
662     };
663     return PostSyncTask(task, "SetGlobalMaximizeMode");
664 }
665 
GetGlobalMaximizeMode(MaximizeMode& mode)666 WSError SceneSession::GetGlobalMaximizeMode(MaximizeMode& mode)
667 {
668     auto task = [weakThis = wptr(this), &mode]() {
669         auto session = weakThis.promote();
670         if (!session) {
671             WLOGFE("[WMSCom] session is null");
672             return WSError::WS_ERROR_DESTROYED_OBJECT;
673         }
674         mode = maximizeMode_;
675         WLOGFD("[WMSCom] mode: %{public}u", static_cast<uint32_t>(mode));
676         return WSError::WS_OK;
677     };
678     return PostSyncTask(task, "GetGlobalMaximizeMode");
679 }
680 
CheckAspectRatioValid(const sptr<SceneSession>& session, float ratio, float vpr)681 static WSError CheckAspectRatioValid(const sptr<SceneSession>& session, float ratio, float vpr)
682 {
683     if (MathHelper::NearZero(ratio)) {
684         return WSError::WS_OK;
685     }
686     if (!session) {
687         return WSError::WS_ERROR_INVALID_PARAM;
688     }
689     auto sessionProperty = session->GetSessionProperty();
690     if (!sessionProperty) {
691         return WSError::WS_ERROR_INVALID_PARAM;
692     }
693     auto limits = sessionProperty->GetWindowLimits();
694     if (session->IsDecorEnable()) {
695         if (limits.minWidth_ && limits.maxHeight_ &&
696             MathHelper::LessNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.minWidth_, vpr) /
697             SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr))) {
698             WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
699             return WSError::WS_ERROR_INVALID_PARAM;
700         } else if (limits.minHeight_ && limits.maxWidth_ &&
701             MathHelper::GreatNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr) /
702             SessionUtils::ToLayoutHeight(limits.minHeight_, vpr))) {
703             WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
704             return WSError::WS_ERROR_INVALID_PARAM;
705         }
706     } else {
707         if (limits.minWidth_ && limits.maxHeight_ && MathHelper::LessNotEqual(ratio,
708             static_cast<float>(limits.minWidth_) / limits.maxHeight_)) {
709             WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
710             return WSError::WS_ERROR_INVALID_PARAM;
711         } else if (limits.minHeight_ && limits.maxWidth_ && MathHelper::GreatNotEqual(ratio,
712             static_cast<float>(limits.maxWidth_) / limits.minHeight_)) {
713             WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
714             return WSError::WS_ERROR_INVALID_PARAM;
715         }
716     }
717     return WSError::WS_OK;
718 }
719 
720 /** @note @window.layout */
SetAspectRatio(float ratio)721 WSError SceneSession::SetAspectRatio(float ratio)
722 {
723     auto task = [weakThis = wptr(this), ratio]() {
724         auto session = weakThis.promote();
725         if (!session) {
726             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
727             return WSError::WS_ERROR_DESTROYED_OBJECT;
728         }
729         if (!session->GetSessionProperty()) {
730             TLOGE(WmsLogTag::WMS_LAYOUT, "Set ratio failed, property is null");
731             return WSError::WS_ERROR_NULLPTR;
732         }
733         float vpr = 1.5f; // 1.5f: default virtual pixel ratio
734         auto display = DisplayManager::GetInstance().GetDefaultDisplay();
735         if (display) {
736             vpr = display->GetVirtualPixelRatio();
737             WLOGD("vpr = %{public}f", vpr);
738         }
739         WSError ret = CheckAspectRatioValid(session, ratio, vpr);
740         if (ret != WSError::WS_OK) {
741             return ret;
742         }
743         session->aspectRatio_ = ratio;
744         if (session->moveDragController_) {
745             session->moveDragController_->SetAspectRatio(ratio);
746         }
747         session->SaveAspectRatio(session->aspectRatio_);
748         WSRect fixedRect = session->winRect_;
749         TLOGI(WmsLogTag::WMS_LAYOUT, "Before fixing, the id:%{public}d, the current rect: %{public}s, "
750             "ratio: %{public}f", session->GetPersistentId(), fixedRect.ToString().c_str(), ratio);
751         if (session->FixRectByAspectRatio(fixedRect)) {
752             TLOGI(WmsLogTag::WMS_LAYOUT, "After fixing, the id:%{public}d, the fixed rect: %{public}s",
753                 session->GetPersistentId(), fixedRect.ToString().c_str());
754             session->NotifySessionRectChange(fixedRect, SizeChangeReason::RESIZE);
755         }
756         return WSError::WS_OK;
757     };
758     return PostSyncTask(task, "SetAspectRatio");
759 }
760 
761 /** @note @window.layout */
UpdateRect(const WSRect& rect, SizeChangeReason reason, const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)762 WSError SceneSession::UpdateRect(const WSRect& rect, SizeChangeReason reason,
763     const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)
764 {
765     auto task = [weakThis = wptr(this), rect, reason, rsTransaction,  updateReason]() {
766         auto session = weakThis.promote();
767         if (!session) {
768             WLOGFE("session is null");
769             return WSError::WS_ERROR_DESTROYED_OBJECT;
770         }
771         if (session->winRect_ == rect && session->reason_ != SizeChangeReason::DRAG_END &&
772             (session->GetWindowType() != WindowType::WINDOW_TYPE_KEYBOARD_PANEL &&
773             session->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT)) {
774             if (!session->sessionStage_) {
775                 TLOGD(WmsLogTag::WMS_LAYOUT, "skip same rect update id:%{public}d rect:%{public}s",
776                     session->GetPersistentId(), rect.ToString().c_str());
777                 return WSError::WS_OK;
778             } else if (session->GetClientRect() == rect) {
779                 TLOGD(WmsLogTag::WMS_LAYOUT, "skip same rect update id:%{public}d rect:%{public}s "
780                     "clientRect:%{public}s", session->GetPersistentId(), rect.ToString().c_str(),
781                     session->GetClientRect().ToString().c_str());
782                 return WSError::WS_OK;
783             }
784         }
785         if (rect.IsInvalid()) {
786             TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d rect:%{public}s is invalid",
787                 session->GetPersistentId(), rect.ToString().c_str());
788             return WSError::WS_ERROR_INVALID_PARAM;
789         }
790         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
791             "SceneSession::UpdateRect%d [%d, %d, %u, %u]",
792             session->GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_);
793         // position change no need to notify client, since frame layout finish will notify
794         if (NearEqual(rect.width_, session->winRect_.width_) && NearEqual(rect.height_, session->winRect_.height_) &&
795             (session->reason_ != SizeChangeReason::MOVE || !session->rectChangeListenerRegistered_)) {
796             TLOGI(WmsLogTag::WMS_LAYOUT, "position change no need notify client id:%{public}d, rect:%{public}s, "
797                 "preRect: %{public}s",
798                 session->GetPersistentId(), rect.ToString().c_str(), session->winRect_.ToString().c_str());
799             session->winRect_ = rect;
800         } else {
801             session->winRect_ = rect;
802             session->NotifyClientToUpdateRect(updateReason, rsTransaction);
803         }
804         session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
805         TLOGI(WmsLogTag::WMS_LAYOUT, "UpdateRect id:%{public}d, reason:%{public}d %{public}s, rect:%{public}s, "
806             "clientRect:%{public}s", session->GetPersistentId(), session->reason_, updateReason.c_str(),
807             rect.ToString().c_str(), session->GetClientRect().ToString().c_str());
808 
809         return WSError::WS_OK;
810     };
811     PostTask(task, "UpdateRect" + GetRectInfo(rect));
812     return WSError::WS_OK;
813 }
814 
NotifyClientToUpdateRectTask(const std::string& updateReason, std::shared_ptr<RSTransaction> rsTransaction)815 WSError SceneSession::NotifyClientToUpdateRectTask(const std::string& updateReason,
816     std::shared_ptr<RSTransaction> rsTransaction)
817 {
818     TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, reason:%{public}d, rect:%{public}s",
819         GetPersistentId(), reason_, winRect_.ToString().c_str());
820     bool isMoveOrDrag = moveDragController_ &&
821         (moveDragController_->GetStartDragFlag() || moveDragController_->GetStartMoveFlag());
822     if (isMoveOrDrag && reason_ == SizeChangeReason::UNDEFINED) {
823         TLOGD(WmsLogTag::WMS_LAYOUT, "skip redundant rect update!");
824         return WSError::WS_ERROR_REPEAT_OPERATION;
825     }
826     WSError ret = WSError::WS_OK;
827     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
828         "SceneSession::NotifyClientToUpdateRect%d [%d, %d, %u, %u] reason:%u",
829         GetPersistentId(), winRect_.posX_, winRect_.posY_, winRect_.width_, winRect_.height_, reason_);
830 
831     // once reason is undefined, not use rsTransaction
832     // when rotation, sync cnt++ in marshalling. Although reason is undefined caused by resize
833     if (reason_ == SizeChangeReason::UNDEFINED || reason_ == SizeChangeReason::MOVE ||
834         reason_ == SizeChangeReason::RESIZE) {
835         ret = Session::UpdateRect(winRect_, reason_, updateReason, nullptr);
836     } else {
837         ret = Session::UpdateRect(winRect_, reason_, updateReason, rsTransaction);
838 #ifdef DEVICE_STATUS_ENABLE
839         // When the drag is in progress, the drag window needs to be notified to rotate.
840         if (rsTransaction != nullptr) {
841             RotateDragWindow(rsTransaction);
842         }
843 #endif // DEVICE_STATUS_ENABLE
844     }
845 
846     return ret;
847 }
848 
NotifyClientToUpdateRect(const std::string& updateReason, std::shared_ptr<RSTransaction> rsTransaction)849 WSError SceneSession::NotifyClientToUpdateRect(const std::string& updateReason,
850     std::shared_ptr<RSTransaction> rsTransaction)
851 {
852     auto task = [weakThis = wptr(this), rsTransaction, updateReason]() {
853         auto session = weakThis.promote();
854         if (!session) {
855             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
856             return WSError::WS_ERROR_DESTROYED_OBJECT;
857         }
858         WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
859         if (ret == WSError::WS_OK) {
860             if (session->specificCallback_ != nullptr) {
861                 if (Session::IsScbCoreEnabled()) {
862                     session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
863                 } else {
864                     session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
865                 }
866             }
867             // clear after use
868             if (session->reason_ != SizeChangeReason::DRAG) {
869                 session->reason_ = SizeChangeReason::UNDEFINED;
870                 session->dirtyFlags_ &= ~static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
871             }
872         }
873         return ret;
874     };
875     PostTask(task, "NotifyClientToUpdateRect");
876     return WSError::WS_OK;
877 }
878 
GetScreenWidthAndHeightFromServer(const sptr<WindowSessionProperty>& sessionProperty, uint32_t& screenWidth, uint32_t& screenHeight)879 bool SceneSession::GetScreenWidthAndHeightFromServer(const sptr<WindowSessionProperty>& sessionProperty,
880     uint32_t& screenWidth, uint32_t& screenHeight)
881 {
882     if (isScreenAngleMismatch_) {
883         screenWidth = targetScreenWidth_;
884         screenHeight = targetScreenHeight_;
885         TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
886         return true;
887     }
888 
889     const auto& screenSession = sessionProperty == nullptr ? nullptr :
890         ScreenSessionManagerClient::GetInstance().GetScreenSession(sessionProperty->GetDisplayId());
891     if (screenSession != nullptr) {
892         screenWidth = screenSession->GetScreenProperty().GetBounds().rect_.width_;
893         screenHeight = screenSession->GetScreenProperty().GetBounds().rect_.height_;
894     } else {
895         TLOGI(WmsLogTag::WMS_KEYBOARD, "sessionProperty or screenSession is nullptr, use defaultDisplayInfo");
896         auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
897         if (defaultDisplayInfo != nullptr) {
898             screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
899             screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
900         } else {
901             TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
902             return false;
903         }
904     }
905     TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
906     return true;
907 }
908 
GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty>& sessionProperty, uint32_t& screenWidth, uint32_t& screenHeight)909 bool SceneSession::GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty>& sessionProperty,
910     uint32_t& screenWidth, uint32_t& screenHeight)
911 {
912     if (isScreenAngleMismatch_) {
913         screenWidth = targetScreenWidth_;
914         screenHeight = targetScreenHeight_;
915         TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
916         return true;
917     }
918 
919     auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
920     if (defaultDisplayInfo != nullptr) {
921         screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
922         screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
923     } else {
924         TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
925         return false;
926     }
927     TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
928     return true;
929 }
930 
NotifyTargetScreenWidthAndHeight(bool isScreenAngleMismatch, uint32_t screenWidth, uint32_t screenHeight)931 void SceneSession::NotifyTargetScreenWidthAndHeight(bool isScreenAngleMismatch, uint32_t screenWidth,
932     uint32_t screenHeight)
933 {
934     auto task = [weakThis = wptr(this), isScreenAngleMismatch, screenWidth, screenHeight]() {
935         auto session = weakThis.promote();
936         if (!session) {
937             TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboard session is null");
938             return;
939         }
940         session->isScreenAngleMismatch_ = isScreenAngleMismatch;
941         session->targetScreenWidth_ = screenWidth;
942         session->targetScreenHeight_ = screenHeight;
943         TLOGI(WmsLogTag::WMS_KEYBOARD, "target isMismatch: %{public}d, width_: %{public}d, height_: %{public}d",
944             isScreenAngleMismatch, screenWidth, screenHeight);
945         return;
946     };
947     PostTask(task, "NotifyTargetScreenWidthAndHeight");
948 }
949 
UpdateInputMethodSessionRect(const WSRect& rect, WSRect& newWinRect, WSRect& newRequestRect)950 bool SceneSession::UpdateInputMethodSessionRect(const WSRect& rect, WSRect& newWinRect, WSRect& newRequestRect)
951 {
952     SessionGravity gravity;
953     uint32_t percent = 0;
954     auto sessionProperty = GetSessionProperty();
955     if (!sessionProperty) {
956         TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
957         return false;
958     }
959     sessionProperty->GetSessionGravity(gravity, percent);
960     if (GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
961         (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM || gravity == SessionGravity::SESSION_GRAVITY_DEFAULT)) {
962         uint32_t screenWidth = 0;
963         uint32_t screenHeight = 0;
964         if (!GetScreenWidthAndHeightFromServer(sessionProperty, screenWidth, screenHeight)) {
965             return false;
966         }
967         newWinRect.width_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) ?
968             static_cast<int32_t>(screenWidth) : rect.width_;
969         newRequestRect.width_ = newWinRect.width_;
970         newWinRect.height_ =
971             (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM && percent != 0)
972                 ? static_cast<int32_t>(screenHeight * percent / 100u) : rect.height_;
973         newRequestRect.height_ = newWinRect.height_;
974         newWinRect.posX_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) ? 0 : rect.posX_;
975         newRequestRect.posX_ = newWinRect.posX_;
976         newWinRect.posY_ = static_cast<int32_t>(screenHeight) - newWinRect.height_;
977         newRequestRect.posY_ = newWinRect.posY_;
978         TLOGI(WmsLogTag::WMS_KEYBOARD, "rect: %{public}s, newRequestRect: %{public}s, newWinRect: %{public}s",
979             rect.ToString().c_str(), newRequestRect.ToString().c_str(), newWinRect.ToString().c_str());
980         return true;
981     }
982     TLOGD(WmsLogTag::WMS_KEYBOARD, "There is no need to update input rect");
983     return false;
984 }
985 
SetSessionRectChangeCallback(const NotifySessionRectChangeFunc& func)986 void SceneSession::SetSessionRectChangeCallback(const NotifySessionRectChangeFunc& func)
987 {
988     auto task = [weakThis = wptr(this), func]() {
989         auto session = weakThis.promote();
990         if (!session) {
991             WLOGFE("session is null");
992             return WSError::WS_ERROR_DESTROYED_OBJECT;
993         }
994         session->sessionRectChangeFunc_ = func;
995         if (session->sessionRectChangeFunc_ && session->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
996             auto reason = SizeChangeReason::UNDEFINED;
997             auto rect = session->GetSessionRequestRect();
998             if (rect.width_ == 0 && rect.height_ == 0) {
999                 reason = SizeChangeReason::MOVE;
1000             }
1001             session->sessionRectChangeFunc_(rect, reason, DISPLAY_ID_INVALID);
1002         }
1003         return WSError::WS_OK;
1004     };
1005     PostTask(task, "SetSessionRectChangeCallback");
1006 }
1007 
SetMainWindowTopmostChangeCallback(const NotifyMainWindowTopmostChangeFunc& func)1008 void SceneSession::SetMainWindowTopmostChangeCallback(const NotifyMainWindowTopmostChangeFunc& func)
1009 {
1010     auto task = [weakThis = wptr(this), func] {
1011         auto session = weakThis.promote();
1012         if (!session || !func) {
1013             TLOGNE(WmsLogTag::WMS_HIERARCHY, "session or func is null");
1014             return;
1015         }
1016         session->mainWindowTopmostChangeFunc_ = func;
1017     };
1018     PostTask(task, __func__);
1019 }
1020 
SetKeyboardGravityChangeCallback(const NotifyKeyboardGravityChangeFunc& func)1021 void SceneSession::SetKeyboardGravityChangeCallback(const NotifyKeyboardGravityChangeFunc& func)
1022 {
1023     auto task = [weakThis = wptr(this), func]() {
1024         auto session = weakThis.promote();
1025         if (!session || !func) {
1026             WLOGFE("session or gravityChangeFunc is null");
1027             return WSError::WS_ERROR_DESTROYED_OBJECT;
1028         }
1029         session->keyboardGravityChangeFunc_ = func;
1030         session->keyboardGravityChangeFunc_(session->GetKeyboardGravity());
1031         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify gravity change when register, id: %{public}d gravity: %{public}d",
1032             session->GetPersistentId(), session->GetKeyboardGravity());
1033         return WSError::WS_OK;
1034     };
1035     PostTask(task, "SetKeyboardGravityChangeCallback");
1036 }
1037 
SetRestoreMainWindowCallback(const NotifyRestoreMainWindowFunc& func)1038 void SceneSession::SetRestoreMainWindowCallback(const NotifyRestoreMainWindowFunc& func)
1039 {
1040     auto task = [weakThis = wptr(this), func]() {
1041         auto session = weakThis.promote();
1042         if (!session || !func) {
1043             TLOGNE(WmsLogTag::WMS_LIFE, "session or RestoreMainWindowFunc is null");
1044             return WSError::WS_ERROR_DESTROYED_OBJECT;
1045         }
1046         if (session->sessionChangeCallback_) {
1047             session->sessionChangeCallback_->onRestoreMainWindowFunc_ = func;
1048         }
1049         TLOGNI(WmsLogTag::WMS_LIFE, "RestoreMainWindow id: %{public}d",
1050             session->GetPersistentId());
1051         return WSError::WS_OK;
1052     };
1053     PostTask(task, "SetRestoreMainWindowCallback");
1054 }
1055 
SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc& func)1056 void SceneSession::SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc& func)
1057 {
1058     auto task = [weakThis = wptr(this), func]() {
1059         auto session = weakThis.promote();
1060         if (!session || !func) {
1061             TLOGE(WmsLogTag::WMS_KEYBOARD, "session or keyboardLayoutFunc is null");
1062             return WSError::WS_ERROR_DESTROYED_OBJECT;
1063         }
1064         session->adjustKeyboardLayoutFunc_ = func;
1065         auto property = session->GetSessionProperty();
1066         if (property == nullptr) {
1067             TLOGE(WmsLogTag::WMS_KEYBOARD, "property is null");
1068             return WSError::WS_ERROR_DESTROYED_OBJECT;
1069         }
1070         KeyboardLayoutParams params = property->GetKeyboardLayoutParams();
1071         session->adjustKeyboardLayoutFunc_(params);
1072         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify adjust keyboard layout when register, keyboardId: %{public}d, "
1073             "gravity: %{public}u, LandscapeKeyboardRect: %{public}s, PortraitKeyboardRect: %{public}s, "
1074             "LandscapePanelRect: %{public}s, PortraitPanelRect: %{public}s", session->GetPersistentId(),
1075             static_cast<uint32_t>(params.gravity_), params.LandscapeKeyboardRect_.ToString().c_str(),
1076             params.PortraitKeyboardRect_.ToString().c_str(), params.LandscapePanelRect_.ToString().c_str(),
1077             params.PortraitPanelRect_.ToString().c_str());
1078         return WSError::WS_OK;
1079     };
1080     PostTask(task, "SetAdjustKeyboardLayoutCallback");
1081 }
1082 
SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc& func)1083 void SceneSession::SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc& func)
1084 {
1085     auto task = [weakThis = wptr(this), func]() {
1086         auto session = weakThis.promote();
1087         if (!session) {
1088             TLOGE(WmsLogTag::WMS_PIP, "session is null");
1089             return WSError::WS_ERROR_DESTROYED_OBJECT;
1090         }
1091         session->sessionPiPControlStatusChangeFunc_ = func;
1092         return WSError::WS_OK;
1093     };
1094     PostTask(task, __func__);
1095 }
1096 
SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc& func)1097 void SceneSession::SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc& func)
1098 {
1099     auto task = [weakThis = wptr(this), func] {
1100         auto session = weakThis.promote();
1101         if (!session) {
1102             TLOGNE(WmsLogTag::WMS_PIP, "session is null");
1103             return;
1104         }
1105         session->autoStartPiPStatusChangeFunc_ = func;
1106     };
1107     PostTask(task, __func__);
1108 }
1109 
1110 /** @note @window.layout */
UpdateSessionRectInner(const WSRect& rect, const SizeChangeReason reason)1111 void SceneSession::UpdateSessionRectInner(const WSRect& rect, const SizeChangeReason reason)
1112 {
1113     auto newWinRect = winRect_;
1114     auto newRequestRect = GetSessionRequestRect();
1115     SizeChangeReason newReason = reason;
1116     if (reason == SizeChangeReason::MOVE) {
1117         newWinRect.posX_ = rect.posX_;
1118         newWinRect.posY_ = rect.posY_;
1119         newRequestRect.posX_ = rect.posX_;
1120         newRequestRect.posY_ = rect.posY_;
1121         if (!Session::IsScbCoreEnabled() && !WindowHelper::IsMainWindow(GetWindowType())) {
1122             SetSessionRect(newWinRect);
1123         }
1124         SetSessionRequestRect(newRequestRect);
1125         NotifySessionRectChange(newRequestRect, reason);
1126     } else if (reason == SizeChangeReason::RESIZE) {
1127         bool needUpdateInputMethod = UpdateInputMethodSessionRect(rect, newWinRect, newRequestRect);
1128         if (needUpdateInputMethod) {
1129             newReason = SizeChangeReason::UNDEFINED;
1130             TLOGD(WmsLogTag::WMS_KEYBOARD, "Input rect has totally changed, need to modify reason, id: %{public}d",
1131                 GetPersistentId());
1132         } else if (rect.width_ > 0 && rect.height_ > 0) {
1133             newWinRect.width_ = rect.width_;
1134             newWinRect.height_ = rect.height_;
1135             newRequestRect.width_ = rect.width_;
1136             newRequestRect.height_ = rect.height_;
1137         }
1138         if (!Session::IsScbCoreEnabled() && GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1139             SetSessionRect(newWinRect);
1140         }
1141         SetSessionRequestRect(newRequestRect);
1142         NotifySessionRectChange(newRequestRect, newReason);
1143     } else {
1144         if (!Session::IsScbCoreEnabled()) {
1145             SetSessionRect(rect);
1146         }
1147         NotifySessionRectChange(rect, reason);
1148     }
1149     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d reason:%{public}d newReason:%{public}d rect:%{public}s "
1150         "newRequestRect:%{public}s newWinRect:%{public}s", GetPersistentId(), reason,
1151         newReason, rect.ToString().c_str(), newRequestRect.ToString().c_str(), newWinRect.ToString().c_str());
1152 }
1153 
1154 /** @note @window.layout */
UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal)1155 WSError SceneSession::UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal)
1156 {
1157     if ((reason == SizeChangeReason::MOVE || reason == SizeChangeReason::RESIZE) &&
1158         GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1159         return WSError::WS_DO_NOTHING;
1160     }
1161     WSRect newRect = rect;
1162     if (isGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) &&
1163         (systemConfig_.IsPhoneWindow() ||
1164          (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode()))) {
1165         auto parentSession = GetParentSession();
1166         if (parentSession) {
1167             auto parentRect = parentSession->GetSessionRect();
1168             if (!CheckIfRectElementIsTooLarge(parentRect)) {
1169                 newRect.posX_ -= parentRect.posX_;
1170                 newRect.posY_ -= parentRect.posY_;
1171             }
1172         }
1173     }
1174     Session::RectCheckProcess();
1175     auto task = [weakThis = wptr(this), newRect, reason]() {
1176         auto session = weakThis.promote();
1177         if (!session) {
1178             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
1179             return WSError::WS_ERROR_DESTROYED_OBJECT;
1180         }
1181         session->UpdateSessionRectInner(newRect, reason);
1182         return WSError::WS_OK;
1183     };
1184     PostTask(task, "UpdateSessionRect" + GetRectInfo(rect));
1185     return WSError::WS_OK;
1186 }
1187 
1188 /** @note @window.layout */
UpdateClientRect(const WSRect& rect)1189 WSError SceneSession::UpdateClientRect(const WSRect& rect)
1190 {
1191     const char* const funcName = __func__;
1192     auto task = [weakThis = wptr(this), rect, funcName] {
1193         auto session = weakThis.promote();
1194         if (!session) {
1195             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
1196             return WSError::WS_ERROR_DESTROYED_OBJECT;
1197         }
1198         if (rect.IsInvalid()) {
1199             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
1200                 funcName, session->GetPersistentId(), rect.ToString().c_str());
1201             return WSError::WS_ERROR_INVALID_PARAM;
1202         }
1203         if (rect == session->GetClientRect()) {
1204             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d skip same rect",
1205                 funcName, session->GetPersistentId());
1206             return WSError::WS_DO_NOTHING;
1207         }
1208         session->SetClientRect(rect);
1209         return WSError::WS_OK;
1210     };
1211     PostTask(task, "UpdateClientRect" + GetRectInfo(rect));
1212     return WSError::WS_OK;
1213 }
1214 
1215 /** @note @window.hierarchy */
RaiseToAppTop()1216 WSError SceneSession::RaiseToAppTop()
1217 {
1218     if (!SessionPermission::IsSystemCalling()) {
1219         WLOGFE("raise to app top permission denied!");
1220         return WSError::WS_ERROR_NOT_SYSTEM_APP;
1221     }
1222     auto task = [weakThis = wptr(this)]() {
1223         auto session = weakThis.promote();
1224         if (!session) {
1225             WLOGFE("session is null");
1226             return WSError::WS_ERROR_DESTROYED_OBJECT;
1227         }
1228         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRaiseToTop_) {
1229             TLOGI(WmsLogTag::WMS_HIERARCHY, "id: %{public}d", session->GetPersistentId());
1230             session->sessionChangeCallback_->onRaiseToTop_();
1231             session->SetMainSessionUIStateDirty(true);
1232         }
1233         return WSError::WS_OK;
1234     };
1235     return PostSyncTask(task, "RaiseToAppTop");
1236 }
1237 
1238 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)1239 WSError SceneSession::RaiseAboveTarget(int32_t subWindowId)
1240 {
1241     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1242         WLOGFE("RaiseAboveTarget permission denied!");
1243         return WSError::WS_ERROR_NOT_SYSTEM_APP;
1244     }
1245     auto subSession = std::find_if(subSession_.begin(), subSession_.end(), [subWindowId](sptr<SceneSession> session) {
1246         bool res = (session != nullptr && session->GetWindowId() == subWindowId) ? true : false;
1247         return res;
1248     });
1249     int32_t callingPid = IPCSkeleton::GetCallingPid();
1250     if (subSession != subSession_.end() && callingPid != (*subSession)->GetCallingPid()) {
1251         TLOGE(WmsLogTag::WMS_HIERARCHY, "permission denied! id: %{public}d", subWindowId);
1252         return WSError::WS_ERROR_INVALID_CALLING;
1253     }
1254     auto task = [weakThis = wptr(this), subWindowId]() {
1255         auto session = weakThis.promote();
1256         if (!session) {
1257             WLOGFE("session is null");
1258             return WSError::WS_ERROR_DESTROYED_OBJECT;
1259         }
1260         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRaiseAboveTarget_) {
1261             session->sessionChangeCallback_->onRaiseAboveTarget_(subWindowId);
1262         }
1263         return WSError::WS_OK;
1264     };
1265     return PostSyncTask(task, "RaiseAboveTarget");
1266 }
1267 
BindDialogSessionTarget(const sptr<SceneSession>& sceneSession)1268 WSError SceneSession::BindDialogSessionTarget(const sptr<SceneSession>& sceneSession)
1269 {
1270     if (sceneSession == nullptr) {
1271         TLOGE(WmsLogTag::WMS_DIALOG, "dialog session is null");
1272         return WSError::WS_ERROR_NULLPTR;
1273     }
1274     if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onBindDialogTarget_) {
1275         TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", sceneSession->GetPersistentId());
1276         sessionChangeCallback_->onBindDialogTarget_(sceneSession);
1277     }
1278     return WSError::WS_OK;
1279 }
1280 
SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)1281 WSError SceneSession::SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)
1282 {
1283     TLOGD(WmsLogTag::WMS_IMMS, "persistentId():%{public}u type:%{public}u"
1284         "enable:%{public}u bgColor:%{public}x Color:%{public}x enableAnimation:%{public}u settingFlag:%{public}u",
1285         GetPersistentId(), static_cast<uint32_t>(type),
1286         systemBarProperty.enable_, systemBarProperty.backgroundColor_, systemBarProperty.contentColor_,
1287         systemBarProperty.enableAnimation_, systemBarProperty.settingFlag_);
1288     auto property = GetSessionProperty();
1289     if (property == nullptr) {
1290         TLOGE(WmsLogTag::WMS_DIALOG, "property is null");
1291         return WSError::WS_ERROR_NULLPTR;
1292     }
1293     property->SetSystemBarProperty(type, systemBarProperty);
1294     if (type == WindowType::WINDOW_TYPE_STATUS_BAR && systemBarProperty.enable_) {
1295         SetIsDisplayStatusBarTemporarily(false);
1296     }
1297     if (onSystemBarPropertyChange_) {
1298         onSystemBarPropertyChange_(property->GetSystemBarProperty());
1299     }
1300     return WSError::WS_OK;
1301 }
1302 
SetIsStatusBarVisible(bool isVisible)1303 void SceneSession::SetIsStatusBarVisible(bool isVisible)
1304 {
1305     bool isNeedNotify = isStatusBarVisible_ != isVisible;
1306     TLOGI(WmsLogTag::WMS_IMMS, "Window [%{public}d, %{public}s] status bar visible %{public}u, need notify %{public}u",
1307           GetPersistentId(), GetWindowName().c_str(), isVisible, isNeedNotify);
1308     isStatusBarVisible_ = isVisible;
1309     if (isNeedNotify && specificCallback_ && specificCallback_->onUpdateAvoidAreaByType_) {
1310         specificCallback_->onUpdateAvoidAreaByType_(GetPersistentId(), AvoidAreaType::TYPE_SYSTEM);
1311     }
1312 }
1313 
NotifyPropertyWhenConnect()1314 void SceneSession::NotifyPropertyWhenConnect()
1315 {
1316     WLOGFI("Notify property when connect.");
1317     auto property = GetSessionProperty();
1318     if (property == nullptr) {
1319         WLOGFD("id: %{public}d property is nullptr", persistentId_);
1320         return;
1321     }
1322     NotifySessionFocusableChange(property->GetFocusable());
1323     NotifySessionTouchableChange(property->GetTouchable());
1324     OnShowWhenLocked(GetShowWhenLockedFlagValue());
1325 }
1326 
1327 /** @note @window.hierarchy */
RaiseAppMainWindowToTop()1328 WSError SceneSession::RaiseAppMainWindowToTop()
1329 {
1330     auto task = [weakThis = wptr(this)]() {
1331         auto session = weakThis.promote();
1332         if (!session) {
1333             WLOGFE("session is null");
1334             return WSError::WS_ERROR_DESTROYED_OBJECT;
1335         }
1336         if (session->IsFocusedOnShow()) {
1337             FocusChangeReason reason = FocusChangeReason::MOVE_UP;
1338             session->NotifyRequestFocusStatusNotifyManager(true, true, reason);
1339             session->NotifyClick();
1340         } else {
1341             session->SetFocusedOnShow(true);
1342         }
1343         return WSError::WS_OK;
1344     };
1345     PostTask(task, "RaiseAppMainWindowToTop");
1346     return WSError::WS_OK;
1347 }
1348 
OnNeedAvoid(bool status)1349 WSError SceneSession::OnNeedAvoid(bool status)
1350 {
1351     auto task = [weakThis = wptr(this), status]() {
1352         auto session = weakThis.promote();
1353         if (!session) {
1354             TLOGE(WmsLogTag::WMS_IMMS, "session is null");
1355             return WSError::WS_ERROR_DESTROYED_OBJECT;
1356         }
1357         TLOGI(WmsLogTag::WMS_IMMS, "SceneSession OnNeedAvoid status:%{public}d, id:%{public}d",
1358             static_cast<int32_t>(status), session->GetPersistentId());
1359         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->OnNeedAvoid_) {
1360             session->sessionChangeCallback_->OnNeedAvoid_(status);
1361         }
1362         return WSError::WS_OK;
1363     };
1364     PostTask(task, "OnNeedAvoid");
1365     return WSError::WS_OK;
1366 }
1367 
OnShowWhenLocked(bool showWhenLocked)1368 WSError SceneSession::OnShowWhenLocked(bool showWhenLocked)
1369 {
1370     WLOGFD("SceneSession ShowWhenLocked status:%{public}d", static_cast<int32_t>(showWhenLocked));
1371     if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnShowWhenLocked_) {
1372         sessionChangeCallback_->OnShowWhenLocked_(showWhenLocked);
1373     }
1374     return WSError::WS_OK;
1375 }
1376 
IsShowWhenLocked() const1377 bool SceneSession::IsShowWhenLocked() const
1378 {
1379     return (GetSessionProperty()->GetWindowFlags() &
1380         static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) || IsTemporarilyShowWhenLocked();
1381 }
1382 
GetShowWhenLockedFlagValue() const1383 bool SceneSession::GetShowWhenLockedFlagValue() const
1384 {
1385     return GetSessionProperty()->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
1386 }
1387 
CalculateAvoidAreaRect(WSRect& rect, WSRect& avoidRect, AvoidArea& avoidArea) const1388 void SceneSession::CalculateAvoidAreaRect(WSRect& rect, WSRect& avoidRect, AvoidArea& avoidArea) const
1389 {
1390     if (SessionHelper::IsEmptyRect(rect) || SessionHelper::IsEmptyRect(avoidRect)) {
1391         return;
1392     }
1393     Rect avoidAreaRect = SessionHelper::TransferToRect(
1394         SessionHelper::GetOverlap(rect, avoidRect, rect.posX_, rect.posY_));
1395     if (WindowHelper::IsEmptyRect(avoidAreaRect)) {
1396         return;
1397     }
1398 
1399     uint32_t avoidAreaCenterX = static_cast<uint32_t>(avoidAreaRect.posX_) + (avoidAreaRect.width_ >> 1);
1400     uint32_t avoidAreaCenterY = static_cast<uint32_t>(avoidAreaRect.posY_) + (avoidAreaRect.height_ >> 1);
1401     float res1 = float(avoidAreaCenterY) - float(rect.height_) / float(rect.width_) *
1402         float(avoidAreaCenterX);
1403     float res2 = float(avoidAreaCenterY) + float(rect.height_) / float(rect.width_) *
1404         float(avoidAreaCenterX) - float(rect.height_);
1405     if (res1 < 0) {
1406         if (res2 < 0) {
1407             avoidArea.topRect_ = avoidAreaRect;
1408         } else {
1409             avoidArea.rightRect_ = avoidAreaRect;
1410         }
1411     } else {
1412         if (res2 < 0) {
1413             avoidArea.leftRect_ = avoidAreaRect;
1414         } else {
1415             avoidArea.bottomRect_ = avoidAreaRect;
1416         }
1417     }
1418 }
1419 
GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)1420 void SceneSession::GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1421 {
1422     auto sessionProperty = GetSessionProperty();
1423     if (sessionProperty == nullptr ||
1424         (sessionProperty->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID))) {
1425         return;
1426     }
1427     DisplayId displayId = sessionProperty->GetDisplayId();
1428     auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
1429     if ((Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
1430          Session::GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1431          Session::GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) &&
1432         WindowHelper::IsMainWindow(Session::GetWindowType()) &&
1433         (systemConfig_.IsPhoneWindow() ||
1434          (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode())) &&
1435         (!screenSession || screenSession->GetName() != "HiCar")) {
1436         float miniScale = 0.316f; // Pressed mini floating Scale with 0.001 precision
1437         if (Session::GetFloatingScale() <= miniScale) {
1438             return;
1439         }
1440         if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
1441             rect.height_ < rect.width_) {
1442             return;
1443         }
1444         float vpr = 3.5f; // 3.5f: default pixel ratio
1445         auto display = DisplayManager::GetInstance().GetDefaultDisplay();
1446         if (display == nullptr) {
1447             WLOGFE("display is null");
1448             return;
1449         }
1450         vpr = display->GetVirtualPixelRatio();
1451         int32_t floatingBarHeight = 32; // 32: floating windowBar Height
1452         avoidArea.topRect_.height_ = vpr * floatingBarHeight;
1453         avoidArea.topRect_.width_ = static_cast<uint32_t>(display->GetWidth());
1454         return;
1455     }
1456     if (!isStatusBarVisible_) {
1457         TLOGI(WmsLogTag::WMS_IMMS, "status bar not visible");
1458         return;
1459     }
1460     std::vector<sptr<SceneSession>> statusBarVector;
1461     if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
1462         statusBarVector = specificCallback_->onGetSceneSessionVectorByType_(
1463             WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
1464     }
1465     for (auto& statusBar : statusBarVector) {
1466         WSRect statusBarRect = statusBar->GetSessionRect();
1467         TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s status bar %{public}s",
1468               rect.ToString().c_str(), statusBarRect.ToString().c_str());
1469         CalculateAvoidAreaRect(rect, statusBarRect, avoidArea);
1470     }
1471     return;
1472 }
1473 
GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)1474 void SceneSession::GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1475 {
1476     if (((Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
1477           WindowHelper::IsMainWindow(Session::GetWindowType())) ||
1478          (WindowHelper::IsSubWindow(Session::GetWindowType()) && GetParentSession() != nullptr &&
1479           GetParentSession()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING)) &&
1480         (systemConfig_.IsPhoneWindow() ||
1481          (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode()))) {
1482         return;
1483     }
1484     auto sessionProperty = GetSessionProperty();
1485     if (!sessionProperty) {
1486         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get session property");
1487         return;
1488     }
1489     std::vector<sptr<SceneSession>> inputMethodVector;
1490     if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
1491         inputMethodVector = specificCallback_->onGetSceneSessionVectorByType_(
1492             WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT, sessionProperty->GetDisplayId());
1493     }
1494     for (auto& inputMethod : inputMethodVector) {
1495         if (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
1496             inputMethod->GetSessionState() != SessionState::STATE_ACTIVE) {
1497             continue;
1498         }
1499         SessionGravity gravity = inputMethod->GetKeyboardGravity();
1500         if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
1501             continue;
1502         }
1503         if (isKeyboardPanelEnabled_) {
1504             WSRect keyboardRect = {0, 0, 0, 0};
1505             if (inputMethod && inputMethod->GetKeyboardPanelSession()) {
1506                 keyboardRect = inputMethod->GetKeyboardPanelSession()->GetSessionRect();
1507             }
1508             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s keyboard %{public}s",
1509                   rect.ToString().c_str(), keyboardRect.ToString().c_str());
1510             CalculateAvoidAreaRect(rect, keyboardRect, avoidArea);
1511         } else {
1512             WSRect inputMethodRect = inputMethod->GetSessionRect();
1513             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s input method %{public}s",
1514                   rect.ToString().c_str(), inputMethodRect.ToString().c_str());
1515             CalculateAvoidAreaRect(rect, inputMethodRect, avoidArea);
1516         }
1517     }
1518     return;
1519 }
1520 
GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)1521 void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1522 {
1523     auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
1524     if (display == nullptr) {
1525         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get display");
1526         return;
1527     }
1528     sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
1529     if (cutoutInfo == nullptr) {
1530         TLOGI(WmsLogTag::WMS_IMMS, "There is no CutoutInfo");
1531         return;
1532     }
1533     std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
1534     if (cutoutAreas.empty()) {
1535         TLOGI(WmsLogTag::WMS_IMMS, "There is no cutoutAreas");
1536         return;
1537     }
1538     for (auto& cutoutArea : cutoutAreas) {
1539         WSRect cutoutAreaRect = {
1540             cutoutArea.posX_,
1541             cutoutArea.posY_,
1542             cutoutArea.width_,
1543             cutoutArea.height_
1544         };
1545         TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s cutout %{public}s",
1546               rect.ToString().c_str(), cutoutAreaRect.ToString().c_str());
1547         CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
1548     }
1549 
1550     return;
1551 }
1552 
GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea) const1553 void SceneSession::GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea) const
1554 {
1555     if (isDisplayStatusBarTemporarily_.load()) {
1556         TLOGI(WmsLogTag::WMS_IMMS, "temporary show navigation bar, no need to avoid");
1557         return;
1558     }
1559     if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
1560         TLOGI(WmsLogTag::WMS_IMMS, "window mode pip return");
1561         return;
1562     }
1563     auto sessionProperty = GetSessionProperty();
1564     if (!sessionProperty) {
1565         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get session property");
1566         return;
1567     }
1568     WSRect barArea;
1569     if (specificCallback_ != nullptr && specificCallback_->onGetAINavigationBarArea_) {
1570         barArea = specificCallback_->onGetAINavigationBarArea_(sessionProperty->GetDisplayId());
1571     }
1572     TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s AI bar %{public}s",
1573           rect.ToString().c_str(), barArea.ToString().c_str());
1574     CalculateAvoidAreaRect(rect, barArea, avoidArea);
1575 }
1576 
CheckGetAvoidAreaAvailable(AvoidAreaType type)1577 bool SceneSession::CheckGetAvoidAreaAvailable(AvoidAreaType type)
1578 {
1579     if (type == AvoidAreaType::TYPE_KEYBOARD) {
1580         return true;
1581     }
1582     WindowMode mode = GetWindowMode();
1583     WindowType winType = GetWindowType();
1584     if (WindowHelper::IsMainWindow(winType)) {
1585         if (mode == WindowMode::WINDOW_MODE_FLOATING && type != AvoidAreaType::TYPE_SYSTEM) {
1586             return false;
1587         }
1588 
1589         if (mode != WindowMode::WINDOW_MODE_FLOATING || systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) {
1590             return true;
1591         }
1592     }
1593     if (WindowHelper::IsSubWindow(winType)) {
1594         auto parentSession = GetParentSession();
1595         if (parentSession != nullptr && parentSession->GetSessionRect() == GetSessionRect()) {
1596             return parentSession->CheckGetAvoidAreaAvailable(type);
1597         }
1598     }
1599     TLOGI(WmsLogTag::WMS_IMMS, "Window [%{public}u, %{public}s] type %{public}u "
1600         "avoidAreaType %{public}u windowMode %{public}u, return default avoid area.",
1601         GetPersistentId(), GetWindowName().c_str(), static_cast<uint32_t>(winType),
1602         static_cast<uint32_t>(type), static_cast<uint32_t>(mode));
1603     return false;
1604 }
1605 
AddModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)1606 void SceneSession::AddModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
1607 {
1608     TLOGD(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d, pid=%{public}d", GetPersistentId(),
1609         extensionInfo.persistentId, extensionInfo.pid);
1610     {
1611         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1612         modalUIExtensionInfoList_.push_back(extensionInfo);
1613     }
1614     NotifySessionInfoChange();
1615 }
1616 
UpdateModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)1617 void SceneSession::UpdateModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
1618 {
1619     TLOGD(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d,pid=%{public}d,"
1620         "Rect:[%{public}d %{public}d %{public}d %{public}d]",
1621         extensionInfo.persistentId, extensionInfo.pid, extensionInfo.windowRect.posX_,
1622         extensionInfo.windowRect.posY_, extensionInfo.windowRect.width_, extensionInfo.windowRect.height_);
1623     {
1624         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1625         auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
1626             [extensionInfo](const ExtensionWindowEventInfo& eventInfo) {
1627             return extensionInfo.persistentId == eventInfo.persistentId && extensionInfo.pid == eventInfo.pid;
1628         });
1629         if (iter == modalUIExtensionInfoList_.end()) {
1630             return;
1631         }
1632         iter->windowRect = extensionInfo.windowRect;
1633     }
1634     NotifySessionInfoChange();
1635 }
1636 
RemoveModalUIExtension(int32_t persistentId)1637 void SceneSession::RemoveModalUIExtension(int32_t persistentId)
1638 {
1639     TLOGI(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d", GetPersistentId(), persistentId);
1640     {
1641         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1642         auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
1643             [persistentId](const ExtensionWindowEventInfo& extensionInfo) {
1644             return extensionInfo.persistentId == persistentId;
1645         });
1646         if (iter == modalUIExtensionInfoList_.end()) {
1647             return;
1648         }
1649         modalUIExtensionInfoList_.erase(iter);
1650     }
1651     NotifySessionInfoChange();
1652 }
1653 
HasModalUIExtension()1654 bool SceneSession::HasModalUIExtension()
1655 {
1656     std::shared_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1657     return !modalUIExtensionInfoList_.empty();
1658 }
1659 
GetLastModalUIExtensionEventInfo()1660 ExtensionWindowEventInfo SceneSession::GetLastModalUIExtensionEventInfo()
1661 {
1662     std::shared_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1663     return modalUIExtensionInfoList_.back();
1664 }
1665 
GetSessionGlobalPosition(bool useUIExtension)1666 Vector2f SceneSession::GetSessionGlobalPosition(bool useUIExtension)
1667 {
1668     WSRect windowRect = GetSessionGlobalRect();
1669     if (useUIExtension && HasModalUIExtension()) {
1670         auto rect = GetLastModalUIExtensionEventInfo().windowRect;
1671         windowRect.posX_ = rect.posX_;
1672         windowRect.posY_ = rect.posY_;
1673     }
1674     Vector2f position(windowRect.posX_, windowRect.posY_);
1675     return position;
1676 }
1677 
AddUIExtSurfaceNodeId(uint64_t surfaceNodeId, int32_t persistentId)1678 void SceneSession::AddUIExtSurfaceNodeId(uint64_t surfaceNodeId, int32_t persistentId)
1679 {
1680     std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
1681     TLOGI(WmsLogTag::WMS_UIEXT, "Add uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
1682         surfaceNodeId, persistentId);
1683     uiExtNodeIdToPersistentIdMap_.insert(std::make_pair(surfaceNodeId, persistentId));
1684 }
1685 
RemoveUIExtSurfaceNodeId(int32_t persistentId)1686 void SceneSession::RemoveUIExtSurfaceNodeId(int32_t persistentId)
1687 {
1688     std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
1689     TLOGI(WmsLogTag::WMS_UIEXT, "Remove uiExtension by persistentId=%{public}d", persistentId);
1690     auto pairIter = std::find_if(uiExtNodeIdToPersistentIdMap_.begin(), uiExtNodeIdToPersistentIdMap_.end(),
1691         [persistentId](const auto& entry) { return entry.second == persistentId; });
1692     if (pairIter != uiExtNodeIdToPersistentIdMap_.end()) {
1693         TLOGI(WmsLogTag::WMS_UIEXT,
1694             "Successfully removed uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
1695             pairIter->first, persistentId);
1696         uiExtNodeIdToPersistentIdMap_.erase(pairIter);
1697         return;
1698     }
1699     TLOGE(WmsLogTag::WMS_UIEXT, "Failed to remove uiExtension by persistentId=%{public}d", persistentId);
1700 }
1701 
GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const1702 int32_t SceneSession::GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const
1703 {
1704     std::shared_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
1705     auto ret = uiExtNodeIdToPersistentIdMap_.find(surfaceNodeId);
1706     if (ret == uiExtNodeIdToPersistentIdMap_.end()) {
1707         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to find uiExtension by surfaceNodeId=%{public}" PRIu64 "", surfaceNodeId);
1708         return 0;
1709     }
1710     return ret->second;
1711 }
1712 
GetAvoidAreaByTypeInner(AvoidAreaType type)1713 AvoidArea SceneSession::GetAvoidAreaByTypeInner(AvoidAreaType type)
1714 {
1715     if (!CheckGetAvoidAreaAvailable(type)) {
1716         return {};
1717     }
1718 
1719     AvoidArea avoidArea;
1720     WSRect rect = GetSessionRect();
1721     switch (type) {
1722         case AvoidAreaType::TYPE_SYSTEM: {
1723             GetSystemAvoidArea(rect, avoidArea);
1724             return avoidArea;
1725         }
1726         case AvoidAreaType::TYPE_CUTOUT: {
1727             GetCutoutAvoidArea(rect, avoidArea);
1728             return avoidArea;
1729         }
1730         case AvoidAreaType::TYPE_SYSTEM_GESTURE: {
1731             return avoidArea;
1732         }
1733         case AvoidAreaType::TYPE_KEYBOARD: {
1734             GetKeyboardAvoidArea(rect, avoidArea);
1735             return avoidArea;
1736         }
1737         case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
1738             GetAINavigationBarArea(rect, avoidArea);
1739             return avoidArea;
1740         }
1741         default: {
1742             TLOGE(WmsLogTag::WMS_IMMS, "cannot find type %{public}u, id %{public}d",
1743                 type, GetPersistentId());
1744             return avoidArea;
1745         }
1746     }
1747 }
1748 
GetAvoidAreaByType(AvoidAreaType type)1749 AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type)
1750 {
1751     auto task = [weakThis = wptr(this), type]() -> AvoidArea {
1752         auto session = weakThis.promote();
1753         if (!session) {
1754             TLOGE(WmsLogTag::WMS_IMMS, "session is null");
1755             return {};
1756         }
1757         return session->GetAvoidAreaByTypeInner(type);
1758     };
1759     return PostSyncTask(task, "GetAvoidAreaByType");
1760 }
1761 
GetAllAvoidAreas(std::map<AvoidAreaType, AvoidArea>& avoidAreas)1762 WSError SceneSession::GetAllAvoidAreas(std::map<AvoidAreaType, AvoidArea>& avoidAreas)
1763 {
1764     auto task = [weakThis = wptr(this), &avoidAreas] {
1765         auto session = weakThis.promote();
1766         if (!session) {
1767             TLOGE(WmsLogTag::WMS_IMMS, "session is null");
1768             return WSError::WS_ERROR_NULLPTR;
1769         }
1770 
1771         using T = std::underlying_type_t<AvoidAreaType>;
1772         for (T avoidType = static_cast<T>(AvoidAreaType::TYPE_SYSTEM);
1773             avoidType <= static_cast<T>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR); avoidType++) {
1774             auto type = static_cast<AvoidAreaType>(avoidType);
1775             avoidAreas[type] = session->GetAvoidAreaByTypeInner(type);
1776         }
1777         return WSError::WS_OK;
1778     };
1779     return PostSyncTask(task, "GetAllAvoidAreas");
1780 }
1781 
UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)1782 WSError SceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
1783 {
1784     if (!sessionStage_) {
1785         return WSError::WS_ERROR_NULLPTR;
1786     }
1787     return sessionStage_->UpdateAvoidArea(avoidArea, type);
1788 }
1789 
SetPipActionEvent(const std::string& action, int32_t status)1790 WSError SceneSession::SetPipActionEvent(const std::string& action, int32_t status)
1791 {
1792     TLOGI(WmsLogTag::WMS_PIP, "action: %{public}s, status: %{public}d", action.c_str(), status);
1793     if (!sessionStage_) {
1794         return WSError::WS_ERROR_NULLPTR;
1795     }
1796     return sessionStage_->SetPipActionEvent(action, status);
1797 }
1798 
SetPiPControlEvent(WsPiPControlType controlType, WsPiPControlStatus status)1799 WSError SceneSession::SetPiPControlEvent(WsPiPControlType controlType, WsPiPControlStatus status)
1800 {
1801     TLOGI(WmsLogTag::WMS_PIP, "controlType: %{public}u, status: %{public}u", controlType, status);
1802     if (GetWindowType() != WindowType::WINDOW_TYPE_PIP || GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
1803         return WSError::WS_ERROR_INVALID_TYPE;
1804     }
1805     if (!sessionStage_) {
1806         return WSError::WS_ERROR_NULLPTR;
1807     }
1808     return sessionStage_->SetPiPControlEvent(controlType, status);
1809 }
1810 
HandleStyleEvent(MMI::WindowArea area)1811 void SceneSession::HandleStyleEvent(MMI::WindowArea area)
1812 {
1813     static std::pair<int32_t, MMI::WindowArea> preWindowArea =
1814         std::make_pair(INVALID_WINDOW_ID, MMI::WindowArea::EXIT);
1815     if (preWindowArea.first == Session::GetWindowId() && preWindowArea.second == area) {
1816         return;
1817     }
1818     if (area != MMI::WindowArea::EXIT) {
1819         if (Session::SetPointerStyle(area) != WSError::WS_OK) {
1820             WLOGFE("Failed to set the cursor style, WSError:%{public}d", Session::SetPointerStyle(area));
1821         }
1822     }
1823     preWindowArea = { Session::GetWindowId(), area };
1824 }
1825 
HandleEnterWinwdowArea(int32_t displayX, int32_t displayY)1826 WSError SceneSession::HandleEnterWinwdowArea(int32_t displayX, int32_t displayY)
1827 {
1828     if (displayX < 0 || displayY < 0) {
1829         TLOGE(WmsLogTag::WMS_EVENT, "Illegal parameter, displayX:%{private}d, displayY:%{private}d",
1830             displayX, displayY);
1831         return WSError::WS_ERROR_INVALID_PARAM;
1832     }
1833 
1834     auto windowType = Session::GetWindowType();
1835     auto iter = Session::windowAreas_.cend();
1836     if (!IsSystemSession() &&
1837         Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
1838         (windowType == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(windowType))) {
1839         iter = Session::windowAreas_.cbegin();
1840         for (;iter != Session::windowAreas_.cend(); ++iter) {
1841             WSRectF rect = iter->second;
1842             if (rect.IsInRegion(displayX, displayY)) {
1843                 break;
1844             }
1845         }
1846     }
1847 
1848     MMI::WindowArea area = MMI::WindowArea::EXIT;
1849     if (iter == Session::windowAreas_.cend()) {
1850         bool isInRegion = false;
1851         WSRect rect = Session::winRect_;
1852         if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
1853             (windowType == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(windowType))) {
1854             WSRectF rectF = Session::UpdateHotRect(rect);
1855             isInRegion = rectF.IsInRegion(displayX, displayY);
1856         } else {
1857             isInRegion = rect.IsInRegion(displayX, displayY);
1858         }
1859         if (!isInRegion) {
1860             WLOGFE("The wrong event(%{public}d, %{public}d) could not be matched to the region:"
1861                 "[%{public}d, %{public}d, %{public}d, %{public}d]",
1862                 displayX, displayY, rect.posX_, rect.posY_, rect.width_, rect.height_);
1863             return WSError::WS_ERROR_INVALID_TYPE;
1864         }
1865         area = MMI::WindowArea::FOCUS_ON_INNER;
1866     } else {
1867         area = iter->first;
1868     }
1869     HandleStyleEvent(area);
1870     return WSError::WS_OK;
1871 }
1872 
ProcessPointDownSession(int32_t posX, int32_t posY)1873 WSError SceneSession::ProcessPointDownSession(int32_t posX, int32_t posY)
1874 {
1875     const auto& id = GetPersistentId();
1876     WLOGFI("id: %{public}d, type: %{public}d", id, GetWindowType());
1877 
1878     // notify touch outside
1879     if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
1880         sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
1881         specificCallback_->onSessionTouchOutside_(id);
1882     }
1883 
1884     // notify outside down event
1885     if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
1886         specificCallback_->onOutsideDownEvent_(posX, posY);
1887     }
1888     return WSError::WS_OK;
1889 }
1890 
SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)1891 WSError SceneSession::SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1892 {
1893     NotifyOutsideDownEvent(pointerEvent);
1894     TransferPointerEvent(pointerEvent, false);
1895     return WSError::WS_OK;
1896 }
1897 
GetStartMoveFlag(bool& isMoving)1898 WSError SceneSession::GetStartMoveFlag(bool& isMoving)
1899 {
1900     auto task = [weakThis = wptr(this), &isMoving]() {
1901         auto session = weakThis.promote();
1902         if (!session || !session->moveDragController_) {
1903             TLOGE(WmsLogTag::DEFAULT, "session or moveDragController_ is null");
1904             return WSError::WS_ERROR_DESTROYED_OBJECT;
1905         }
1906         isMoving = session->moveDragController_->GetStartMoveFlag();
1907         TLOGI(WmsLogTag::DEFAULT, "isMoving: %{public}u", static_cast<uint32_t>(isMoving));
1908         return WSError::WS_OK;
1909     };
1910     return PostSyncTask(task, "GetStartMoveFlag");
1911 }
1912 
NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)1913 void SceneSession::NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1914 {
1915     // notify touchOutside and touchDown event
1916     int32_t action = pointerEvent->GetPointerAction();
1917     if (action != MMI::PointerEvent::POINTER_ACTION_DOWN &&
1918         action != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
1919         return;
1920     }
1921 
1922     MMI::PointerEvent::PointerItem pointerItem;
1923     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
1924         return;
1925     }
1926 
1927     // notify outside down event
1928     if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
1929         specificCallback_->onOutsideDownEvent_(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
1930     }
1931 }
1932 
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, bool needNotifyClient)1933 WSError SceneSession::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1934     bool needNotifyClient)
1935 {
1936     WLOGFD("[WMSCom] TransferPointEvent, id: %{public}d, type: %{public}d, needNotifyClient: %{public}d",
1937         GetPersistentId(), GetWindowType(), needNotifyClient);
1938     if (pointerEvent == nullptr) {
1939         WLOGFE("pointerEvent is null");
1940         return WSError::WS_ERROR_NULLPTR;
1941     }
1942 
1943     int32_t action = pointerEvent->GetPointerAction();
1944     {
1945         bool isSystemWindow = GetSessionInfo().isSystem_;
1946         std::lock_guard<std::mutex> guard(enterSessionMutex_);
1947         if (action == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
1948             WLOGFD("Set enter session, persistentId:%{public}d", GetPersistentId());
1949             enterSession_ = wptr<SceneSession>(this);
1950         }
1951         if ((enterSession_ != nullptr) &&
1952             (isSystemWindow && (action != MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW))) {
1953             WLOGFD("Remove enter session, persistentId:%{public}d", GetPersistentId());
1954             enterSession_ = nullptr;
1955         }
1956     }
1957 
1958     if (!CheckPointerEventDispatch(pointerEvent)) {
1959         WLOGFI("Do not dispatch this pointer event");
1960         return WSError::WS_DO_NOTHING;
1961     }
1962 
1963     bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
1964         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1965     if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ != nullptr && isPointDown) {
1966         specificCallback_->onSessionTouchOutside_(GetPersistentId());
1967     }
1968 
1969     auto property = GetSessionProperty();
1970     if (property == nullptr) {
1971         return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
1972     }
1973     auto windowType = property->GetWindowType();
1974     bool isMovableWindowType = IsMovableWindowType();
1975     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
1976     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
1977     bool isDialog = WindowHelper::IsDialogWindow(windowType);
1978     bool isMaxModeAvoidSysBar = property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR;
1979     bool isDragEnabledSystemWindow = WindowHelper::IsSystemWindow(windowType) && property->GetDragEnabled() &&
1980         !isDialog;
1981     bool isMovableSystemWindow = WindowHelper::IsSystemWindow(windowType) && !isDialog;
1982     TLOGD(WmsLogTag::WMS_EVENT, "%{public}s: %{public}d && %{public}d", property->GetWindowName().c_str(),
1983         WindowHelper::IsSystemWindow(windowType), property->GetDragEnabled());
1984     if (isMovableWindowType && (isMainWindow || isSubWindow || isDialog || isDragEnabledSystemWindow ||
1985             isMovableSystemWindow) && !isMaxModeAvoidSysBar) {
1986         if (CheckDialogOnForeground() && isPointDown) {
1987             HandlePointDownDialog();
1988             pointerEvent->MarkProcessed();
1989             TLOGI(WmsLogTag::WMS_DIALOG, "There is dialog window foreground");
1990             return WSError::WS_OK;
1991         }
1992         if (!moveDragController_) {
1993             TLOGD(WmsLogTag::WMS_LAYOUT, "moveDragController_ is null");
1994             return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
1995         }
1996         if ((property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && property->GetDragEnabled())
1997             || isDragEnabledSystemWindow) {
1998             if ((systemConfig_.IsPcWindow() || IsFreeMultiWindowMode() ||
1999                  (property->GetIsPcAppInPad() && !isMainWindow)) &&
2000                 moveDragController_->ConsumeDragEvent(pointerEvent, winRect_, property, systemConfig_)) {
2001                 moveDragController_->UpdateGravityWhenDrag(pointerEvent, surfaceNode_);
2002                 PresentFoucusIfNeed(pointerEvent->GetPointerAction());
2003                 pointerEvent->MarkProcessed();
2004                 return WSError::WS_OK;
2005             }
2006         }
2007         if ((IsDecorEnable() || isMovableSystemWindow) && moveDragController_->
2008                 ConsumeMoveEvent(pointerEvent, winRect_)) {
2009             PresentFoucusIfNeed(pointerEvent->GetPointerAction());
2010             pointerEvent->MarkProcessed();
2011             return WSError::WS_OK;
2012         }
2013     }
2014 
2015     bool raiseEnabled = property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && property->GetRaiseEnabled() &&
2016         (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
2017     if (raiseEnabled) {
2018         RaiseToAppTopForPointDown();
2019     }
2020     return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
2021 }
2022 
IsMovableWindowType()2023 bool SceneSession::IsMovableWindowType()
2024 {
2025     auto property = GetSessionProperty();
2026     if (property == nullptr) {
2027         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2028         return false;
2029     }
2030 
2031     return property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
2032         property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
2033         property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2034         IsFullScreenMovable();
2035 }
2036 
IsFullScreenMovable()2037 bool SceneSession::IsFullScreenMovable()
2038 {
2039     auto property = GetSessionProperty();
2040     if (property == nullptr) {
2041         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2042         return false;
2043     }
2044     return property->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2045         WindowHelper::IsWindowModeSupported(property->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FLOATING);
2046 }
2047 
IsMovable()2048 bool SceneSession::IsMovable()
2049 {
2050     if (!moveDragController_) {
2051         TLOGW(WmsLogTag::WMS_LAYOUT, "moveDragController_ is null, id: %{public}d", GetPersistentId());
2052         return false;
2053     }
2054     if (!(!moveDragController_->GetStartDragFlag() && IsFocused() && IsMovableWindowType() &&
2055           moveDragController_->HasPointDown() && moveDragController_->GetMovable())) {
2056         TLOGW(WmsLogTag::WMS_LAYOUT, "Window is not movable, id: %{public}d, startDragFlag: %{public}d, "
2057             "isFocused: %{public}d, movableWindowType: %{public}d, hasPointDown: %{public}d, movable: %{public}d",
2058             GetPersistentId(), moveDragController_->GetStartDragFlag(), IsFocused(), IsMovableWindowType(),
2059             moveDragController_->HasPointDown(), moveDragController_->GetMovable());
2060         return false;
2061     }
2062     return true;
2063 }
2064 
RequestSessionBack(bool needMoveToBackground)2065 WSError SceneSession::RequestSessionBack(bool needMoveToBackground)
2066 {
2067     auto task = [weakThis = wptr(this), needMoveToBackground]() {
2068         auto session = weakThis.promote();
2069         if (!session) {
2070             WLOGFE("session is null");
2071             return WSError::WS_ERROR_DESTROYED_OBJECT;
2072         }
2073         if (!session->backPressedFunc_) {
2074             WLOGFW("Session didn't register back event consumer!");
2075             return WSError::WS_DO_NOTHING;
2076         }
2077         if (g_enableForceUIFirst) {
2078             auto rsTransaction = RSTransactionProxy::GetInstance();
2079             if (rsTransaction) {
2080                 rsTransaction->Begin();
2081             }
2082             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
2083             if (leashWinSurfaceNode) {
2084                 leashWinSurfaceNode->SetForceUIFirst(true);
2085                 WLOGFI("leashWinSurfaceNode_ SetForceUIFirst id:%{public}u!", session->GetPersistentId());
2086             } else {
2087                 WLOGFI("failed, leashWinSurfaceNode_ null id:%{public}u", session->GetPersistentId());
2088             }
2089             if (rsTransaction) {
2090                 rsTransaction->Commit();
2091             }
2092         }
2093         session->backPressedFunc_(needMoveToBackground);
2094         return WSError::WS_OK;
2095     };
2096     PostTask(task, "RequestSessionBack:" + std::to_string(needMoveToBackground));
2097     return WSError::WS_OK;
2098 }
2099 
GetEnterWindow()2100 const wptr<SceneSession> SceneSession::GetEnterWindow()
2101 {
2102     std::lock_guard<std::mutex> guard(enterSessionMutex_);
2103     return enterSession_;
2104 }
2105 
ClearEnterWindow()2106 void SceneSession::ClearEnterWindow()
2107 {
2108     std::lock_guard<std::mutex> guard(enterSessionMutex_);
2109     enterSession_ = nullptr;
2110 }
2111 
2112 #ifdef DEVICE_STATUS_ENABLE
RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)2113 void SceneSession::RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)
2114 {
2115     Msdp::DeviceStatus::DragState state = Msdp::DeviceStatus::DragState::STOP;
2116     Msdp::DeviceStatus::InteractionManager::GetInstance()->GetDragState(state);
2117     if (state == Msdp::DeviceStatus::DragState::START) {
2118         Msdp::DeviceStatus::InteractionManager::GetInstance()->RotateDragWindowSync(rsTransaction);
2119     }
2120 }
2121 #endif // DEVICE_STATUS_ENABLE
2122 
2123 /** @note @window.layout */
NotifySessionRectChange(const WSRect& rect, const SizeChangeReason reason, const DisplayId displayId)2124 void SceneSession::NotifySessionRectChange(const WSRect& rect,
2125     const SizeChangeReason reason, const DisplayId displayId)
2126 {
2127     auto task = [weakThis = wptr(this), rect, reason, displayId] {
2128         auto session = weakThis.promote();
2129         if (!session) {
2130             WLOGFE("session is null");
2131             return;
2132         }
2133         if (session->sessionRectChangeFunc_) {
2134             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::NotifySessionRectChange");
2135             session->sessionRectChangeFunc_(rect, reason, displayId);
2136         }
2137     };
2138     PostTask(task, "NotifySessionRectChange" + GetRectInfo(rect));
2139 }
2140 
IsDecorEnable() const2141 bool SceneSession::IsDecorEnable() const
2142 {
2143     auto property = GetSessionProperty();
2144     if (property == nullptr) {
2145         WLOGE("property is nullptr");
2146         return false;
2147     }
2148     auto windowType = property->GetWindowType();
2149     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2150     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2151     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
2152     bool isValidWindow = isMainWindow ||
2153         ((isSubWindow || isDialogWindow) && property->IsDecorEnable());
2154     bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
2155         systemConfig_.decorModeSupportInfo_, property->GetWindowMode());
2156     bool enable = isValidWindow && systemConfig_.isSystemDecorEnable_ && isWindowModeSupported;
2157     return enable;
2158 }
2159 
GetRatioPreferenceKey()2160 std::string SceneSession::GetRatioPreferenceKey()
2161 {
2162     std::string key = sessionInfo_.bundleName_ + sessionInfo_.moduleName_ + sessionInfo_.abilityName_;
2163     if (key.length() > ScenePersistentStorage::MAX_KEY_LEN) {
2164         return key.substr(key.length() - ScenePersistentStorage::MAX_KEY_LEN);
2165     }
2166     return key;
2167 }
2168 
SaveAspectRatio(float ratio)2169 bool SceneSession::SaveAspectRatio(float ratio)
2170 {
2171     std::string key = GetRatioPreferenceKey();
2172     if (!key.empty()) {
2173         ScenePersistentStorage::Insert(key, ratio, ScenePersistentStorageType::ASPECT_RATIO);
2174         WLOGD("SceneSession save aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
2175         return true;
2176     }
2177     return false;
2178 }
2179 
FixRectByLimits(WindowLimits limits, WSRect& rect, float ratio, bool isDecor, float vpr)2180 void SceneSession::FixRectByLimits(WindowLimits limits, WSRect& rect, float ratio, bool isDecor, float vpr)
2181 {
2182     if (isDecor) {
2183         rect.width_ = SessionUtils::ToLayoutWidth(rect.width_, vpr);
2184         rect.height_ = SessionUtils::ToLayoutHeight(rect.height_, vpr);
2185         limits.minWidth_ = SessionUtils::ToLayoutWidth(limits.minWidth_, vpr);
2186         limits.maxWidth_ = SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr);
2187         limits.minHeight_ = SessionUtils::ToLayoutHeight(limits.minHeight_, vpr);
2188         limits.maxHeight_ = SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr);
2189     }
2190     if (static_cast<uint32_t>(rect.height_) > limits.maxHeight_) {
2191         rect.height_ = static_cast<int32_t>(limits.maxHeight_);
2192         rect.width_ = floor(rect.height_ * ratio);
2193     } else if (static_cast<uint32_t>(rect.width_) > limits.maxWidth_) {
2194         rect.width_ = static_cast<int32_t>(limits.maxWidth_);
2195         rect.height_ = floor(rect.width_ / ratio);
2196     } else if (static_cast<uint32_t>(rect.width_) < limits.minWidth_) {
2197         rect.width_ = static_cast<int32_t>(limits.minWidth_);
2198         rect.height_ = ceil(rect.width_ / ratio);
2199     } else if (static_cast<uint32_t>(rect.height_) < limits.minHeight_) {
2200         rect.height_ = static_cast<int32_t>(limits.minHeight_);
2201         rect.width_ = ceil(rect.height_ * ratio);
2202     }
2203     if (isDecor) {
2204         rect.height_ = SessionUtils::ToWinHeight(rect.height_, vpr) ;
2205         rect.width_ = SessionUtils::ToWinWidth(rect.width_, vpr);
2206     }
2207 }
FixRectByAspectRatio(WSRect& rect)2208 bool SceneSession::FixRectByAspectRatio(WSRect& rect)
2209 {
2210     const int tolerancePx = 2; // 2: tolerance delta pixel value, unit: px
2211     WSRect originalRect = rect;
2212     auto property = GetSessionProperty();
2213     if (!property || property->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING ||
2214         !WindowHelper::IsMainWindow(GetWindowType())) {
2215         return false;
2216     }
2217 
2218     if (MathHelper::NearZero(aspectRatio_)) {
2219         return false;
2220     }
2221     float vpr = 1.5f; // 1.5f: default virtual pixel ratio
2222     auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2223     if (display) {
2224         vpr = display->GetVirtualPixelRatio();
2225     }
2226     int32_t minW;
2227     int32_t maxW;
2228     int32_t minH;
2229     int32_t maxH;
2230     SessionUtils::CalcFloatWindowRectLimits(property->GetWindowLimits(), systemConfig_.maxFloatingWindowSize_, vpr,
2231         minW, maxW, minH, maxH);
2232     rect.width_ = std::max(minW, static_cast<int32_t>(rect.width_));
2233     rect.width_ = std::min(maxW, static_cast<int32_t>(rect.width_));
2234     rect.height_ = std::max(minH, static_cast<int32_t>(rect.height_));
2235     rect.height_ = std::min(maxH, static_cast<int32_t>(rect.height_));
2236     if (IsDecorEnable()) {
2237         if (SessionUtils::ToLayoutWidth(rect.width_, vpr) >
2238                 SessionUtils::ToLayoutHeight(rect.height_, vpr) * aspectRatio_) {
2239             rect.width_ = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(rect.height_, vpr)* aspectRatio_, vpr);
2240         } else {
2241             rect.height_ = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(rect.width_, vpr) / aspectRatio_, vpr);
2242         }
2243     } else {
2244         if (rect.width_ > rect.height_ * aspectRatio_) {
2245             rect.width_ = rect.height_ * aspectRatio_;
2246         } else {
2247             rect.height_ = rect.width_ / aspectRatio_;
2248         }
2249     }
2250     FixRectByLimits(property->GetWindowLimits(), rect, aspectRatio_, IsDecorEnable(), vpr);
2251     if (std::abs(static_cast<int32_t>(originalRect.width_) - static_cast<int32_t>(rect.width_)) <= tolerancePx &&
2252         std::abs(static_cast<int32_t>(originalRect.height_) - static_cast<int32_t>(rect.height_)) <= tolerancePx) {
2253         rect = originalRect;
2254         return false;
2255     }
2256     return true;
2257 }
2258 
HandleCompatibleModeMoveDrag(WSRect& rect, const SizeChangeReason reason, bool isSupportDragInPcCompatibleMode, bool isGlobal, bool needFlush)2259 void SceneSession::HandleCompatibleModeMoveDrag(WSRect& rect, const SizeChangeReason reason,
2260     bool isSupportDragInPcCompatibleMode, bool isGlobal, bool needFlush)
2261 {
2262     auto sessionProperty = GetSessionProperty();
2263     if (!sessionProperty) {
2264         TLOGE(WmsLogTag::WMS_SCB, "sessionProperty is null");
2265         return;
2266     }
2267     if (reason != SizeChangeReason::MOVE) {
2268         HandleCompatibleModeDrag(rect, reason, isSupportDragInPcCompatibleMode, isGlobal, needFlush);
2269     } else {
2270         SetSurfaceBounds(rect, isGlobal, needFlush);
2271         UpdateSizeChangeReason(reason);
2272     }
2273 }
2274 
HandleCompatibleModeDrag(WSRect& rect, const SizeChangeReason reason, bool isSupportDragInPcCompatibleMode, bool isGlobal, bool needFlush)2275 void SceneSession::HandleCompatibleModeDrag(WSRect& rect, const SizeChangeReason reason,
2276     bool isSupportDragInPcCompatibleMode, bool isGlobal, bool needFlush)
2277 {
2278     auto sessionProperty = GetSessionProperty();
2279     if (!sessionProperty) {
2280         TLOGE(WmsLogTag::WMS_SCB, "sessionProperty is null");
2281         return;
2282     }
2283     WindowLimits windowLimits = sessionProperty->GetWindowLimits();
2284     const int32_t compatibleInPcPortraitWidth = sessionProperty->GetCompatibleInPcPortraitWidth();
2285     const int32_t compatibleInPcPortraitHeight = sessionProperty->GetCompatibleInPcPortraitHeight();
2286     const int32_t compatibleInPcLandscapeWidth = sessionProperty->GetCompatibleInPcLandscapeWidth();
2287     const int32_t compatibleInPcLandscapeHeight = sessionProperty->GetCompatibleInPcLandscapeHeight();
2288     const int32_t compatibleInPcDragLimit = compatibleInPcLandscapeWidth - compatibleInPcPortraitWidth;
2289     WSRect windowRect = GetSessionRect();
2290     auto windowWidth = windowRect.width_;
2291     auto windowHeight = windowRect.height_;
2292 
2293     if (isSupportDragInPcCompatibleMode && windowWidth > windowHeight &&
2294         (rect.width_ < compatibleInPcLandscapeWidth - compatibleInPcDragLimit ||
2295             rect.width_ == static_cast<int32_t>(windowLimits.minWidth_))) {
2296         rect.width_ = compatibleInPcPortraitWidth;
2297         rect.height_ = compatibleInPcPortraitHeight;
2298         SetSurfaceBounds(rect, isGlobal, needFlush);
2299         UpdateSizeChangeReason(reason);
2300         UpdateRect(rect, reason, "compatibleInPcPortrait");
2301     } else if (isSupportDragInPcCompatibleMode && windowWidth < windowHeight &&
2302         rect.width_ > compatibleInPcPortraitWidth + compatibleInPcDragLimit) {
2303         rect.width_ = compatibleInPcLandscapeWidth;
2304         rect.height_ = compatibleInPcLandscapeHeight;
2305         SetSurfaceBounds(rect, isGlobal, needFlush);
2306         UpdateSizeChangeReason(reason);
2307         UpdateRect(rect, reason, "compatibleInPcLandscape");
2308     } else if (isSupportDragInPcCompatibleMode) {
2309         if (windowWidth < windowHeight) {
2310             rect.width_ = compatibleInPcPortraitWidth;
2311             rect.height_ = compatibleInPcPortraitHeight;
2312         } else {
2313             rect.width_ = compatibleInPcLandscapeWidth;
2314             rect.height_ = compatibleInPcLandscapeHeight;
2315         }
2316         rect.posX_ = windowRect.posX_;
2317         rect.posY_ = windowRect.posY_;
2318         SetSurfaceBounds(rect, isGlobal, needFlush);
2319         UpdateSizeChangeReason(reason);
2320     } else {
2321         rect.posX_ = windowRect.posX_;
2322         rect.posY_ = windowRect.posY_;
2323         SetSurfaceBounds(rect, isGlobal, needFlush);
2324         UpdateSizeChangeReason(reason);
2325     }
2326 }
2327 
SetMoveDragCallback()2328 void SceneSession::SetMoveDragCallback()
2329 {
2330     if (moveDragController_) {
2331         MoveDragCallback callBack = [this](const SizeChangeReason reason) {
2332             this->OnMoveDragCallback(reason);
2333         };
2334         moveDragController_->RegisterMoveDragCallback(callBack);
2335     }
2336 }
2337 
InitializeCrossMoveDrag()2338 void SceneSession::InitializeCrossMoveDrag()
2339 {
2340     auto movedSurfaceNode = GetSurfaceNodeForMoveDrag();
2341     if (!movedSurfaceNode) {
2342         return;
2343     }
2344     auto parentNode = movedSurfaceNode->GetParent();
2345     if (!parentNode) {
2346         return;
2347     }
2348     auto property = GetSessionProperty();
2349     if (!property) {
2350         return;
2351     }
2352     moveDragController_->InitCrossDisplayProperty(property->GetDisplayId(), parentNode->GetId());
2353 }
2354 
HandleMoveDrag(WSRect& rect, WSRect& globalRect, const SizeChangeReason reason, bool isGlobal, bool needFlush)2355 void SceneSession::HandleMoveDrag(WSRect& rect, WSRect& globalRect, const SizeChangeReason reason,
2356     bool isGlobal, bool needFlush)
2357 {
2358     SetSurfaceBounds(globalRect, isGlobal, needFlush);
2359     UpdateSizeChangeReason(reason);
2360     if (reason != SizeChangeReason::MOVE) {
2361         UpdateRect(rect, reason, "OnMoveDragCallback");
2362     }
2363 }
2364 
HandleMoveDragEnd(WSRect& rect, const SizeChangeReason reason)2365 void SceneSession::HandleMoveDragEnd(WSRect& rect, const SizeChangeReason reason)
2366 {
2367     if (GetOriPosYBeforeRaisedByKeyboard() != 0) {
2368         TLOGI(WmsLogTag::WMS_KEYBOARD, "Calling session is moved and reset oriPosYBeforeRaisedBykeyboard");
2369         SetOriPosYBeforeRaisedByKeyboard(0);
2370     }
2371     if (moveDragController_->GetMoveDragEndDisplayId() == moveDragController_->GetMoveDragStartDisplayId() ||
2372         moveDragController_->IsSystemWindow()) {
2373         NotifySessionRectChange(rect, reason);
2374     } else {
2375         NotifySessionRectChange(rect, reason, moveDragController_->GetMoveDragEndDisplayId());
2376     }
2377     moveDragController_->ResetCrossMoveDragProperty();
2378     OnSessionEvent(SessionEvent::EVENT_END_MOVE);
2379 }
2380 
OnMoveDragCallback(const SizeChangeReason reason)2381 void SceneSession::OnMoveDragCallback(const SizeChangeReason reason)
2382 {
2383     if (!moveDragController_) {
2384         WLOGE("moveDragController_ is null");
2385         return;
2386     }
2387     auto property = GetSessionProperty();
2388     if (property == nullptr) {
2389         TLOGE(WmsLogTag::WMS_SCB, "property is null");
2390         return;
2391     }
2392     if (reason == SizeChangeReason::DRAG_START) {
2393         InitializeCrossMoveDrag();
2394     }
2395     bool isCompatibleModeInPc = property->GetCompatibleModeInPc();
2396     bool isSupportDragInPcCompatibleMode = property->GetIsSupportDragInPcCompatibleMode();
2397     WSRect rect = moveDragController_->GetTargetRect(reason == SizeChangeReason::DRAG_END ?
2398             MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY :
2399             MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
2400     WSRect globalRect = moveDragController_->GetTargetRect(reason == SizeChangeReason::DRAG_END ?
2401             MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY :
2402             MoveDragController::TargetRectCoordinate::GLOBAL);
2403     bool isGlobal = (reason != SizeChangeReason::DRAG_END);
2404     bool needFlush = (reason != SizeChangeReason::DRAG_END);
2405 
2406     TLOGD(WmsLogTag::WMS_LAYOUT, "Rect: [%{public}d, %{public}d, %{public}u, %{public}u], reason: %{public}d, "
2407         "isCompatibleMode: %{public}d, isSupportDragInPcCompatibleMode: %{public}d", rect.posX_, rect.posY_,
2408         rect.width_, rect.height_, reason, isCompatibleModeInPc, isSupportDragInPcCompatibleMode);
2409     HandleMoveDragSurfaceNode(reason);
2410     if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END) {
2411         UpdateWinRectForSystemBar(rect);
2412     }
2413     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
2414         "SceneSession::OnMoveDragCallback [%d, %d, %u, %u]", rect.posX_, rect.posY_, rect.width_, rect.height_);
2415     if (isCompatibleModeInPc && !IsFreeMultiWindowMode()) {
2416         HandleCompatibleModeMoveDrag(globalRect, reason, isSupportDragInPcCompatibleMode, isGlobal, needFlush);
2417     } else if (reason == SizeChangeReason::DRAG && IsFreeMultiWindowMode()) {
2418         OnSessionEvent(SessionEvent::EVENT_DRAG);
2419         return;
2420     } else {
2421         HandleMoveDrag(rect, globalRect, reason, isGlobal, needFlush);
2422     }
2423     if (reason == SizeChangeReason::DRAG_END) {
2424         HandleMoveDragEnd(rect, reason);
2425     } else if (reason == SizeChangeReason::DRAG_START) {
2426         OnSessionEvent(SessionEvent::EVENT_DRAG_START);
2427     }
2428 }
2429 
HandleMoveDragSurfaceNode(const SizeChangeReason reason)2430 void SceneSession::HandleMoveDragSurfaceNode(const SizeChangeReason reason)
2431 {
2432     auto movedSurfaceNode = GetSurfaceNodeForMoveDrag();
2433     if (movedSurfaceNode == nullptr) {
2434         TLOGD(WmsLogTag::WMS_LAYOUT, "SurfaceNode is null");
2435         return;
2436     }
2437     if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::MOVE) {
2438         for (const auto displayId : moveDragController_->GetNewAddedDisplayIdsDuringMoveDrag()) {
2439             if (displayId == moveDragController_->GetMoveDragStartDisplayId()) {
2440                 continue;
2441             }
2442             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
2443             if (screenSession == nullptr) {
2444                 TLOGD(WmsLogTag::WMS_LAYOUT, "ScreenSession is null");
2445                 continue;
2446             }
2447             movedSurfaceNode->SetPositionZ(MOVE_DRAG_POSITION_Z);
2448             screenSession->GetDisplayNode()->AddCrossParentChild(movedSurfaceNode, -1);
2449         }
2450     } else if (reason == SizeChangeReason::DRAG_END) {
2451         for (const auto displayId : moveDragController_->GetDisplayIdsDuringMoveDrag()) {
2452             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
2453             if (screenSession == nullptr) {
2454                 TLOGD(WmsLogTag::WMS_LAYOUT, "ScreenSession is null");
2455                 continue;
2456             }
2457             screenSession->GetDisplayNode()->RemoveCrossParentChild(
2458                 movedSurfaceNode, moveDragController_->GetInitParentNodeId());
2459         }
2460     }
2461 }
2462 
UpdateWinRectForSystemBar(WSRect& rect)2463 void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
2464 {
2465     if (!specificCallback_) {
2466         WLOGFE("specificCallback_ is null!");
2467         return;
2468     }
2469     auto sessionProperty = GetSessionProperty();
2470     if (!sessionProperty) {
2471         WLOGFE("get session property is null!");
2472         return;
2473     }
2474     float tmpPosY = 0.0;
2475     std::vector<sptr<SceneSession>> statusBarVector;
2476     if (specificCallback_->onGetSceneSessionVectorByType_) {
2477         statusBarVector = specificCallback_->onGetSceneSessionVectorByType_(
2478             WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
2479     }
2480     for (auto& statusBar : statusBarVector) {
2481         if (!(statusBar->isVisible_)) {
2482             continue;
2483         }
2484         WSRect statusBarRect = statusBar->GetSessionRect();
2485         if ((rect.posY_ < statusBarRect.posY_ + static_cast<int32_t>(statusBarRect.height_)) &&
2486             (rect.height_ != winRect_.height_ || rect.width_ != winRect_.width_)) {
2487             tmpPosY = rect.posY_ + rect.height_;
2488             rect.posY_ = statusBarRect.posY_ + statusBarRect.height_;
2489             rect.height_ = tmpPosY - rect.posY_;
2490         }
2491     }
2492     WLOGFD("after UpdateWinRectForSystemBar rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
2493         rect.posX_, rect.posY_, rect.width_, rect.height_);
2494 }
2495 
SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)2496 void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)
2497 {
2498     TLOGD(WmsLogTag::WMS_LAYOUT, "rect: %{public}s", rect.ToString().c_str());
2499     auto rsTransaction = RSTransactionProxy::GetInstance();
2500     if (rsTransaction && needFlush) {
2501         rsTransaction->Begin();
2502     }
2503     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2504     auto property = GetSessionProperty();
2505     if (surfaceNode_ && leashWinSurfaceNode) {
2506         leashWinSurfaceNode->SetGlobalPositionEnabled(isGlobal);
2507         leashWinSurfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2508         leashWinSurfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2509         surfaceNode_->SetBounds(0, 0, rect.width_, rect.height_);
2510         surfaceNode_->SetFrame(0, 0, rect.width_, rect.height_);
2511     } else if (WindowHelper::IsPipWindow(GetWindowType()) && surfaceNode_) {
2512         TLOGD(WmsLogTag::WMS_PIP, "PipWindow setSurfaceBounds");
2513         surfaceNode_->SetGlobalPositionEnabled(isGlobal);
2514         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2515         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2516     } else if (WindowHelper::IsSubWindow(GetWindowType()) && surfaceNode_) {
2517         WLOGFD("subwindow setSurfaceBounds");
2518         surfaceNode_->SetGlobalPositionEnabled(isGlobal);
2519         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2520         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2521     } else if (WindowHelper::IsDialogWindow(GetWindowType()) && surfaceNode_) {
2522         TLOGD(WmsLogTag::WMS_DIALOG, "dialogWindow setSurfaceBounds");
2523         surfaceNode_->SetGlobalPositionEnabled(isGlobal);
2524         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2525         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2526     } else if (WindowHelper::IsSystemWindow(GetWindowType()) &&
2527         property && property->GetDragEnabled() && surfaceNode_) {
2528         TLOGD(WmsLogTag::WMS_SYSTEM, "drag enabled systemwindow setSurfaceBounds");
2529         surfaceNode_->SetGlobalPositionEnabled(isGlobal);
2530         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2531         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2532     } else {
2533         WLOGE("SetSurfaceBounds surfaceNode is null!");
2534     }
2535     if (rsTransaction && needFlush) {
2536         RSTransaction::FlushImplicitTransaction();
2537         rsTransaction->Commit();
2538     }
2539 }
2540 
SetZOrder(uint32_t zOrder)2541 void SceneSession::SetZOrder(uint32_t zOrder)
2542 {
2543     auto task = [weakThis = wptr(this), zOrder]() {
2544         auto session = weakThis.promote();
2545         if (session == nullptr) {
2546             WLOGFE("session is null");
2547             return;
2548         }
2549         if (session->zOrder_ != zOrder) {
2550             session->Session::SetZOrder(zOrder);
2551             if (session->specificCallback_ != nullptr) {
2552                 session->specificCallback_->onWindowInfoUpdate_(session->GetPersistentId(),
2553                     WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2554             }
2555         }
2556     };
2557     PostTask(task, "SetZOrder");
2558 }
2559 
SetFloatingScale(float floatingScale)2560 void SceneSession::SetFloatingScale(float floatingScale)
2561 {
2562     if (floatingScale_ != floatingScale) {
2563         Session::SetFloatingScale(floatingScale);
2564         if (specificCallback_ != nullptr) {
2565             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2566             if (Session::IsScbCoreEnabled()) {
2567                 dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
2568             } else {
2569                 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
2570             }
2571         }
2572     }
2573 }
2574 
SetParentPersistentId(int32_t parentId)2575 void SceneSession::SetParentPersistentId(int32_t parentId)
2576 {
2577     auto property = GetSessionProperty();
2578     if (property) {
2579         property->SetParentPersistentId(parentId);
2580     }
2581 }
2582 
GetParentPersistentId() const2583 int32_t SceneSession::GetParentPersistentId() const
2584 {
2585     auto property = GetSessionProperty();
2586     if (property) {
2587         return property->GetParentPersistentId();
2588     }
2589     return INVALID_SESSION_ID;
2590 }
2591 
GetMainSessionId()2592 int32_t SceneSession::GetMainSessionId()
2593 {
2594     const auto& mainSession = GetMainSession();
2595     if (mainSession) {
2596         return mainSession->GetPersistentId();
2597     }
2598     return INVALID_SESSION_ID;
2599 }
2600 
GetWindowNameAllType() const2601 std::string SceneSession::GetWindowNameAllType() const
2602 {
2603     if (GetSessionInfo().isSystem_) {
2604         return GetSessionInfo().abilityName_;
2605     } else {
2606         return GetWindowName();
2607     }
2608 }
2609 
SetTurnScreenOn(bool turnScreenOn)2610 WSError SceneSession::SetTurnScreenOn(bool turnScreenOn)
2611 {
2612     GetSessionProperty()->SetTurnScreenOn(turnScreenOn);
2613     return WSError::WS_OK;
2614 }
2615 
IsTurnScreenOn() const2616 bool SceneSession::IsTurnScreenOn() const
2617 {
2618     return GetSessionProperty()->IsTurnScreenOn();
2619 }
2620 
SetKeepScreenOn(bool keepScreenOn)2621 WSError SceneSession::SetKeepScreenOn(bool keepScreenOn)
2622 {
2623     GetSessionProperty()->SetKeepScreenOn(keepScreenOn);
2624     return WSError::WS_OK;
2625 }
2626 
IsKeepScreenOn() const2627 bool SceneSession::IsKeepScreenOn() const
2628 {
2629     return GetSessionProperty()->IsKeepScreenOn();
2630 }
2631 
GetSessionSnapshotFilePath() const2632 std::string SceneSession::GetSessionSnapshotFilePath() const
2633 {
2634     WLOGFI("GetSessionSnapshotFilePath id %{public}d", GetPersistentId());
2635     if (Session::GetSessionState() < SessionState::STATE_BACKGROUND) {
2636         WLOGFI("GetSessionSnapshotFilePath UpdateSnapshot");
2637         auto snapshot = Snapshot();
2638         if (scenePersistence_ != nullptr) {
2639             scenePersistence_->SaveSnapshot(snapshot);
2640         }
2641     }
2642     if (scenePersistence_ != nullptr) {
2643         return scenePersistence_->GetSnapshotFilePath();
2644     }
2645     return "";
2646 }
2647 
SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap>& icon)2648 void SceneSession::SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap>& icon)
2649 {
2650     WLOGFI("run SaveUpdatedIcon");
2651     if (scenePersistence_ != nullptr) {
2652         scenePersistence_->SaveUpdatedIcon(icon);
2653     }
2654 }
2655 
GetUpdatedIconPath() const2656 std::string SceneSession::GetUpdatedIconPath() const
2657 {
2658     WLOGFI("run GetUpdatedIconPath");
2659     if (scenePersistence_ != nullptr) {
2660         return scenePersistence_->GetUpdatedIconPath();
2661     }
2662     return "";
2663 }
2664 
UpdateNativeVisibility(bool visible)2665 void SceneSession::UpdateNativeVisibility(bool visible)
2666 {
2667     auto task = [weakThis = wptr(this), visible]() {
2668         auto session = weakThis.promote();
2669         if (!session) {
2670             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
2671             return;
2672         }
2673         int32_t persistentId = session->GetPersistentId();
2674         WLOGFI("[WMSSCB] name: %{public}s, id: %{public}u, visible: %{public}u",
2675             session->sessionInfo_.bundleName_.c_str(), persistentId, visible);
2676         if (session->visibilityChangedDetectFunc_) {
2677             session->visibilityChangedDetectFunc_(session->GetCallingPid(), session->isVisible_, visible);
2678         }
2679         session->isVisible_ = visible;
2680         if (session->specificCallback_ == nullptr) {
2681             WLOGFW("specific callback is null.");
2682             return;
2683         }
2684 
2685         if (visible) {
2686             session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
2687         } else {
2688             session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
2689         }
2690         session->NotifyAccessibilityVisibilityChange();
2691         session->specificCallback_->onUpdateAvoidArea_(persistentId);
2692         // update private state
2693         if (!session->GetSessionProperty()) {
2694             WLOGFE("UpdateNativeVisibility property is null");
2695             return;
2696         }
2697         if (session->updatePrivateStateAndNotifyFunc_ != nullptr) {
2698             session->updatePrivateStateAndNotifyFunc_(persistentId);
2699         }
2700     };
2701     PostTask(task, "UpdateNativeVisibility");
2702 }
2703 
UpdateRotationAvoidArea()2704 void SceneSession::UpdateRotationAvoidArea()
2705 {
2706     if (specificCallback_) {
2707         if (Session::IsScbCoreEnabled()) {
2708             dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
2709         } else {
2710             specificCallback_->onUpdateAvoidArea_(GetPersistentId());
2711         }
2712     }
2713 }
2714 
SetPrivacyMode(bool isPrivacy)2715 void SceneSession::SetPrivacyMode(bool isPrivacy)
2716 {
2717     auto property = GetSessionProperty();
2718     if (!property) {
2719         WLOGFE("SetPrivacyMode property is null");
2720         return;
2721     }
2722     if (!surfaceNode_) {
2723         WLOGFE("surfaceNode_ is null");
2724         return;
2725     }
2726     bool lastPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
2727     if (lastPrivacyMode == isPrivacy) {
2728         WLOGFW("privacy mode is not change, do nothing, isPrivacy:%{public}d", isPrivacy);
2729         return;
2730     }
2731     property->SetPrivacyMode(isPrivacy);
2732     property->SetSystemPrivacyMode(isPrivacy);
2733     auto rsTransaction = RSTransactionProxy::GetInstance();
2734     if (rsTransaction != nullptr) {
2735         rsTransaction->Begin();
2736     }
2737     surfaceNode_->SetSecurityLayer(isPrivacy);
2738     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2739     if (leashWinSurfaceNode != nullptr) {
2740         leashWinSurfaceNode->SetSecurityLayer(isPrivacy);
2741     }
2742     if (rsTransaction != nullptr) {
2743         rsTransaction->Commit();
2744     }
2745     NotifyPrivacyModeChange();
2746 }
2747 
NotifyPrivacyModeChange()2748 void SceneSession::NotifyPrivacyModeChange()
2749 {
2750     auto sessionProperty = GetSessionProperty();
2751     if (sessionProperty == nullptr) {
2752         TLOGW(WmsLogTag::WMS_SCB, "sessionProperty is null");
2753         return;
2754     }
2755 
2756     bool curExtPrivacyMode = combinedExtWindowFlags_.privacyModeFlag;
2757     bool curPrivacyMode = curExtPrivacyMode || sessionProperty->GetPrivacyMode();
2758     TLOGD(WmsLogTag::WMS_SCB, "id:%{public}d, curExtPrivacyMode:%{public}d, session property privacyMode:%{public}d"
2759         ", old privacyMode:%{public}d",
2760         GetPersistentId(), curExtPrivacyMode, sessionProperty->GetPrivacyMode(), isPrivacyMode_);
2761 
2762     if (curPrivacyMode != isPrivacyMode_) {
2763         isPrivacyMode_ = curPrivacyMode;
2764         if (privacyModeChangeNotifyFunc_) {
2765             privacyModeChangeNotifyFunc_(isPrivacyMode_);
2766         }
2767     }
2768 }
2769 
SetSnapshotSkip(bool isSkip)2770 void SceneSession::SetSnapshotSkip(bool isSkip)
2771 {
2772     auto property = GetSessionProperty();
2773     if (!property) {
2774         TLOGE(WmsLogTag::DEFAULT, "property is null");
2775         return;
2776     }
2777     if (!surfaceNode_) {
2778         TLOGE(WmsLogTag::DEFAULT, "surfaceNode_ is null");
2779         return;
2780     }
2781     bool lastSnapshotSkip = property->GetSnapshotSkip();
2782     if (lastSnapshotSkip == isSkip) {
2783         TLOGW(WmsLogTag::DEFAULT, "Snapshot skip does not change, do nothing, isSkip: %{public}d, "
2784             "id: %{public}d", isSkip, GetPersistentId());
2785         return;
2786     }
2787     property->SetSnapshotSkip(isSkip);
2788     surfaceNode_->SetSkipLayer(isSkip);
2789     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2790     if (leashWinSurfaceNode != nullptr) {
2791         leashWinSurfaceNode->SetSkipLayer(isSkip);
2792     }
2793     RSTransaction::FlushImplicitTransaction();
2794 }
2795 
SetWatermarkEnabled(const std::string& watermarkName, bool isEnabled)2796 void SceneSession::SetWatermarkEnabled(const std::string& watermarkName, bool isEnabled)
2797 {
2798     if (!surfaceNode_) {
2799         TLOGE(WmsLogTag::DEFAULT, "surfaceNode is null");
2800         return;
2801     }
2802     TLOGI(WmsLogTag::DEFAULT, "watermarkName:%{public}s, isEnabled:%{public}d, wid:%{public}d",
2803         watermarkName.c_str(), isEnabled, GetPersistentId());
2804     surfaceNode_->SetWatermarkEnabled(watermarkName, isEnabled);
2805     if (auto leashWinSurfaceNode = GetLeashWinSurfaceNode()) {
2806         leashWinSurfaceNode->SetWatermarkEnabled(watermarkName, isEnabled);
2807     }
2808     RSTransaction::FlushImplicitTransaction();
2809 }
2810 
SetPiPTemplateInfo(const PiPTemplateInfo& pipTemplateInfo)2811 void SceneSession::SetPiPTemplateInfo(const PiPTemplateInfo& pipTemplateInfo)
2812 {
2813     pipTemplateInfo_ = pipTemplateInfo;
2814 }
2815 
SetSystemSceneOcclusionAlpha(double alpha)2816 void SceneSession::SetSystemSceneOcclusionAlpha(double alpha)
2817 {
2818     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAbilityBGAlpha");
2819     if (alpha < 0 || alpha > 1.0) {
2820         WLOGFE("OnSetSystemSceneOcclusionAlpha property is null");
2821         return;
2822     }
2823     if (!surfaceNode_) {
2824         WLOGFE("surfaceNode_ is null");
2825         return;
2826     }
2827     uint8_t alpha8bit = static_cast<uint8_t>(alpha * 255);
2828     WLOGFI("SetAbilityBGAlpha alpha8bit=%{public}u.", alpha8bit);
2829     surfaceNode_->SetAbilityBGAlpha(alpha8bit);
2830     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2831     if (leashWinSurfaceNode != nullptr) {
2832         leashWinSurfaceNode->SetAbilityBGAlpha(alpha8bit);
2833     }
2834     RSTransaction::FlushImplicitTransaction();
2835 }
2836 
SetSystemSceneForceUIFirst(bool forceUIFirst)2837 void SceneSession::SetSystemSceneForceUIFirst(bool forceUIFirst)
2838 {
2839     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetForceUIFirst");
2840     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2841     if (leashWinSurfaceNode == nullptr && surfaceNode_ == nullptr) {
2842         TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
2843         return;
2844     }
2845     auto rsTransaction = RSTransactionProxy::GetInstance();
2846     if (rsTransaction) {
2847         RSTransaction::FlushImplicitTransaction();
2848         rsTransaction->Begin();
2849     }
2850     if (leashWinSurfaceNode != nullptr) {
2851         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
2852             leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), forceUIFirst);
2853         leashWinSurfaceNode->SetForceUIFirst(forceUIFirst);
2854     } else if (surfaceNode_ != nullptr) {
2855         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
2856             surfaceNode_->GetName().c_str(), surfaceNode_->GetId(), forceUIFirst);
2857         surfaceNode_->SetForceUIFirst(forceUIFirst);
2858     }
2859     if (rsTransaction) {
2860         rsTransaction->Commit();
2861     }
2862 }
2863 
UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)2864 WSError SceneSession::UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)
2865 {
2866     auto task = [weakThis = wptr(this), needDefaultAnimationFlag]() {
2867         auto session = weakThis.promote();
2868         if (!session) {
2869             WLOGFE("session is null");
2870             return WSError::WS_ERROR_DESTROYED_OBJECT;
2871         }
2872         session->needDefaultAnimationFlag_ = needDefaultAnimationFlag;
2873         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onWindowAnimationFlagChange_) {
2874             session->sessionChangeCallback_->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
2875         }
2876         return WSError::WS_OK;
2877     };
2878     return PostSyncTask(task, "UpdateWindowAnimationFlag");
2879 }
2880 
SetWindowAnimationFlag(bool needDefaultAnimationFlag)2881 void SceneSession::SetWindowAnimationFlag(bool needDefaultAnimationFlag)
2882 {
2883     needDefaultAnimationFlag_ = needDefaultAnimationFlag;
2884     if (sessionChangeCallback_ && sessionChangeCallback_->onWindowAnimationFlagChange_) {
2885         sessionChangeCallback_->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
2886     }
2887     return;
2888 }
2889 
IsNeedDefaultAnimation() const2890 bool SceneSession::IsNeedDefaultAnimation() const
2891 {
2892     return needDefaultAnimationFlag_;
2893 }
2894 
IsAppSession() const2895 bool SceneSession::IsAppSession() const
2896 {
2897     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2898         return true;
2899     }
2900     if (GetParentSession() && GetParentSession()->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2901         return true;
2902     }
2903     return false;
2904 }
2905 
2906 /** @note @window.focus */
IsAppOrLowerSystemSession() const2907 bool SceneSession::IsAppOrLowerSystemSession() const
2908 {
2909     WindowType windowType = GetWindowType();
2910     if (windowType == WindowType::WINDOW_TYPE_NEGATIVE_SCREEN ||
2911         windowType == WindowType::WINDOW_TYPE_GLOBAL_SEARCH ||
2912         windowType == WindowType::WINDOW_TYPE_DESKTOP) {
2913         return true;
2914     }
2915     return IsAppSession();
2916 }
2917 
2918 /** @note @window.focus */
IsSystemSessionAboveApp() const2919 bool SceneSession::IsSystemSessionAboveApp() const
2920 {
2921     WindowType windowType = GetWindowType();
2922     if (windowType == WindowType::WINDOW_TYPE_DIALOG || windowType == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2923         return true;
2924     }
2925     if (windowType == WindowType::WINDOW_TYPE_PANEL &&
2926         sessionInfo_.bundleName_.find("SCBDropdownPanel") != std::string::npos) {
2927         return true;
2928     }
2929     return false;
2930 }
2931 
NotifyIsCustomAnimationPlaying(bool isPlaying)2932 void SceneSession::NotifyIsCustomAnimationPlaying(bool isPlaying)
2933 {
2934     WLOGFI("id %{public}d %{public}u", GetPersistentId(), isPlaying);
2935     if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onIsCustomAnimationPlaying_) {
2936         sessionChangeCallback_->onIsCustomAnimationPlaying_(isPlaying);
2937     }
2938 }
2939 
UpdateWindowSceneAfterCustomAnimation(bool isAdd)2940 WSError SceneSession::UpdateWindowSceneAfterCustomAnimation(bool isAdd)
2941 {
2942     if (!SessionPermission::IsSystemCalling()) {
2943         TLOGE(WmsLogTag::WMS_SYSTEM, "failed to update with id:%{public}u!", GetPersistentId());
2944         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2945     }
2946     auto task = [weakThis = wptr(this), isAdd]() {
2947         auto session = weakThis.promote();
2948         if (!session) {
2949             WLOGFE("session is null");
2950             return WSError::WS_ERROR_DESTROYED_OBJECT;
2951         }
2952         WLOGFI("UpdateWindowSceneAfterCustomAnimation, id %{public}d, isAdd: %{public}d",
2953             session->GetPersistentId(), isAdd);
2954         if (isAdd) {
2955             WLOGFE("SetOpacityFunc not register %{public}d", session->GetPersistentId());
2956             return WSError::WS_ERROR_INVALID_OPERATION;
2957         } else {
2958             WLOGFI("background after custom animation id %{public}d", session->GetPersistentId());
2959             // since background will remove surfaceNode
2960             session->Background();
2961             session->NotifyIsCustomAnimationPlaying(false);
2962         }
2963         return WSError::WS_OK;
2964     };
2965     PostTask(task, "UpdateWindowSceneAfterCustomAnimation:" + std::to_string(isAdd));
2966     return WSError::WS_OK;
2967 }
2968 
IsFloatingWindowAppType() const2969 bool SceneSession::IsFloatingWindowAppType() const
2970 {
2971     auto property = GetSessionProperty();
2972     if (property == nullptr) {
2973         return false;
2974     }
2975     return property->IsFloatingWindowAppType();
2976 }
2977 
GetTouchHotAreas() const2978 std::vector<Rect> SceneSession::GetTouchHotAreas() const
2979 {
2980     std::vector<Rect> touchHotAreas;
2981     auto property = GetSessionProperty();
2982     if (property) {
2983         property->GetTouchHotAreas(touchHotAreas);
2984     }
2985     return touchHotAreas;
2986 }
2987 
GetPiPTemplateInfo() const2988 PiPTemplateInfo SceneSession::GetPiPTemplateInfo() const
2989 {
2990     return pipTemplateInfo_;
2991 }
2992 
DumpSessionElementInfo(const std::vector<std::string>& params)2993 void SceneSession::DumpSessionElementInfo(const std::vector<std::string>& params)
2994 {
2995     if (!sessionStage_) {
2996         return;
2997     }
2998     return sessionStage_->DumpSessionElementInfo(params);
2999 }
3000 
NotifyTouchOutside()3001 void SceneSession::NotifyTouchOutside()
3002 {
3003     WLOGFI("id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
3004     if (sessionStage_) {
3005         WLOGFD("Notify sessionStage TouchOutside");
3006         sessionStage_->NotifyTouchOutside();
3007     }
3008     if (sessionChangeCallback_ && sessionChangeCallback_->OnTouchOutside_) {
3009         WLOGFD("Notify sessionChangeCallback TouchOutside");
3010         sessionChangeCallback_->OnTouchOutside_();
3011     }
3012 }
3013 
NotifyWindowVisibility()3014 void SceneSession::NotifyWindowVisibility()
3015 {
3016     if (sessionStage_) {
3017         sessionStage_->NotifyWindowVisibility(GetRSVisible());
3018     } else {
3019         WLOGFE("Notify window(id:%{public}d) visibility failed, for this session stage is nullptr", GetPersistentId());
3020     }
3021 }
3022 
CheckOutTouchOutsideRegister()3023 bool SceneSession::CheckOutTouchOutsideRegister()
3024 {
3025     if (sessionChangeCallback_ && sessionChangeCallback_->OnTouchOutside_) {
3026         return true;
3027     }
3028     return false;
3029 }
3030 
SetRequestedOrientation(Orientation orientation)3031 void SceneSession::SetRequestedOrientation(Orientation orientation)
3032 {
3033     WLOGFI("id: %{public}d orientation: %{public}u", GetPersistentId(), static_cast<uint32_t>(orientation));
3034     GetSessionProperty()->SetRequestedOrientation(orientation);
3035     if (sessionChangeCallback_ && sessionChangeCallback_->OnRequestedOrientationChange_) {
3036         sessionChangeCallback_->OnRequestedOrientationChange_(static_cast<uint32_t>(orientation));
3037     }
3038 }
3039 
SetDefaultRequestedOrientation(Orientation orientation)3040 WSError SceneSession::SetDefaultRequestedOrientation(Orientation orientation)
3041 {
3042     auto task = [weakThis = wptr(this), orientation]() -> WSError {
3043         auto session = weakThis.promote();
3044         if (!session) {
3045             TLOGE(WmsLogTag::DEFAULT, "session is null");
3046             return WSError::WS_ERROR_NULLPTR;
3047         }
3048         TLOGI(WmsLogTag::DEFAULT, "id: %{public}d defaultRequestedOrientation: %{public}u",
3049             session->GetPersistentId(), static_cast<uint32_t>(orientation));
3050         auto property = session->GetSessionProperty();
3051         if (property == nullptr) {
3052             TLOGE(WmsLogTag::DEFAULT, "get session property failed");
3053             return WSError::WS_ERROR_NULLPTR;
3054         }
3055         property->SetRequestedOrientation(orientation);
3056         property->SetDefaultRequestedOrientation(orientation);
3057         return WSError::WS_OK;
3058     };
3059     return PostSyncTask(task, "SetDefaultRequestedOrientation");
3060 }
3061 
NotifyForceHideChange(bool hide)3062 void SceneSession::NotifyForceHideChange(bool hide)
3063 {
3064     WLOGFI("id: %{public}d forceHide: %{public}u", persistentId_, hide);
3065     auto property = GetSessionProperty();
3066     if (property == nullptr) {
3067         WLOGFD("id: %{public}d property is nullptr", persistentId_);
3068         return;
3069     }
3070     property->SetForceHide(hide);
3071     if (sessionChangeCallback_ && sessionChangeCallback_->OnForceHideChange_) {
3072         sessionChangeCallback_->OnForceHideChange_(hide);
3073     }
3074     SetForceTouchable(!hide);
3075     if (hide) {
3076         if (isFocused_) {
3077             FocusChangeReason reason = FocusChangeReason::DEFAULT;
3078             NotifyRequestFocusStatusNotifyManager(false, true, reason);
3079             SetForceHideState(ForceHideState::HIDDEN_WHEN_FOCUSED);
3080         } else if (forceHideState_ == ForceHideState::NOT_HIDDEN) {
3081             SetForceHideState(ForceHideState::HIDDEN_WHEN_UNFOCUSED);
3082         }
3083     } else {
3084         if (forceHideState_ == ForceHideState::HIDDEN_WHEN_FOCUSED) {
3085             SetForceHideState(ForceHideState::NOT_HIDDEN);
3086             FocusChangeReason reason = FocusChangeReason::DEFAULT;
3087             NotifyRequestFocusStatusNotifyManager(true, true, reason);
3088         } else {
3089             SetForceHideState(ForceHideState::NOT_HIDDEN);
3090         }
3091     }
3092 }
3093 
GetRequestedOrientation() const3094 Orientation SceneSession::GetRequestedOrientation() const
3095 {
3096     return GetSessionProperty()->GetRequestedOrientation();
3097 }
3098 
IsAnco() const3099 bool SceneSession::IsAnco() const
3100 {
3101     return collaboratorType_ == static_cast<int32_t>(CollaboratorType::RESERVE_TYPE);
3102 }
3103 
SetBlankFlag(bool isAddBlank)3104 void SceneSession::SetBlankFlag(bool isAddBlank)
3105 {
3106     isAddBlank_ = isAddBlank;
3107 }
3108 
GetBlankFlag() const3109 bool SceneSession::GetBlankFlag() const
3110 {
3111     return isAddBlank_;
3112 }
3113 
SetBufferAvailableCallbackEnable(bool enable)3114 void SceneSession::SetBufferAvailableCallbackEnable(bool enable)
3115 {
3116     bufferAvailableCallbackEnable_ = enable;
3117 }
3118 
GetBufferAvailableCallbackEnable() const3119 bool SceneSession::GetBufferAvailableCallbackEnable() const
3120 {
3121     return bufferAvailableCallbackEnable_;
3122 }
3123 
GetCollaboratorType() const3124 int32_t SceneSession::GetCollaboratorType() const
3125 {
3126     return collaboratorType_;
3127 }
3128 
SetCollaboratorType(int32_t collaboratorType)3129 void SceneSession::SetCollaboratorType(int32_t collaboratorType)
3130 {
3131     collaboratorType_ = collaboratorType;
3132     sessionInfo_.collaboratorType_ = collaboratorType;
3133 }
3134 
GetClientIdentityToken() const3135 std::string SceneSession::GetClientIdentityToken() const
3136 {
3137     return clientIdentityToken_;
3138 }
3139 
SetClientIdentityToken(const std::string& clientIdentityToken)3140 void SceneSession::SetClientIdentityToken(const std::string& clientIdentityToken)
3141 {
3142     clientIdentityToken_ = clientIdentityToken;
3143 }
3144 
DumpSessionInfo(std::vector<std::string>& info) const3145 void SceneSession::DumpSessionInfo(std::vector<std::string>& info) const
3146 {
3147     std::string dumpInfo = "      Session ID #" + std::to_string(persistentId_);
3148     info.push_back(dumpInfo);
3149     dumpInfo = "        session name [" + SessionUtils::ConvertSessionName(sessionInfo_.bundleName_,
3150         sessionInfo_.abilityName_, sessionInfo_.moduleName_, sessionInfo_.appIndex_) + "]";
3151     info.push_back(dumpInfo);
3152     dumpInfo = "        runningState [" + std::string(isActive_ ? "FOREGROUND" : "BACKGROUND") + "]";
3153     info.push_back(dumpInfo);
3154     dumpInfo = "        lockedState [" + std::to_string(sessionInfo_.lockedState) + "]";
3155     info.push_back(dumpInfo);
3156     auto abilityInfo = sessionInfo_.abilityInfo;
3157     dumpInfo = "        continuable [" + (abilityInfo ? std::to_string(abilityInfo->continuable) : " ") + "]";
3158     info.push_back(dumpInfo);
3159     dumpInfo = "        timeStamp [" + sessionInfo_.time + "]";
3160     info.push_back(dumpInfo);
3161     dumpInfo = "        label [" + (abilityInfo ? abilityInfo->label : " ") + "]";
3162     info.push_back(dumpInfo);
3163     dumpInfo = "        iconPath [" + (abilityInfo ? abilityInfo->iconPath : " ") + "]";
3164     info.push_back(dumpInfo);
3165     dumpInfo = "        want [" + (sessionInfo_.want ? sessionInfo_.want->ToUri() : " ") + "]";
3166     info.push_back(dumpInfo);
3167 }
3168 
GetAbilityInfo() const3169 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSession::GetAbilityInfo() const
3170 {
3171     const SessionInfo& sessionInfo = GetSessionInfo();
3172     return sessionInfo.abilityInfo;
3173 }
3174 
SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)3175 void SceneSession::SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
3176 {
3177     SetSessionInfoAbilityInfo(abilityInfo);
3178 }
3179 
SetSessionState(SessionState state)3180 void SceneSession::SetSessionState(SessionState state)
3181 {
3182     Session::SetSessionState(state);
3183     NotifyAccessibilityVisibilityChange();
3184 }
3185 
UpdateSessionState(SessionState state)3186 void SceneSession::UpdateSessionState(SessionState state)
3187 {
3188     Session::UpdateSessionState(state);
3189     NotifyAccessibilityVisibilityChange();
3190 }
3191 
IsVisibleForAccessibility() const3192 bool SceneSession::IsVisibleForAccessibility() const
3193 {
3194     if (Session::IsScbCoreEnabled()) {
3195         return GetSystemTouchable() && GetForegroundInteractiveStatus() && IsVisibleForeground();
3196     }
3197     return GetSystemTouchable() && GetForegroundInteractiveStatus() &&
3198         (IsVisible() || state_ == SessionState::STATE_ACTIVE || state_ == SessionState::STATE_FOREGROUND);
3199 }
3200 
SetForegroundInteractiveStatus(bool interactive)3201 void SceneSession::SetForegroundInteractiveStatus(bool interactive)
3202 {
3203     Session::SetForegroundInteractiveStatus(interactive);
3204     NotifyAccessibilityVisibilityChange();
3205     if (interactive) {
3206         return;
3207     }
3208     for (auto toastSession : toastSession_) {
3209         if (toastSession == nullptr) {
3210             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
3211             continue;
3212         }
3213         auto state = toastSession->GetSessionState();
3214         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
3215             continue;
3216         }
3217         toastSession->SetActive(false);
3218         toastSession->BackgroundTask();
3219     }
3220 }
3221 
NotifyAccessibilityVisibilityChange()3222 void SceneSession::NotifyAccessibilityVisibilityChange()
3223 {
3224     bool isVisibleForAccessibilityNew = IsVisibleForAccessibility();
3225     if (isVisibleForAccessibilityNew == isVisibleForAccessibility_.load()) {
3226         return;
3227     }
3228     WLOGFD("[WMSAccess] NotifyAccessibilityVisibilityChange id: %{public}d, access: %{public}d ",
3229         GetPersistentId(), isVisibleForAccessibilityNew);
3230     isVisibleForAccessibility_.store(isVisibleForAccessibilityNew);
3231     if (specificCallback_ && specificCallback_->onWindowInfoUpdate_) {
3232         if (isVisibleForAccessibilityNew) {
3233             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
3234         } else {
3235             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
3236         }
3237     } else {
3238         WLOGFD("specificCallback_->onWindowInfoUpdate_ not exist, persistent id: %{public}d", GetPersistentId());
3239     }
3240 }
3241 
SetSystemTouchable(bool touchable)3242 void SceneSession::SetSystemTouchable(bool touchable)
3243 {
3244     Session::SetSystemTouchable(touchable);
3245     NotifyAccessibilityVisibilityChange();
3246 }
3247 
ChangeSessionVisibilityWithStatusBar( const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool visible)3248 WSError SceneSession::ChangeSessionVisibilityWithStatusBar(
3249     const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool visible)
3250 {
3251     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
3252         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
3253         return WSError::WS_ERROR_INVALID_PERMISSION;
3254     }
3255     auto task = [weakThis = wptr(this), abilitySessionInfo, visible]() {
3256         auto session = weakThis.promote();
3257         if (!session) {
3258             WLOGFE("session is null");
3259             return WSError::WS_ERROR_DESTROYED_OBJECT;
3260         }
3261         if (abilitySessionInfo == nullptr) {
3262             WLOGFE("abilitySessionInfo is null");
3263             return WSError::WS_ERROR_NULLPTR;
3264         }
3265 
3266         SessionInfo info;
3267         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
3268         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
3269         info.moduleName_ = abilitySessionInfo->want.GetModuleName();
3270         int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
3271         info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
3272         info.persistentId_ = abilitySessionInfo->persistentId;
3273         info.callerPersistentId_ = session->GetPersistentId();
3274         info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
3275         info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
3276         info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
3277         info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
3278         info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
3279         info.requestCode = abilitySessionInfo->requestCode;
3280         info.callerToken_ = abilitySessionInfo->callerToken;
3281         info.startSetting = abilitySessionInfo->startSetting;
3282         info.callingTokenId_ = abilitySessionInfo->callingTokenId;
3283         info.reuse = abilitySessionInfo->reuse;
3284         info.processOptions = abilitySessionInfo->processOptions;
3285 
3286         if (session->changeSessionVisibilityWithStatusBarFunc_) {
3287             session->changeSessionVisibilityWithStatusBarFunc_(info, visible);
3288         }
3289 
3290         return WSError::WS_OK;
3291     };
3292     PostTask(task, "ChangeSessionVisibilityWithStatusBar");
3293     return WSError::WS_OK;
3294 }
3295 
MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo>& abilitySessionInfo, const sptr<SceneSession>& session)3296 static SessionInfo MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo>& abilitySessionInfo,
3297     const sptr<SceneSession>& session)
3298 {
3299     SessionInfo info;
3300     info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
3301     info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
3302     info.moduleName_ = abilitySessionInfo->want.GetModuleName();
3303     int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
3304     info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
3305     info.persistentId_ = abilitySessionInfo->persistentId;
3306     info.callerPersistentId_ = session->GetPersistentId();
3307     info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
3308     info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
3309     info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
3310     info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
3311     info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
3312     info.requestCode = abilitySessionInfo->requestCode;
3313     info.callerToken_ = abilitySessionInfo->callerToken;
3314     info.startSetting = abilitySessionInfo->startSetting;
3315     info.callingTokenId_ = abilitySessionInfo->callingTokenId;
3316     info.reuse = abilitySessionInfo->reuse;
3317     info.processOptions = abilitySessionInfo->processOptions;
3318     info.isAtomicService_ = abilitySessionInfo->isAtomicService;
3319     info.isBackTransition_ = abilitySessionInfo->isBackTransition;
3320     info.needClearInNotShowRecent_ = abilitySessionInfo->needClearInNotShowRecent;
3321     info.appInstanceKey_ = abilitySessionInfo->instanceKey;
3322     info.isFromIcon_ = abilitySessionInfo->isFromIcon;
3323     if (session->IsPcOrPadEnableActivation()) {
3324         info.startWindowOption = abilitySessionInfo->startWindowOption;
3325     }
3326     if (info.want != nullptr) {
3327         info.windowMode = info.want->GetIntParam(AAFwk::Want::PARAM_RESV_WINDOW_MODE, 0);
3328         info.sessionAffinity = info.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
3329         info.screenId_ = static_cast<uint64_t>(info.want->GetIntParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, -1));
3330         TLOGI(WmsLogTag::WMS_LIFE, "want: screenId %{public}" PRIu64, info.screenId_);
3331     }
3332     if (info.windowMode == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN)) {
3333         info.fullScreenStart_ = true;
3334     }
3335     TLOGI(WmsLogTag::WMS_LIFE, "bundleName:%{public}s, moduleName:%{public}s, "
3336         "abilityName:%{public}s, appIndex:%{public}d, affinity:%{public}s. "
3337         "callState:%{public}d, want persistentId:%{public}d, "
3338         "uiAbilityId:%{public}" PRIu64 ", windowMode:%{public}d, callerId: %{public}d "
3339         "needClearInNotShowRecent:%{public}u, appInstanceKey: %{public}s, isFromIcon:%{public}d",
3340         info.bundleName_.c_str(), info.moduleName_.c_str(), info.abilityName_.c_str(), info.appIndex_,
3341         info.sessionAffinity.c_str(), info.callState_, info.persistentId_, info.uiAbilityId_,
3342         info.windowMode, info.callerPersistentId_, info.needClearInNotShowRecent_, info.appInstanceKey_.c_str(),
3343         info.isFromIcon_);
3344     return info;
3345 }
3346 
PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)3347 WSError SceneSession::PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
3348 {
3349     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
3350         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
3351         return WSError::WS_ERROR_INVALID_PERMISSION;
3352     }
3353     bool isFoundationCall = SessionPermission::IsFoundationCall();
3354     auto task = [weakThis = wptr(this), abilitySessionInfo, isFoundationCall]() {
3355         auto session = weakThis.promote();
3356         if (!session) {
3357             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
3358             return WSError::WS_ERROR_DESTROYED_OBJECT;
3359         }
3360         if (abilitySessionInfo == nullptr) {
3361             TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
3362             return WSError::WS_ERROR_NULLPTR;
3363         }
3364         if (!session->IsPcOrPadEnableActivation() && WindowHelper::IsMainWindow(session->GetWindowType())) {
3365             SessionState sessionState = session->GetSessionState();
3366             TLOGI(WmsLogTag::WMS_LIFE, "sceneSession state:%{public}d, isFoundationCall:%{public}u, "
3367                 "canStartAbilityFromBackground:%{public}u, foregroundInteractiveStatus:%{public}u",
3368                 sessionState, isFoundationCall, abilitySessionInfo->canStartAbilityFromBackground,
3369                 session->GetForegroundInteractiveStatus());
3370             bool isSessionForeground = sessionState == SessionState::STATE_FOREGROUND ||
3371                 sessionState == SessionState::STATE_ACTIVE;
3372             if (isSessionForeground && !session->GetForegroundInteractiveStatus()) {
3373                 TLOGW(WmsLogTag::WMS_LIFE, "start ability invalid, sceneSession in a non interactive state");
3374                 return WSError::WS_ERROR_INVALID_OPERATION;
3375             }
3376             if (!isSessionForeground && !(isFoundationCall && abilitySessionInfo->canStartAbilityFromBackground)) {
3377                 TLOGW(WmsLogTag::WMS_LIFE, "no permission to start ability from Background");
3378                 return WSError::WS_ERROR_INVALID_OPERATION;
3379             }
3380         }
3381         session->sessionInfo_.startMethod = StartMethod::START_CALL;
3382         SessionInfo info = MakeSessionInfoDuringPendingActivation(abilitySessionInfo, session);
3383         if (MultiInstanceManager::IsSupportMultiInstance(session->systemConfig_) &&
3384             MultiInstanceManager::GetInstance().IsMultiInstance(session->GetSessionInfo().bundleName_)) {
3385             if (!MultiInstanceManager::GetInstance().MultiInstancePendingSessionActivation(info)) {
3386                 TLOGE(WmsLogTag::WMS_LIFE, "multi instance start fail, id:%{public}d instanceKey:%{public}s",
3387                     session->GetPersistentId(), info.appInstanceKey_.c_str());
3388                 return WSError::WS_ERROR_INVALID_PARAM;
3389             }
3390         }
3391         session->HandleCastScreenConnection(info, session);
3392         if (session->pendingSessionActivationFunc_) {
3393             session->pendingSessionActivationFunc_(info);
3394         }
3395         return WSError::WS_OK;
3396     };
3397     PostTask(task, "PendingSessionActivation");
3398     return WSError::WS_OK;
3399 }
3400 
HandleCastScreenConnection(SessionInfo& info, sptr<SceneSession> session)3401 void SceneSession::HandleCastScreenConnection(SessionInfo& info, sptr<SceneSession> session)
3402 {
3403     ScreenId defScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
3404     if (defScreenId == info.screenId_) {
3405         return;
3406     }
3407     auto flag = Rosen::ScreenManager::GetInstance().GetVirtualScreenFlag(info.screenId_);
3408     if (flag != VirtualScreenFlag::CAST) {
3409         return;
3410     }
3411     TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state :%{public}d persistentId:%{public}d",
3412         session->GetSessionState(), info.callerPersistentId_);
3413     if (session->GetSessionState() != SessionState::STATE_FOREGROUND &&
3414         session->GetSessionState() != SessionState::STATE_ACTIVE) {
3415         TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state is not foreground");
3416         return;
3417     }
3418     info.isCastSession_ = true;
3419     std::vector<uint64_t> mirrorIds { info.screenId_ };
3420     Rosen::DMError ret = Rosen::ScreenManager::GetInstance().MakeUniqueScreen(mirrorIds);
3421     if (ret != Rosen::DMError::DM_OK) {
3422         TLOGE(WmsLogTag::WMS_LIFE, "MakeUniqueScreen failed,ret: %{public}d", ret);
3423         return;
3424     }
3425 }
3426 
IsNeedSystemPermissionByAction(WSPropertyChangeAction action, const sptr<WindowSessionProperty>& property, const sptr<WindowSessionProperty>& sessionProperty)3427 static bool IsNeedSystemPermissionByAction(WSPropertyChangeAction action,
3428     const sptr<WindowSessionProperty>& property, const sptr<WindowSessionProperty>& sessionProperty)
3429 {
3430     switch (action) {
3431         case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON:
3432         case WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP:
3433         case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
3434         case WSPropertyChangeAction::ACTION_UPDATE_TOPMOST:
3435         case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE:
3436         case WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED:
3437         case WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED:
3438         case WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO:
3439             return true;
3440         case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG:
3441             return property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM);
3442         case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
3443             uint32_t oldFlags = sessionProperty->GetWindowFlags();
3444             uint32_t flags = property->GetWindowFlags();
3445             if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
3446                 return true;
3447             }
3448             break;
3449         }
3450         default:
3451             break;
3452     }
3453     return false;
3454 }
3455 
UpdateSessionPropertyByAction(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3456 WMError SceneSession::UpdateSessionPropertyByAction(const sptr<WindowSessionProperty>& property,
3457     WSPropertyChangeAction action)
3458 {
3459     if (property == nullptr) {
3460         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
3461         return WMError::WM_ERROR_NULLPTR;
3462     }
3463     auto sessionProperty = GetSessionProperty();
3464     if (sessionProperty == nullptr) {
3465         TLOGE(WmsLogTag::DEFAULT, "get session property failed");
3466         return WMError::WM_ERROR_NULLPTR;
3467     }
3468     if (action == WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE) {
3469         if (!SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
3470             return WMError::WM_ERROR_INVALID_PERMISSION;
3471         }
3472     }
3473     if (action == WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST) {
3474         uint32_t accessTokenId = property->GetAccessTokenId();
3475         if (!SessionPermission::VerifyPermissionByCallerToken(accessTokenId,
3476             PermissionConstants::PERMISSION_MAIN_WINDOW_TOPMOST)) {
3477             TLOGE(WmsLogTag::WMS_HIERARCHY, "The caller has no permission granted.");
3478             return WMError::WM_ERROR_INVALID_PERMISSION;
3479         }
3480     }
3481 
3482     bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
3483     if (!isSystemCalling && IsNeedSystemPermissionByAction(action, property, sessionProperty)) {
3484         TLOGE(WmsLogTag::DEFAULT, "permission denied! action: %{public}u", action);
3485         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3486     }
3487     property->SetSystemCalling(isSystemCalling);
3488     wptr<SceneSession> weak = this;
3489     auto task = [weak, property, action]() -> WMError {
3490         auto sceneSession = weak.promote();
3491         if (sceneSession == nullptr) {
3492             TLOGE(WmsLogTag::DEFAULT, "the session is nullptr");
3493             return WMError::WM_DO_NOTHING;
3494         }
3495         TLOGD(WmsLogTag::DEFAULT, "Id: %{public}d, action: %{public}u", sceneSession->GetPersistentId(), action);
3496         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession:UpdateProperty");
3497         return sceneSession->HandleUpdatePropertyByAction(property, action);
3498     };
3499     if (AppExecFwk::EventRunner::IsAppMainThread()) {
3500         PostTask(task, "UpdateProperty");
3501         return WMError::WM_OK;
3502     }
3503     return PostSyncTask(task, "UpdateProperty");
3504 }
3505 
SetGestureBackEnabled(bool isEnabled)3506 WMError SceneSession::SetGestureBackEnabled(bool isEnabled)
3507 {
3508     auto task = [weakThis = wptr(this), isEnabled] {
3509         auto sceneSession = weakThis.promote();
3510         if (!sceneSession) {
3511             TLOGNE(WmsLogTag::WMS_IMMS, "session is invalid");
3512             return;
3513         }
3514         if (sceneSession->isEnableGestureBack_ == isEnabled) {
3515             TLOGNI(WmsLogTag::WMS_IMMS, "isEnabled equals last.");
3516             return;
3517         }
3518         TLOGNI(WmsLogTag::WMS_IMMS, "id: %{public}d, isEnabled: %{public}d",
3519             sceneSession->GetPersistentId(), isEnabled);
3520         sceneSession->isEnableGestureBack_ = isEnabled;
3521         sceneSession->isEnableGestureBackHadSet_ = true;
3522         sceneSession->UpdateGestureBackEnabled();
3523     };
3524     PostTask(task, __func__);
3525     return WMError::WM_OK;
3526 }
3527 
GetGestureBackEnabled()3528 bool SceneSession::GetGestureBackEnabled()
3529 {
3530     return isEnableGestureBack_;
3531 }
3532 
GetEnableGestureBackHadSet()3533 bool SceneSession::GetEnableGestureBackHadSet()
3534 {
3535     return isEnableGestureBackHadSet_;
3536 }
3537 
SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc& func)3538 void SceneSession::SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc& func)
3539 {
3540     TLOGD(WmsLogTag::DEFAULT, "setListener success");
3541     sessionChangeByActionNotifyManagerFunc_ = func;
3542 }
3543 
HandleUpdatePropertyByAction(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3544 WMError SceneSession::HandleUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
3545     WSPropertyChangeAction action)
3546 {
3547     if (property == nullptr) {
3548         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
3549         return WMError::WM_ERROR_NULLPTR;
3550     }
3551 
3552     return ProcessUpdatePropertyByAction(property, action);
3553 }
3554 
ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3555 WMError SceneSession::ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
3556     WSPropertyChangeAction action)
3557 {
3558     switch (static_cast<uint32_t>(action)) {
3559         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON):
3560             return HandleActionUpdateTurnScreenOn(property, action);
3561         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON):
3562             return HandleActionUpdateKeepScreenOn(property, action);
3563         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE):
3564             return HandleActionUpdateFocusable(property, action);
3565         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE):
3566             return HandleActionUpdateTouchable(property, action);
3567         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS):
3568             return HandleActionUpdateSetBrightness(property, action);
3569         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION):
3570             return HandleActionUpdateOrientation(property, action);
3571         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE):
3572             return HandleActionUpdatePrivacyMode(property, action);
3573         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE):
3574             return HandleActionUpdatePrivacyMode(property, action);
3575         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP):
3576             return HandleActionUpdateSnapshotSkip(property, action);
3577         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE):
3578             return HandleActionUpdateMaximizeState(property, action);
3579         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS):
3580             return HandleActionUpdateOtherProps(property, action);
3581         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS):
3582             return HandleActionUpdateStatusProps(property, action);
3583         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS):
3584             return HandleActionUpdateNavigationProps(property, action);
3585         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS):
3586             return HandleActionUpdateNavigationIndicatorProps(property, action);
3587         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_FLAGS):
3588             return HandleActionUpdateFlags(property, action);
3589         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE):
3590             return HandleActionUpdateMode(property, action);
3591         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG):
3592             return HandleActionUpdateAnimationFlag(property, action);
3593         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA):
3594             return HandleActionUpdateTouchHotArea(property, action);
3595         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE):
3596             return HandleActionUpdateDecorEnable(property, action);
3597         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS):
3598             return HandleActionUpdateWindowLimits(property, action);
3599         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED):
3600             return HandleActionUpdateDragenabled(property, action);
3601         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED):
3602             return HandleActionUpdateRaiseenabled(property, action);
3603         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS):
3604             return HandleActionUpdateHideNonSystemFloatingWindows(property, action);
3605         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO):
3606             return HandleActionUpdateTextfieldAvoidInfo(property, action);
3607         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK):
3608             return HandleActionUpdateWindowMask(property, action);
3609         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TOPMOST):
3610             return HandleActionUpdateTopmost(property, action);
3611         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST):
3612             return HandleActionUpdateMainWindowTopmost(property, action);
3613         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO):
3614             return HandleActionUpdateModeSupportInfo(property, action);
3615         default:
3616             TLOGE(WmsLogTag::DEFAULT, "Failed to find func handler!");
3617             return WMError::WM_DO_NOTHING;
3618     }
3619 }
3620 
HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3621 WMError SceneSession::HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty>& property,
3622     WSPropertyChangeAction action)
3623 {
3624     SetTurnScreenOn(property->IsTurnScreenOn());
3625 #ifdef POWER_MANAGER_ENABLE
3626     auto task = [weakThis = wptr(this)]() {
3627         auto sceneSession = weakThis.promote();
3628         if (!sceneSession) {
3629             TLOGE(WmsLogTag::DEFAULT, "session is invalid");
3630             return;
3631         }
3632         TLOGD(WmsLogTag::DEFAULT, "Win: %{public}s, is turn on: %{public}d",
3633             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
3634         std::string identity = IPCSkeleton::ResetCallingIdentity();
3635         if (sceneSession->IsTurnScreenOn()) {
3636             TLOGI(WmsLogTag::DEFAULT, "turn screen on");
3637             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
3638         }
3639         // set ipc identity to raw
3640         IPCSkeleton::SetCallingIdentity(identity);
3641     };
3642     PostTask(task, "HandleTurnScreenOn");
3643 #else
3644     TLOGD(WmsLogTag::DEFAULT, "Can not found the sub system of PowerMgr");
3645 #endif
3646     return WMError::WM_OK;
3647 }
3648 
HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3649 WMError SceneSession::HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty>& property,
3650     WSPropertyChangeAction action)
3651 {
3652     SetKeepScreenOn(property->IsKeepScreenOn());
3653     NotifySessionChangeByActionNotifyManager(property, action);
3654     return WMError::WM_OK;
3655 }
3656 
HandleActionUpdateFocusable(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3657 WMError SceneSession::HandleActionUpdateFocusable(const sptr<WindowSessionProperty>& property,
3658     WSPropertyChangeAction action)
3659 {
3660     SetFocusable(property->GetFocusable());
3661     NotifySessionChangeByActionNotifyManager(property, action);
3662     return WMError::WM_OK;
3663 }
3664 
HandleActionUpdateTouchable(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3665 WMError SceneSession::HandleActionUpdateTouchable(const sptr<WindowSessionProperty>& property,
3666     WSPropertyChangeAction action)
3667 {
3668     SetTouchable(property->GetTouchable());
3669     NotifySessionChangeByActionNotifyManager(property, action);
3670     return WMError::WM_OK;
3671 }
3672 
HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3673 WMError SceneSession::HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty>& property,
3674     WSPropertyChangeAction action)
3675 {
3676     if (GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3677         TLOGW(WmsLogTag::DEFAULT, "only app main window can set brightness");
3678         return WMError::WM_OK;
3679     }
3680     if (!IsSessionValid()) {
3681         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
3682             GetPersistentId(), GetSessionState());
3683         return WMError::WM_ERROR_INVALID_SESSION;
3684     }
3685     float brightness = property->GetBrightness();
3686     if (std::abs(brightness - GetBrightness()) < std::numeric_limits<float>::epsilon()) {
3687         TLOGD(WmsLogTag::DEFAULT, "Session brightness do not change: [%{public}f]", brightness);
3688         return WMError::WM_OK;
3689     }
3690     SetBrightness(brightness);
3691     NotifySessionChangeByActionNotifyManager(property, action);
3692     return WMError::WM_OK;
3693 }
3694 
HandleActionUpdateOrientation(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3695 WMError SceneSession::HandleActionUpdateOrientation(const sptr<WindowSessionProperty>& property,
3696     WSPropertyChangeAction action)
3697 {
3698     SetRequestedOrientation(property->GetRequestedOrientation());
3699     return WMError::WM_OK;
3700 }
3701 
HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3702 WMError SceneSession::HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty>& property,
3703     WSPropertyChangeAction action)
3704 {
3705     bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
3706     SetPrivacyMode(isPrivacyMode);
3707     NotifySessionChangeByActionNotifyManager(property, action);
3708     return WMError::WM_OK;
3709 }
3710 
HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3711 WMError SceneSession::HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty>& property,
3712     WSPropertyChangeAction action)
3713 {
3714     SetSnapshotSkip(property->GetSnapshotSkip());
3715     return WMError::WM_OK;
3716 }
3717 
HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3718 WMError SceneSession::HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty>& property,
3719     WSPropertyChangeAction action)
3720 {
3721     auto sessionProperty = GetSessionProperty();
3722     if (sessionProperty != nullptr) {
3723         sessionProperty->SetMaximizeMode(property->GetMaximizeMode());
3724         sessionProperty->SetIsLayoutFullScreen(property->IsLayoutFullScreen());
3725     }
3726     return WMError::WM_OK;
3727 }
3728 
HandleActionUpdateOtherProps(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3729 WMError SceneSession::HandleActionUpdateOtherProps(const sptr<WindowSessionProperty>& property,
3730     WSPropertyChangeAction action)
3731 {
3732     auto systemBarProperties = property->GetSystemBarProperty();
3733     for (auto iter : systemBarProperties) {
3734         SetSystemBarProperty(iter.first, iter.second);
3735     }
3736     NotifySessionChangeByActionNotifyManager(property, action);
3737     return WMError::WM_OK;
3738 }
3739 
HandleActionUpdateStatusProps(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3740 WMError SceneSession::HandleActionUpdateStatusProps(const sptr<WindowSessionProperty>& property,
3741     WSPropertyChangeAction action)
3742 {
3743     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, property);
3744     NotifySessionChangeByActionNotifyManager(property, action);
3745     return WMError::WM_OK;
3746 }
3747 
HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3748 WMError SceneSession::HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty>& property,
3749     WSPropertyChangeAction action)
3750 {
3751     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, property);
3752     NotifySessionChangeByActionNotifyManager(property, action);
3753     return WMError::WM_OK;
3754 }
3755 
HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3756 WMError SceneSession::HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty>& property,
3757     WSPropertyChangeAction action)
3758 {
3759     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, property);
3760     NotifySessionChangeByActionNotifyManager(property, action);
3761     return WMError::WM_OK;
3762 }
3763 
HandleActionUpdateFlags(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3764 WMError SceneSession::HandleActionUpdateFlags(const sptr<WindowSessionProperty>& property,
3765     WSPropertyChangeAction action)
3766 {
3767     SetWindowFlags(property);
3768     NotifySessionChangeByActionNotifyManager(property, action);
3769     return WMError::WM_OK;
3770 }
3771 
HandleActionUpdateMode(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3772 WMError SceneSession::HandleActionUpdateMode(const sptr<WindowSessionProperty>& property,
3773     WSPropertyChangeAction action)
3774 {
3775     auto sessionProperty = GetSessionProperty();
3776     if (sessionProperty != nullptr) {
3777         sessionProperty->SetWindowMode(property->GetWindowMode());
3778     }
3779     NotifySessionChangeByActionNotifyManager(property, action);
3780     return WMError::WM_OK;
3781 }
3782 
HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3783 WMError SceneSession::HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty>& property,
3784     WSPropertyChangeAction action)
3785 {
3786     auto sessionProperty = GetSessionProperty();
3787     if (sessionProperty != nullptr) {
3788         sessionProperty->SetAnimationFlag(property->GetAnimationFlag());
3789     }
3790     return WMError::WM_OK;
3791 }
3792 
HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3793 WMError SceneSession::HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty>& property,
3794     WSPropertyChangeAction action)
3795 {
3796     auto sessionProperty = GetSessionProperty();
3797     if (sessionProperty != nullptr) {
3798         std::vector<Rect> touchHotAreas;
3799         property->GetTouchHotAreas(touchHotAreas);
3800         sessionProperty->SetTouchHotAreas(touchHotAreas);
3801     }
3802     return WMError::WM_OK;
3803 }
3804 
HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3805 WMError SceneSession::HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty>& property,
3806     WSPropertyChangeAction action)
3807 {
3808     if (property != nullptr && !property->GetSystemCalling()) {
3809         TLOGE(WmsLogTag::DEFAULT, "update decor enable permission denied!");
3810         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3811     }
3812     auto sessionProperty = GetSessionProperty();
3813     if (sessionProperty != nullptr) {
3814         sessionProperty->SetDecorEnable(property->IsDecorEnable());
3815     }
3816     return WMError::WM_OK;
3817 }
3818 
HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3819 WMError SceneSession::HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty>& property,
3820     WSPropertyChangeAction action)
3821 {
3822     auto sessionProperty = GetSessionProperty();
3823     if (sessionProperty != nullptr) {
3824         sessionProperty->SetWindowLimits(property->GetWindowLimits());
3825         WindowLimits windowLimits = sessionProperty->GetWindowLimits();
3826         TLOGI(WmsLogTag::WMS_LAYOUT, "UpdateWindowLimits minWidth:%{public}u, minHeight:%{public}u, "
3827             "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", windowLimits.minWidth_,
3828             windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
3829     }
3830     return WMError::WM_OK;
3831 }
3832 
HandleActionUpdateDragenabled(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3833 WMError SceneSession::HandleActionUpdateDragenabled(const sptr<WindowSessionProperty>& property,
3834     WSPropertyChangeAction action)
3835 {
3836     if (!property->GetSystemCalling()) {
3837         TLOGE(WmsLogTag::DEFAULT, "Update property dragEnabled permission denied!");
3838         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3839     }
3840 
3841     auto sessionProperty = GetSessionProperty();
3842     if (sessionProperty != nullptr) {
3843         sessionProperty->SetDragEnabled(property->GetDragEnabled());
3844     }
3845     return WMError::WM_OK;
3846 }
3847 
HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3848 WMError SceneSession::HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty>& property,
3849     WSPropertyChangeAction action)
3850 {
3851     if (!property->GetSystemCalling()) {
3852         TLOGE(WmsLogTag::DEFAULT, "Update property raiseEnabled permission denied!");
3853         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3854     }
3855 
3856     auto sessionProperty = GetSessionProperty();
3857     if (sessionProperty != nullptr) {
3858         sessionProperty->SetRaiseEnabled(property->GetRaiseEnabled());
3859     }
3860     return WMError::WM_OK;
3861 }
3862 
HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3863 WMError SceneSession::HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3864     WSPropertyChangeAction action)
3865 {
3866     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3867         TLOGE(WmsLogTag::DEFAULT, "Update property hideNonSystemFloatingWindows permission denied!");
3868         return WMError::WM_OK;
3869     }
3870     auto currentProperty = GetSessionProperty();
3871     if (currentProperty != nullptr) {
3872         NotifySessionChangeByActionNotifyManager(property, action);
3873         currentProperty->SetHideNonSystemFloatingWindows(property->GetHideNonSystemFloatingWindows());
3874     }
3875     return WMError::WM_OK;
3876 }
3877 
HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3878 WMError SceneSession::HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty>& property,
3879     WSPropertyChangeAction action)
3880 {
3881     auto sessionProperty = GetSessionProperty();
3882     if (sessionProperty != nullptr) {
3883         sessionProperty->SetTextFieldPositionY(property->GetTextFieldPositionY());
3884         sessionProperty->SetTextFieldHeight(property->GetTextFieldHeight());
3885     }
3886     return WMError::WM_OK;
3887 }
3888 
HandleActionUpdateWindowMask(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3889 WMError SceneSession::HandleActionUpdateWindowMask(const sptr<WindowSessionProperty>& property,
3890     WSPropertyChangeAction action)
3891 {
3892     auto sessionProperty = GetSessionProperty();
3893     if (sessionProperty != nullptr) {
3894         sessionProperty->SetWindowMask(property->GetWindowMask());
3895         sessionProperty->SetIsShaped(property->GetIsShaped());
3896         NotifySessionChangeByActionNotifyManager(property, action);
3897     }
3898     return WMError::WM_OK;
3899 }
3900 
HandleActionUpdateTopmost(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3901 WMError SceneSession::HandleActionUpdateTopmost(const sptr<WindowSessionProperty>& property,
3902     WSPropertyChangeAction action)
3903 {
3904     if (!SessionPermission::IsSystemCalling()) {
3905         TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
3906         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3907     }
3908 
3909     SetTopmost(property->IsTopmost());
3910     return WMError::WM_OK;
3911 }
3912 
HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3913 WMError SceneSession::HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty>& property,
3914     WSPropertyChangeAction action)
3915 {
3916     SetMainWindowTopmost(property->IsMainWindowTopmost());
3917     return WMError::WM_OK;
3918 }
3919 
HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property)3920 void SceneSession::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property)
3921 {
3922     auto systemBarProperties = property->GetSystemBarProperty();
3923     if (auto iter = systemBarProperties.find(type); iter != systemBarProperties.end()) {
3924         SetSystemBarProperty(iter->first, iter->second);
3925         TLOGD(WmsLogTag::WMS_IMMS, "%{public}d, enable: %{public}d",
3926             static_cast<int32_t>(iter->first), iter->second.enable_);
3927     }
3928 }
3929 
SetWindowFlags(const sptr<WindowSessionProperty>& property)3930 void SceneSession::SetWindowFlags(const sptr<WindowSessionProperty>& property)
3931 {
3932     auto sessionProperty = GetSessionProperty();
3933     if (sessionProperty == nullptr) {
3934         TLOGE(WmsLogTag::DEFAULT, "get session property failed");
3935         return;
3936     }
3937     uint32_t flags = property->GetWindowFlags();
3938     uint32_t oldFlags = sessionProperty->GetWindowFlags();
3939     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
3940          (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
3941         !property->GetSystemCalling()) {
3942         TLOGE(WmsLogTag::DEFAULT, "Set window flags permission denied");
3943         return;
3944     }
3945     sessionProperty->SetWindowFlags(flags);
3946     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
3947         OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
3948     }
3949     TLOGI(WmsLogTag::DEFAULT, "flags: %{public}u", flags);
3950 }
3951 
NotifySessionChangeByActionNotifyManager(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)3952 void SceneSession::NotifySessionChangeByActionNotifyManager(const sptr<WindowSessionProperty>& property,
3953     WSPropertyChangeAction action)
3954 {
3955     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, action: %{public}d",
3956         GetPersistentId(), action);
3957     if (sessionChangeByActionNotifyManagerFunc_ == nullptr) {
3958         TLOGW(WmsLogTag::DEFAULT, "func is null");
3959         return;
3960     }
3961     sessionChangeByActionNotifyManagerFunc_(this, property, action);
3962 }
3963 
TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)3964 WSError SceneSession::TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
3965 {
3966     auto task = [weakThis = wptr(this), abilitySessionInfo]() {
3967         auto session = weakThis.promote();
3968         if (!session) {
3969             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
3970             return WSError::WS_ERROR_DESTROYED_OBJECT;
3971         }
3972         if (abilitySessionInfo == nullptr) {
3973             TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
3974             return WSError::WS_ERROR_NULLPTR;
3975         }
3976         if (session->isTerminating_) {
3977             TLOGE(WmsLogTag::WMS_LIFE, "TerminateSession: is terminating, return!");
3978             return WSError::WS_ERROR_INVALID_OPERATION;
3979         }
3980         session->isTerminating_ = true;
3981         SessionInfo info;
3982         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
3983         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
3984         info.callerToken_ = abilitySessionInfo->callerToken;
3985         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
3986         {
3987             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
3988             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
3989             session->sessionInfo_.resultCode = abilitySessionInfo->resultCode;
3990         }
3991         if (session->terminateSessionFunc_) {
3992             session->terminateSessionFunc_(info);
3993         }
3994         return WSError::WS_OK;
3995     };
3996     PostLifeCycleTask(task, "TerminateSession", LifeCycleTaskType::STOP);
3997     return WSError::WS_OK;
3998 }
3999 
NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needRemoveSession, bool isFromClient)4000 WSError SceneSession::NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,
4001     bool needRemoveSession, bool isFromClient)
4002 {
4003     auto task = [weakThis = wptr(this), abilitySessionInfo, needRemoveSession, isFromClient]() {
4004         auto session = weakThis.promote();
4005         if (!session) {
4006             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
4007             return WSError::WS_ERROR_DESTROYED_OBJECT;
4008         }
4009         if (abilitySessionInfo == nullptr) {
4010             TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
4011             return WSError::WS_ERROR_NULLPTR;
4012         }
4013         if (SessionHelper::IsMainWindow(session->GetWindowType()) && isFromClient &&
4014             !session->clientIdentityToken_.empty() &&
4015             session->clientIdentityToken_ != abilitySessionInfo->identityToken) {
4016             TLOGE(WmsLogTag::WMS_LIFE, "client exception not matched: %{public}s, %{public}s",
4017                 session->clientIdentityToken_.c_str(), abilitySessionInfo->identityToken.c_str());
4018             return WSError::WS_ERROR_INVALID_PARAM;
4019         }
4020         if (session->isTerminating_) {
4021             TLOGE(WmsLogTag::WMS_LIFE, "NotifySessionExceptionInner: is terminating, return!");
4022             return WSError::WS_ERROR_INVALID_OPERATION;
4023         }
4024         session->isTerminating_ = true;
4025         SessionInfo info;
4026         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
4027         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
4028         info.callerToken_ = abilitySessionInfo->callerToken;
4029         info.errorCode = abilitySessionInfo->errorCode;
4030         info.errorReason = abilitySessionInfo->errorReason;
4031         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
4032         {
4033             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
4034             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
4035             session->sessionInfo_.errorCode = abilitySessionInfo->errorCode;
4036             session->sessionInfo_.errorReason = abilitySessionInfo->errorReason;
4037         }
4038         if (session->sessionExceptionFunc_) {
4039             auto exceptionFunc = *(session->sessionExceptionFunc_);
4040             exceptionFunc(info, needRemoveSession);
4041         }
4042         if (session->jsSceneSessionExceptionFunc_) {
4043             auto exceptionFunc = *(session->jsSceneSessionExceptionFunc_);
4044             exceptionFunc(info, needRemoveSession);
4045         }
4046         return WSError::WS_OK;
4047     };
4048     PostLifeCycleTask(task, "NotifySessionExceptionInner", LifeCycleTaskType::STOP);
4049     return WSError::WS_OK;
4050 }
4051 
NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needRemoveSession)4052 WSError SceneSession::NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needRemoveSession)
4053 {
4054     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
4055         TLOGE(WmsLogTag::WMS_LIFE, "permission failed.");
4056         return WSError::WS_ERROR_INVALID_PERMISSION;
4057     }
4058     return NotifySessionExceptionInner(abilitySessionInfo, needRemoveSession, true);
4059 }
4060 
GetLastSafeRect() const4061 WSRect SceneSession::GetLastSafeRect() const
4062 {
4063     return lastSafeRect;
4064 }
4065 
SetLastSafeRect(WSRect rect)4066 void SceneSession::SetLastSafeRect(WSRect rect)
4067 {
4068     lastSafeRect.posX_ = rect.posX_;
4069     lastSafeRect.posY_ = rect.posY_;
4070     lastSafeRect.width_ = rect.width_;
4071     lastSafeRect.height_ = rect.height_;
4072     return;
4073 }
4074 
SetMovable(bool movable)4075 void SceneSession::SetMovable(bool movable)
4076 {
4077     auto task = [weakThis = wptr(this), movable] {
4078         auto session = weakThis.promote();
4079         if (!session) {
4080             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
4081             return;
4082         }
4083         if (session->moveDragController_) {
4084             TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, isMovable: %{public}d", session->GetPersistentId(), movable);
4085             session->moveDragController_->SetMovable(movable);
4086         }
4087     };
4088     PostTask(task, "SetMovable");
4089 }
4090 
SetSplitButtonVisible(bool isVisible)4091 WSError SceneSession::SetSplitButtonVisible(bool isVisible)
4092 {
4093     TLOGI(WmsLogTag::WMS_LAYOUT, "isVisible: %{public}d", isVisible);
4094     if (!sessionStage_) {
4095         TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage is null");
4096         return WSError::WS_ERROR_NULLPTR;
4097     }
4098     return sessionStage_->SetSplitButtonVisible(isVisible);
4099 }
4100 
GetOriPosYBeforeRaisedByKeyboard() const4101 int32_t SceneSession::GetOriPosYBeforeRaisedByKeyboard() const
4102 {
4103     return oriPosYBeforeRaisedByKeyboard_;
4104 }
4105 
SetOriPosYBeforeRaisedByKeyboard(int32_t posY)4106 void SceneSession::SetOriPosYBeforeRaisedByKeyboard(int32_t posY)
4107 {
4108     oriPosYBeforeRaisedByKeyboard_ = posY;
4109 }
4110 
AddSubSession(const sptr<SceneSession>& subSession)4111 bool SceneSession::AddSubSession(const sptr<SceneSession>& subSession)
4112 {
4113     if (subSession == nullptr) {
4114         TLOGE(WmsLogTag::WMS_SUB, "subSession is nullptr");
4115         return false;
4116     }
4117     const auto& persistentId = subSession->GetPersistentId();
4118     auto iter = std::find_if(subSession_.begin(), subSession_.end(),
4119         [persistentId](sptr<SceneSession> session) {
4120             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4121             return res;
4122         });
4123     if (iter != subSession_.end()) {
4124         TLOGE(WmsLogTag::WMS_SUB, "Sub ession is already exists, id: %{public}d, parentId: %{public}d",
4125             subSession->GetPersistentId(), GetPersistentId());
4126         return false;
4127     }
4128     TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d",
4129         subSession->GetPersistentId(), GetPersistentId());
4130     subSession_.push_back(subSession);
4131     return true;
4132 }
4133 
RemoveSubSession(int32_t persistentId)4134 bool SceneSession::RemoveSubSession(int32_t persistentId)
4135 {
4136     auto iter = std::find_if(subSession_.begin(), subSession_.end(),
4137         [persistentId](sptr<SceneSession> session) {
4138             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4139             return res;
4140         });
4141     if (iter == subSession_.end()) {
4142         TLOGE(WmsLogTag::WMS_SUB, "Could not find subsession, id: %{public}d, parentId: %{public}d",
4143             persistentId, GetPersistentId());
4144         return false;
4145     }
4146     TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
4147     subSession_.erase(iter);
4148     return true;
4149 }
4150 
AddToastSession(const sptr<SceneSession>& toastSession)4151 bool SceneSession::AddToastSession(const sptr<SceneSession>& toastSession)
4152 {
4153     if (toastSession == nullptr) {
4154         TLOGE(WmsLogTag::WMS_TOAST, "toastSession is nullptr");
4155         return false;
4156     }
4157     const auto& persistentId = toastSession->GetPersistentId();
4158     auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
4159         [persistentId](sptr<SceneSession> session) {
4160             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4161             return res;
4162         });
4163     if (iter != toastSession_.end()) {
4164         TLOGE(WmsLogTag::WMS_TOAST, "Toast ession is already exists, id: %{public}d, parentId: %{public}d",
4165             toastSession->GetPersistentId(), GetPersistentId());
4166         return false;
4167     }
4168     TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d",
4169         toastSession->GetPersistentId(), GetPersistentId());
4170     toastSession_.push_back(toastSession);
4171     return true;
4172 }
4173 
RemoveToastSession(int32_t persistentId)4174 bool SceneSession::RemoveToastSession(int32_t persistentId)
4175 {
4176     auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
4177         [persistentId](sptr<SceneSession> session) {
4178             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4179             return res;
4180         });
4181     if (iter == toastSession_.end()) {
4182         TLOGE(WmsLogTag::WMS_TOAST, "Could not find toastSession, id: %{public}d, parentId: %{public}d",
4183             persistentId, GetPersistentId());
4184         return false;
4185     }
4186     TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
4187     toastSession_.erase(iter);
4188     return true;
4189 }
4190 
NotifyPiPWindowPrepareClose()4191 void SceneSession::NotifyPiPWindowPrepareClose()
4192 {
4193     TLOGD(WmsLogTag::WMS_PIP, "NotifyPiPWindowPrepareClose");
4194     int32_t callingPid = IPCSkeleton::GetCallingPid();
4195     auto task = [weakThis = wptr(this), callingPid]() {
4196         auto session = weakThis.promote();
4197         if (!session) {
4198             TLOGE(WmsLogTag::WMS_PIP, "session is null");
4199             return;
4200         }
4201         if (callingPid != session->GetCallingPid()) {
4202             TLOGW(WmsLogTag::WMS_PIP, "permission denied, not call by the same process");
4203             return;
4204         }
4205         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onPrepareClosePiPSession_) {
4206             session->sessionChangeCallback_->onPrepareClosePiPSession_();
4207         }
4208         TLOGD(WmsLogTag::WMS_PIP, "NotifyPiPWindowPrepareClose, id: %{public}d", session->GetPersistentId());
4209         return;
4210     };
4211     PostTask(task, "NotifyPiPWindowPrepareClose");
4212 }
4213 
SetLandscapeMultiWindow(bool isLandscapeMultiWindow)4214 WSError SceneSession::SetLandscapeMultiWindow(bool isLandscapeMultiWindow)
4215 {
4216     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "NotifySetLandscapeMultiWindow");
4217     int32_t callingPid = IPCSkeleton::GetCallingPid();
4218     auto task = [weakThis = wptr(this), isLandscapeMultiWindow, callingPid]() {
4219         auto session = weakThis.promote();
4220         if (!session) {
4221             TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "session is null");
4222             return WSError::WS_ERROR_DESTROYED_OBJECT;
4223         }
4224         if (callingPid != session->GetCallingPid()) {
4225             TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "premission denied, not call by the same process");
4226             return WSError::WS_ERROR_INVALID_PERMISSION;
4227         }
4228         if (session->sessionChangeCallback_ &&
4229             session->sessionChangeCallback_->onSetLandscapeMultiWindowFunc_) {
4230             session->sessionChangeCallback_->onSetLandscapeMultiWindowFunc_(
4231                 isLandscapeMultiWindow);
4232         }
4233         TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "NotifySetLandscapeMultiWindow, id: %{public}d,"
4234             "isLandscapeMultiWindow: %{public}u", session->GetPersistentId(), isLandscapeMultiWindow);
4235         return WSError::WS_OK;
4236     };
4237     PostTask(task, "NotifySetLandscapeMultiWindow");
4238     return WSError::WS_OK;
4239 }
4240 
GetSubSession() const4241 std::vector<sptr<SceneSession>> SceneSession::GetSubSession() const
4242 {
4243     return subSession_;
4244 }
4245 
GetToastSession() const4246 std::vector<sptr<SceneSession>> SceneSession::GetToastSession() const
4247 {
4248     return toastSession_;
4249 }
4250 
GetSessionTargetRect() const4251 WSRect SceneSession::GetSessionTargetRect() const
4252 {
4253     WSRect rect;
4254     if (moveDragController_) {
4255         rect = moveDragController_->GetTargetRect();
4256     } else {
4257         WLOGFI("moveDragController_ is null");
4258     }
4259     return rect;
4260 }
4261 
SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc& func)4262 void SceneSession::SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc& func)
4263 {
4264     if (moveDragController_) {
4265         moveDragController_->SetWindowDragHotAreaFunc(func);
4266     }
4267 }
4268 
NotifySessionForeground(uint32_t reason, bool withAnimation)4269 void SceneSession::NotifySessionForeground(uint32_t reason, bool withAnimation)
4270 {
4271     if (!sessionStage_) {
4272         return;
4273     }
4274     return sessionStage_->NotifySessionForeground(reason, withAnimation);
4275 }
4276 
NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)4277 void SceneSession::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
4278 {
4279     if (!sessionStage_) {
4280         return;
4281     }
4282     return sessionStage_->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
4283 }
4284 
NotifySessionFullScreen(bool fullScreen)4285 void SceneSession::NotifySessionFullScreen(bool fullScreen)
4286 {
4287     if (!sessionStage_) {
4288         TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage is null");
4289         return;
4290     }
4291     sessionStage_->NotifySessionFullScreen(fullScreen);
4292 }
4293 
UpdatePiPRect(const Rect& rect, SizeChangeReason reason)4294 WSError SceneSession::UpdatePiPRect(const Rect& rect, SizeChangeReason reason)
4295 {
4296     if (!WindowHelper::IsPipWindow(GetWindowType())) {
4297         return WSError::WS_DO_NOTHING;
4298     }
4299     int32_t callingPid = IPCSkeleton::GetCallingPid();
4300     auto task = [weakThis = wptr(this), rect, reason, callingPid]() {
4301         auto session = weakThis.promote();
4302         if (!session || session->isTerminating_) {
4303             TLOGE(WmsLogTag::WMS_PIP, "SceneSession::UpdatePiPRect session is null or is terminating");
4304             return WSError::WS_ERROR_INVALID_OPERATION;
4305         }
4306         if (callingPid != session->GetCallingPid()) {
4307             TLOGW(WmsLogTag::WMS_PIP, "permission denied, not call by the same process");
4308             return WSError::WS_ERROR_INVALID_PERMISSION;
4309         }
4310         WSRect wsRect = SessionHelper::TransferToWSRect(rect);
4311         if (reason == SizeChangeReason::PIP_START) {
4312             session->SetSessionRequestRect(wsRect);
4313         }
4314         TLOGI(WmsLogTag::WMS_PIP, "rect:%{public}s, reason: %{public}u", wsRect.ToString().c_str(),
4315             static_cast<uint32_t>(reason));
4316         session->NotifySessionRectChange(wsRect, reason);
4317         return WSError::WS_OK;
4318     };
4319     if (mainHandler_ != nullptr) {
4320         mainHandler_->PostTask(std::move(task), "wms:UpdatePiPRect", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
4321     } else {
4322         PostTask(task, "UpdatePiPRect");
4323     }
4324     return WSError::WS_OK;
4325 }
4326 
UpdatePiPControlStatus(WsPiPControlType controlType, WsPiPControlStatus status)4327 WSError SceneSession::UpdatePiPControlStatus(WsPiPControlType controlType, WsPiPControlStatus status)
4328 {
4329     TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, status:%{public}d", controlType, status);
4330     if (!WindowHelper::IsPipWindow(GetWindowType())) {
4331         return WSError::WS_DO_NOTHING;
4332     }
4333     int32_t callingPid = IPCSkeleton::GetCallingPid();
4334     auto task = [weakThis = wptr(this), controlType, status, callingPid]() {
4335         auto session = weakThis.promote();
4336         if (!session || session->isTerminating_) {
4337             TLOGE(WmsLogTag::WMS_PIP, "session is null or is terminating");
4338             return WSError::WS_ERROR_INVALID_OPERATION;
4339         }
4340         if (callingPid != session->GetCallingPid()) {
4341             TLOGW(WmsLogTag::WMS_PIP, "permission denied, not call by the same process");
4342             return WSError::WS_ERROR_INVALID_PERMISSION;
4343         }
4344         if (session->sessionPiPControlStatusChangeFunc_) {
4345             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdatePiPControlStatus");
4346             session->sessionPiPControlStatusChangeFunc_(controlType, status);
4347         }
4348         return WSError::WS_OK;
4349     };
4350     PostTask(task, "UpdatePiPControlStatus");
4351     return WSError::WS_OK;
4352 }
4353 
SetAutoStartPiP(bool isAutoStart)4354 WSError SceneSession::SetAutoStartPiP(bool isAutoStart)
4355 {
4356     TLOGI(WmsLogTag::WMS_PIP, "isAutoStart:%{public}u", isAutoStart);
4357     auto task = [weakThis = wptr(this), isAutoStart] {
4358         auto session = weakThis.promote();
4359         if (!session || session->isTerminating_) {
4360             TLOGNE(WmsLogTag::WMS_PIP, "session is null or is terminating");
4361             return;
4362         }
4363         if (session->autoStartPiPStatusChangeFunc_) {
4364             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAutoStartPiP");
4365             session->autoStartPiPStatusChangeFunc_(isAutoStart);
4366         }
4367     };
4368     PostTask(task, __func__);
4369     return WSError::WS_OK;
4370 }
4371 
SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)4372 void SceneSession::SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)
4373 {
4374     std::lock_guard<std::mutex> lock(pointerEventMutex_);
4375     if (systemSessionPointerEventFunc_ != nullptr) {
4376         systemSessionPointerEventFunc_(pointerEvent);
4377     } else {
4378         TLOGE(WmsLogTag::WMS_EVENT, "PointerEventFunc_ nullptr, id:%{public}d", pointerEvent->GetId());
4379         pointerEvent->MarkProcessed();
4380     }
4381 }
4382 
SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent, bool isPreImeEvent)4383 bool SceneSession::SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent, bool isPreImeEvent)
4384 {
4385     std::shared_lock<std::shared_mutex> lock(keyEventMutex_);
4386     if (systemSessionKeyEventFunc_ != nullptr) {
4387         return systemSessionKeyEventFunc_(keyEvent, isPreImeEvent);
4388     }
4389     return false;
4390 }
4391 
UpdateSizeChangeReason(SizeChangeReason reason)4392 WSError SceneSession::UpdateSizeChangeReason(SizeChangeReason reason)
4393 {
4394     auto task = [weakThis = wptr(this), reason]() {
4395         auto session = weakThis.promote();
4396         if (!session) {
4397             WLOGFE("session is null");
4398             return WSError::WS_ERROR_DESTROYED_OBJECT;
4399         }
4400         session->reason_ = reason;
4401         if (reason != SizeChangeReason::UNDEFINED) {
4402             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
4403                 "SceneSession::UpdateSizeChangeReason%d reason:%d",
4404                 session->GetPersistentId(), static_cast<uint32_t>(reason));
4405             TLOGD(WmsLogTag::WMS_LAYOUT, "UpdateSizeChangeReason Id: %{public}d, reason: %{public}d",
4406                 session->GetPersistentId(), reason);
4407         }
4408         return WSError::WS_OK;
4409     };
4410     PostTask(task, "UpdateSizeChangeReason");
4411     return WSError::WS_OK;
4412 }
4413 
IsDirtyWindow()4414 bool SceneSession::IsDirtyWindow()
4415 {
4416     return dirtyFlags_ & static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
4417 }
4418 
NotifyUILostFocus()4419 void SceneSession::NotifyUILostFocus()
4420 {
4421     if (moveDragController_) {
4422         moveDragController_->OnLostFocus();
4423     }
4424     Session::NotifyUILostFocus();
4425 }
4426 
SetScale(float scaleX, float scaleY, float pivotX, float pivotY)4427 void SceneSession::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
4428 {
4429     if (scaleX_ != scaleX || scaleY_ != scaleY || pivotX_ != pivotX || pivotY_ != pivotY) {
4430         Session::SetScale(scaleX, scaleY, pivotX, pivotY);
4431         if (specificCallback_ != nullptr) {
4432             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4433         }
4434         if (sessionStage_ != nullptr) {
4435             Transform transform;
4436             transform.scaleX_ = scaleX;
4437             transform.scaleY_ = scaleY;
4438             transform.pivotX_ = pivotX;
4439             transform.pivotY_ = pivotY;
4440             sessionStage_->NotifyTransformChange(transform);
4441         } else {
4442             WLOGFE("sessionStage_ is nullptr");
4443         }
4444     }
4445 }
4446 
RequestHideKeyboard(bool isAppColdStart)4447 void SceneSession::RequestHideKeyboard(bool isAppColdStart)
4448 {
4449 #ifdef IMF_ENABLE
4450     auto task = [weakThis = wptr(this), isAppColdStart]() {
4451         auto session = weakThis.promote();
4452         if (!session) {
4453             TLOGE(WmsLogTag::WMS_KEYBOARD, "Session is null, notify inputMethod framework hide keyboard failed!");
4454             return;
4455         }
4456         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify inputMethod framework hide keyboard start, id: %{public}d,"
4457             "isAppColdStart: %{public}d", session->GetPersistentId(), isAppColdStart);
4458         if (MiscServices::InputMethodController::GetInstance()) {
4459             MiscServices::InputMethodController::GetInstance()->RequestHideInput();
4460             TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify InputMethod framework hide keyboard end. id: %{public}d",
4461                 session->GetPersistentId());
4462         }
4463     };
4464     PostExportTask(task, "RequestHideKeyboard");
4465 #endif
4466 }
4467 
IsStartMoving() const4468 bool SceneSession::IsStartMoving() const
4469 {
4470     return isStartMoving_.load();
4471 }
4472 
SetIsStartMoving(const bool startMoving)4473 void SceneSession::SetIsStartMoving(const bool startMoving)
4474 {
4475     isStartMoving_.store(startMoving);
4476 }
4477 
SetShouldHideNonSecureWindows(bool shouldHide)4478 void SceneSession::SetShouldHideNonSecureWindows(bool shouldHide)
4479 {
4480     shouldHideNonSecureWindows_.store(shouldHide);
4481 }
4482 
CalculateCombinedExtWindowFlags()4483 void SceneSession::CalculateCombinedExtWindowFlags()
4484 {
4485     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
4486     std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
4487     combinedExtWindowFlags_.bitData = 0;
4488     for (const auto& iter: extWindowFlagsMap_) {
4489         combinedExtWindowFlags_.bitData |= iter.second.bitData;
4490     }
4491 
4492     NotifyPrivacyModeChange();
4493 }
4494 
UpdateExtWindowFlags(int32_t extPersistentId, const ExtensionWindowFlags& extWindowFlags, const ExtensionWindowFlags& extWindowActions)4495 void SceneSession::UpdateExtWindowFlags(int32_t extPersistentId, const ExtensionWindowFlags& extWindowFlags,
4496     const ExtensionWindowFlags& extWindowActions)
4497 {
4498     auto iter = extWindowFlagsMap_.find(extPersistentId);
4499     // Each flag is false when inactive, 0 means all flags are inactive
4500     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
4501     ExtensionWindowFlags newFlags((extWindowFlags.bitData & extWindowActions.bitData) |
4502         (oldFlags.bitData & ~extWindowActions.bitData));
4503     if (newFlags.bitData == 0) {
4504         extWindowFlagsMap_.erase(extPersistentId);
4505     } else {
4506         extWindowFlagsMap_[extPersistentId] = newFlags;
4507     }
4508     CalculateCombinedExtWindowFlags();
4509 }
4510 
GetCombinedExtWindowFlags()4511 ExtensionWindowFlags SceneSession::GetCombinedExtWindowFlags()
4512 {
4513     std::shared_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
4514     auto combinedExtWindowFlags = combinedExtWindowFlags_;
4515     combinedExtWindowFlags.hideNonSecureWindowsFlag = IsSessionForeground() &&
4516         (combinedExtWindowFlags.hideNonSecureWindowsFlag || shouldHideNonSecureWindows_.load());
4517     return combinedExtWindowFlags;
4518 }
4519 
NotifyDisplayMove(DisplayId from, DisplayId to)4520 void SceneSession::NotifyDisplayMove(DisplayId from, DisplayId to)
4521 {
4522     if (sessionStage_) {
4523         sessionStage_->NotifyDisplayMove(from, to);
4524     } else {
4525         WLOGFE("Notify display move failed, sessionStage is null");
4526     }
4527 }
4528 
RemoveExtWindowFlags(int32_t extPersistentId)4529 void SceneSession::RemoveExtWindowFlags(int32_t extPersistentId)
4530 {
4531     extWindowFlagsMap_.erase(extPersistentId);
4532     CalculateCombinedExtWindowFlags();
4533 }
4534 
ClearExtWindowFlags()4535 void SceneSession::ClearExtWindowFlags()
4536 {
4537     std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
4538     extWindowFlagsMap_.clear();
4539     combinedExtWindowFlags_.bitData = 0;
4540 }
4541 
UpdateRectChangeListenerRegistered(bool isRegister)4542 WSError SceneSession::UpdateRectChangeListenerRegistered(bool isRegister)
4543 {
4544     auto task = [weakThis = wptr(this), isRegister]() {
4545         auto session = weakThis.promote();
4546         if (!session) {
4547             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
4548             return WSError::WS_ERROR_DESTROYED_OBJECT;
4549         }
4550         session->rectChangeListenerRegistered_ = isRegister;
4551         return WSError::WS_OK;
4552     };
4553     PostTask(task, "UpdateRectChangeListenerRegistered");
4554     return WSError::WS_OK;
4555 }
4556 
OnLayoutFullScreenChange(bool isLayoutFullScreen)4557 WSError SceneSession::OnLayoutFullScreenChange(bool isLayoutFullScreen)
4558 {
4559     auto task = [weakThis = wptr(this), isLayoutFullScreen]() {
4560         auto session = weakThis.promote();
4561         if (!session) {
4562             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
4563             return WSError::WS_ERROR_DESTROYED_OBJECT;
4564         }
4565         TLOGI(WmsLogTag::WMS_LAYOUT, "OnLayoutFullScreenChange, isLayoutFullScreen: %{public}d",
4566             isLayoutFullScreen);
4567         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onLayoutFullScreenChangeFunc_) {
4568             session->sessionChangeCallback_->onLayoutFullScreenChangeFunc_(isLayoutFullScreen);
4569         }
4570         return WSError::WS_OK;
4571     };
4572     PostTask(task, "OnLayoutFullScreenChange");
4573     return WSError::WS_OK;
4574 }
4575 
OnTitleAndDockHoverShowChange(bool isTitleHoverShown, bool isDockHoverShown)4576 WSError SceneSession::OnTitleAndDockHoverShowChange(bool isTitleHoverShown, bool isDockHoverShown)
4577 {
4578     const char* const funcName = __func__;
4579     auto task = [weakThis = wptr(this), isTitleHoverShown, isDockHoverShown, funcName]() {
4580         auto session = weakThis.promote();
4581         if (!session) {
4582             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", funcName);
4583             return WSError::WS_ERROR_DESTROYED_OBJECT;
4584         }
4585         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s isTitleHoverShown: %{public}d, isDockHoverShown: %{public}d", funcName,
4586             isTitleHoverShown, isDockHoverShown);
4587         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onTitleAndDockHoverShowChangeFunc_) {
4588             session->sessionChangeCallback_->onTitleAndDockHoverShowChangeFunc_(
4589                 isTitleHoverShown, isDockHoverShown);
4590         }
4591         return WSError::WS_OK;
4592     };
4593     PostTask(task, "OnTitleAndDockHoverShowChange");
4594     return WSError::WS_OK;
4595 }
4596 
SetForceHideState(ForceHideState forceHideState)4597 void SceneSession::SetForceHideState(ForceHideState forceHideState)
4598 {
4599     forceHideState_ = forceHideState;
4600 }
4601 
GetForceHideState() const4602 ForceHideState SceneSession::GetForceHideState() const
4603 {
4604     return forceHideState_;
4605 }
4606 
SetIsDisplayStatusBarTemporarily(bool isTemporary)4607 void SceneSession::SetIsDisplayStatusBarTemporarily(bool isTemporary)
4608 {
4609     isDisplayStatusBarTemporarily_.store(isTemporary);
4610 }
4611 
GetIsDisplayStatusBarTemporarily() const4612 bool SceneSession::GetIsDisplayStatusBarTemporarily() const
4613 {
4614     return isDisplayStatusBarTemporarily_.load();
4615 }
4616 
SetStartingWindowExitAnimationFlag(bool enable)4617 void SceneSession::SetStartingWindowExitAnimationFlag(bool enable)
4618 {
4619     TLOGI(WmsLogTag::DEFAULT, "SetStartingWindowExitAnimationFlag %{public}d", enable);
4620     needStartingWindowExitAnimation_.store(enable);
4621 }
4622 
NeedStartingWindowExitAnimation() const4623 bool SceneSession::NeedStartingWindowExitAnimation() const
4624 {
4625     return needStartingWindowExitAnimation_.load();
4626 }
4627 
IsSystemSpecificSession() const4628 bool SceneSession::IsSystemSpecificSession() const
4629 {
4630     return isSystemSpecificSession_;
4631 }
4632 
SetIsSystemSpecificSession(bool isSystemSpecificSession)4633 void SceneSession::SetIsSystemSpecificSession(bool isSystemSpecificSession)
4634 {
4635     isSystemSpecificSession_ = isSystemSpecificSession;
4636 }
4637 
SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)4638 void SceneSession::SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)
4639 {
4640     if (isTemporarilyShowWhenLocked_.load() == isTemporarilyShowWhenLocked) {
4641         return;
4642     }
4643     isTemporarilyShowWhenLocked_.store(isTemporarilyShowWhenLocked);
4644     TLOGI(WmsLogTag::WMS_SCB, "SetTemporarilyShowWhenLocked successfully, target:%{public}u",
4645         isTemporarilyShowWhenLocked);
4646 }
4647 
IsTemporarilyShowWhenLocked() const4648 bool SceneSession::IsTemporarilyShowWhenLocked() const
4649 {
4650     return isTemporarilyShowWhenLocked_.load();
4651 }
4652 
SetSkipDraw(bool skip)4653 void SceneSession::SetSkipDraw(bool skip)
4654 {
4655     if (!surfaceNode_) {
4656         WLOGFE("surfaceNode_ is null");
4657         return;
4658     }
4659     surfaceNode_->SetSkipDraw(skip);
4660     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4661     if (leashWinSurfaceNode != nullptr) {
4662         leashWinSurfaceNode->SetSkipDraw(skip);
4663     }
4664     RSTransaction::FlushImplicitTransaction();
4665 }
4666 
SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)4667 void SceneSession::SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)
4668 {
4669     TLOGW(WmsLogTag::WMS_SCB, "in sceneSession, do nothing");
4670     return;
4671 }
4672 
SetUniqueDensityDpi(bool useUnique, float dpi)4673 WMError SceneSession::SetUniqueDensityDpi(bool useUnique, float dpi)
4674 {
4675     TLOGI(WmsLogTag::DEFAULT, "SceneSession set unique dpi: id = %{public}d, dpi = %{public}f",
4676         GetPersistentId(), dpi);
4677     if (useUnique && (dpi > DOT_PER_INCH_MAXIMUM_VALUE || dpi < DOT_PER_INCH_MINIMUM_VALUE)) {
4678         TLOGE(WmsLogTag::DEFAULT, "Invalid input dpi value, valid input range for DPI is %{public}u ~ %{public}u",
4679             DOT_PER_INCH_MINIMUM_VALUE, DOT_PER_INCH_MAXIMUM_VALUE);
4680         return WMError::WM_ERROR_INVALID_PARAM;
4681     }
4682     float density = static_cast<float>(dpi) / 160; // 160 is the coefficient between density and dpi;
4683     if (!IsSessionValid()) {
4684         return WMError::WM_ERROR_INVALID_SESSION;
4685     }
4686     if (!sessionStage_) {
4687         TLOGE(WmsLogTag::DEFAULT, "sessionStage_ is nullptr");
4688         return WMError::WM_ERROR_NULLPTR;
4689     }
4690     sessionStage_->SetUniqueVirtualPixelRatio(useUnique, density);
4691     return WMError::WM_OK;
4692 }
4693 
SetSystemWindowEnableDrag(bool enableDrag)4694 WMError SceneSession::SetSystemWindowEnableDrag(bool enableDrag)
4695 {
4696     TLOGI(WmsLogTag::WMS_LAYOUT, "enableDrag : %{public}d", enableDrag);
4697     if (!SessionPermission::IsSystemCalling()) {
4698         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
4699         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4700     }
4701 
4702     if (!WindowHelper::IsSystemWindow(GetWindowType())) {
4703         TLOGE(WmsLogTag::WMS_LAYOUT, "is not allow since this is not system window");
4704         return WMError::WM_ERROR_INVALID_CALLING;
4705     }
4706 
4707     auto task = [weakThis = wptr(this), enableDrag]() {
4708         auto session = weakThis.promote();
4709         if (!session) {
4710             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
4711             return;
4712         }
4713         auto sessionProperty = session->GetSessionProperty();
4714 
4715         TLOGI(WmsLogTag::WMS_LAYOUT, "task id: %{public}d, enableDrag: %{public}d",
4716             session->GetPersistentId(), enableDrag);
4717         if (!sessionProperty) {
4718             TLOGE(WmsLogTag::WMS_LAYOUT, "sessionProperty is null");
4719             return;
4720         }
4721         sessionProperty->SetDragEnabled(enableDrag);
4722     };
4723     PostTask(task, "SetSystemWindowEnableDrag");
4724     return WMError::WM_OK;
4725 }
4726 
HandleActionUpdateModeSupportInfo(const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)4727 WMError SceneSession::HandleActionUpdateModeSupportInfo(const sptr<WindowSessionProperty>& property,
4728     WSPropertyChangeAction action)
4729 {
4730     if (!property->GetSystemCalling()) {
4731         TLOGE(WmsLogTag::DEFAULT, "Update property modeSupportInfo permission denied!");
4732         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4733     }
4734 
4735     auto sessionProperty = GetSessionProperty();
4736     if (sessionProperty != nullptr) {
4737         sessionProperty->SetModeSupportInfo(property->GetModeSupportInfo());
4738     }
4739     return WMError::WM_OK;
4740 }
4741 
RegisterForceSplitListener(const NotifyForceSplitFunc& func)4742 void SceneSession::RegisterForceSplitListener(const NotifyForceSplitFunc& func)
4743 {
4744     forceSplitFunc_ = func;
4745 }
4746 
GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)4747 WMError SceneSession::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
4748 {
4749     if (forceSplitFunc_ == nullptr) {
4750         return WMError::WM_ERROR_NULLPTR;
4751     }
4752     config = forceSplitFunc_(sessionInfo_.bundleName_);
4753     return WMError::WM_OK;
4754 }
4755 
SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc& func)4756 void SceneSession::SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc& func)
4757 {
4758     updatePrivateStateAndNotifyFunc_ = func;
4759 }
4760 
SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc& func)4761 void SceneSession::SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc& func)
4762 {
4763     notifyVisibleChangeFunc_ = func;
4764 }
4765 
SetPrivacyModeChangeNotifyFunc(const NotifyPrivacyModeChangeFunc& func)4766 void SceneSession::SetPrivacyModeChangeNotifyFunc(const NotifyPrivacyModeChangeFunc& func)
4767 {
4768     privacyModeChangeNotifyFunc_ = func;
4769 }
4770 
GetStatusBarHeight()4771 int32_t SceneSession::GetStatusBarHeight()
4772 {
4773     int32_t height = 0;
4774     if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByType_ == nullptr ||
4775         GetSessionProperty() == nullptr) {
4776         TLOGE(WmsLogTag::WMS_IMMS, "specificCallback_ or session property is null");
4777         return height;
4778     }
4779     std::vector<sptr<SceneSession>> statusBarVector = specificCallback_->onGetSceneSessionVectorByType_(
4780         WindowType::WINDOW_TYPE_STATUS_BAR, GetSessionProperty()->GetDisplayId());
4781     for (auto& statusBar : statusBarVector) {
4782         if (statusBar != nullptr && statusBar->GetSessionRect().height_ > height) {
4783             height = statusBar->GetSessionRect().height_;
4784         }
4785     }
4786     TLOGD(WmsLogTag::WMS_IMMS, "StatusBarVectorHeight is %{public}d", height);
4787     return height;
4788 }
4789 
CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty>& property) const4790 bool SceneSession::CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty>& property) const
4791 {
4792     if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
4793         if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4794             TLOGE(WmsLogTag::WMS_LIFE, "Not system app, no permission");
4795             return false;
4796         }
4797     }
4798     return true;
4799 }
4800 
PcUpdateZOrderAndDirty(const uint32_t zOrder)4801 void SceneSession::PcUpdateZOrderAndDirty(const uint32_t zOrder)
4802 {
4803     dirtyFlags_ |= UpdateZOrderInner(zOrder) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
4804 }
4805 
UpdateUIParam(const SessionUIParam& uiParam)4806 uint32_t SceneSession::UpdateUIParam(const SessionUIParam& uiParam)
4807 {
4808     bool lastVisible = IsVisible();
4809     dirtyFlags_ |= UpdateInteractiveInner(uiParam.interactive_) ?
4810         static_cast<uint32_t>(SessionUIDirtyFlag::INTERACTIVE) : 0;
4811     if (!uiParam.interactive_) {
4812         // keep ui state in recent
4813         return dirtyFlags_;
4814     }
4815     dirtyFlags_ |= UpdateVisibilityInner(true) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
4816     dirtyFlags_ |= UpdateRectInner(uiParam, reason_) ?
4817         static_cast<uint32_t>(SessionUIDirtyFlag::RECT) : 0;
4818     dirtyFlags_ |= UpdateScaleInner(uiParam.scaleX_, uiParam.scaleY_, uiParam.pivotX_, uiParam.pivotY_) ?
4819         static_cast<uint32_t>(SessionUIDirtyFlag::SCALE) : 0;
4820     if (!isPcScenePanel_) {
4821         dirtyFlags_ |= UpdateZOrderInner(uiParam.zOrder_) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
4822     }
4823     if (!lastVisible && IsVisible() && !isFocused_ && !postProcessFocusState_.enabled_ &&
4824         GetForegroundInteractiveStatus()) {
4825         postProcessFocusState_.enabled_ = true;
4826         postProcessFocusState_.isFocused_ = true;
4827         postProcessFocusState_.reason_ = isStarting_ ?
4828             FocusChangeReason::SCB_START_APP : FocusChangeReason::FOREGROUND;
4829     }
4830     return dirtyFlags_;
4831 }
4832 
UpdateUIParam()4833 uint32_t SceneSession::UpdateUIParam()
4834 {
4835     bool lastVisible = IsVisible();
4836     dirtyFlags_ |= UpdateVisibilityInner(false) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
4837     if (lastVisible && !IsVisible() && isFocused_) {
4838         postProcessFocusState_.enabled_ = true;
4839         postProcessFocusState_.isFocused_ = false;
4840         postProcessFocusState_.reason_ = FocusChangeReason::BACKGROUND;
4841     }
4842     return dirtyFlags_;
4843 }
4844 
UpdateVisibilityInner(bool visibility)4845 bool SceneSession::UpdateVisibilityInner(bool visibility)
4846 {
4847     if (isVisible_ == visibility) {
4848         return false;
4849     }
4850     TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, visibility: %{public}u -> %{public}u",
4851         GetPersistentId(), isVisible_, visibility);
4852     if (visibilityChangedDetectFunc_) {
4853         visibilityChangedDetectFunc_(GetCallingPid(), isVisible_, visibility);
4854     }
4855     isVisible_ = visibility;
4856     if (updatePrivateStateAndNotifyFunc_ != nullptr) {
4857         updatePrivateStateAndNotifyFunc_(GetPersistentId());
4858     }
4859     if (notifyVisibleChangeFunc_ != nullptr) {
4860         notifyVisibleChangeFunc_(GetPersistentId());
4861     }
4862     return true;
4863 }
4864 
UpdateInteractiveInner(bool interactive)4865 bool SceneSession::UpdateInteractiveInner(bool interactive)
4866 {
4867     if (GetForegroundInteractiveStatus() == interactive) {
4868         return false;
4869     }
4870     SetForegroundInteractiveStatus(interactive);
4871     NotifyClientToUpdateInteractive(interactive);
4872     return true;
4873 }
4874 
PipelineNeedNotifyClientToUpdateRect() const4875 bool SceneSession::PipelineNeedNotifyClientToUpdateRect() const
4876 {
4877     return IsVisibleForeground() && GetForegroundInteractiveStatus();
4878 }
4879 
UpdateRectInner(const SessionUIParam& uiParam, SizeChangeReason reason)4880 bool SceneSession::UpdateRectInner(const SessionUIParam& uiParam, SizeChangeReason reason)
4881 {
4882     if (!((NotifyServerToUpdateRect(uiParam, reason) || IsDirtyWindow()) && PipelineNeedNotifyClientToUpdateRect())) {
4883         return false;
4884     }
4885     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
4886     auto transactionController = RSSyncTransactionController::GetInstance();
4887     if (transactionController) {
4888         rsTransaction = transactionController->GetRSTransaction();
4889     }
4890     NotifyClientToUpdateRect("WMSPipeline", rsTransaction);
4891     return true;
4892 }
4893 
NotifyServerToUpdateRect(const SessionUIParam& uiParam, SizeChangeReason reason)4894 bool SceneSession::NotifyServerToUpdateRect(const SessionUIParam& uiParam, SizeChangeReason reason)
4895 {
4896     if (!GetForegroundInteractiveStatus()) {
4897         TLOGD(WmsLogTag::WMS_PIPELINE, "skip recent, id:%{public}d", GetPersistentId());
4898         return false;
4899     }
4900     if (uiParam.rect_.IsInvalid()) {
4901         TLOGW(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid",
4902             GetPersistentId(), uiParam.rect_.ToString().c_str());
4903         return false;
4904     }
4905     SetSessionGlobalRect(uiParam.rect_);
4906     if (!uiParam.needSync_) {
4907         TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, updateRect not sync rectAfter:%{public}s preRect:%{public}s",
4908             GetPersistentId(), uiParam.rect_.ToString().c_str(), winRect_.ToString().c_str());
4909         return false;
4910     }
4911     WSRect rect = { uiParam.rect_.posX_ - uiParam.transX_, uiParam.rect_.posY_ - uiParam.transY_,
4912         uiParam.rect_.width_, uiParam.rect_.height_ };
4913     if (winRect_ == rect) {
4914         TLOGD(WmsLogTag::WMS_PIPELINE, "skip same rect update id:%{public}d rect:%{public}s!",
4915             GetPersistentId(), rect.ToString().c_str());
4916         return false;
4917     }
4918     if (rect.IsInvalid()) {
4919         TLOGE(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid",
4920             GetPersistentId(), rect.ToString().c_str());
4921         return false;
4922     }
4923     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, updateRect rectAfter:%{public}s preRect:%{public}s",
4924         GetPersistentId(), rect.ToString().c_str(), winRect_.ToString().c_str());
4925     winRect_ = rect;
4926     RectCheckProcess();
4927     return true;
4928 }
4929 
PostProcessNotifyAvoidArea()4930 void SceneSession::PostProcessNotifyAvoidArea()
4931 {
4932     if (PipelineNeedNotifyClientToUpdateAvoidArea(dirtyFlags_)) {
4933         NotifyClientToUpdateAvoidArea();
4934     }
4935 }
4936 
PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const4937 bool SceneSession::PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const
4938 {
4939     return ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE)) && IsImmersiveType()) ||
4940         ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) && isVisible_);
4941 }
4942 
NotifyClientToUpdateAvoidArea()4943 void SceneSession::NotifyClientToUpdateAvoidArea()
4944 {
4945     if (specificCallback_ == nullptr) {
4946         return;
4947     }
4948     if (specificCallback_->onUpdateAvoidArea_) {
4949         specificCallback_->onUpdateAvoidArea_(GetPersistentId());
4950     }
4951     if (specificCallback_->onUpdateOccupiedAreaIfNeed_) {
4952         specificCallback_->onUpdateOccupiedAreaIfNeed_(GetPersistentId());
4953     }
4954 }
4955 
UpdateScaleInner(float scaleX, float scaleY, float pivotX, float pivotY)4956 bool SceneSession::UpdateScaleInner(float scaleX, float scaleY, float pivotX, float pivotY)
4957 {
4958     if (NearEqual(scaleX_, scaleX) && NearEqual(scaleY_, scaleY) &&
4959         NearEqual(pivotX_, pivotX) && NearEqual(pivotY_, pivotY)) {
4960         return false;
4961     }
4962     Session::SetScale(scaleX, scaleY, pivotX, pivotY);
4963     if (sessionStage_ != nullptr) {
4964         Transform transform;
4965         transform.scaleX_ = scaleX;
4966         transform.scaleY_ = scaleY;
4967         transform.pivotX_ = pivotX;
4968         transform.pivotY_ = pivotY;
4969         sessionStage_->NotifyTransformChange(transform);
4970     } else {
4971         WLOGFE("sessionStage is nullptr");
4972     }
4973     return true;
4974 }
4975 
UpdateZOrderInner(uint32_t zOrder)4976 bool SceneSession::UpdateZOrderInner(uint32_t zOrder)
4977 {
4978     if (zOrder_ == zOrder) {
4979         return false;
4980     }
4981     TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}u -> %{public}u, lastZOrder: %{public}u",
4982           GetPersistentId(), zOrder_, zOrder, lastZOrder_);
4983     lastZOrder_ = zOrder_;
4984     zOrder_ = zOrder;
4985     return true;
4986 }
4987 
SetPostProcessFocusState(PostProcessFocusState state)4988 void SceneSession::SetPostProcessFocusState(PostProcessFocusState state)
4989 {
4990     postProcessFocusState_ = state;
4991 }
4992 
GetPostProcessFocusState() const4993 PostProcessFocusState SceneSession::GetPostProcessFocusState() const
4994 {
4995     return postProcessFocusState_;
4996 }
4997 
ResetPostProcessFocusState()4998 void SceneSession::ResetPostProcessFocusState()
4999 {
5000     postProcessFocusState_.Reset();
5001 }
5002 
SetPostProcessProperty(bool state)5003 void SceneSession::SetPostProcessProperty(bool state)
5004 {
5005     postProcessProperty_ = state;
5006 }
5007 
GetPostProcessProperty() const5008 bool SceneSession::GetPostProcessProperty() const
5009 {
5010     return postProcessProperty_;
5011 }
5012 
IsImmersiveType() const5013 bool SceneSession::IsImmersiveType() const
5014 {
5015     WindowType type = GetWindowType();
5016     return type == WindowType::WINDOW_TYPE_STATUS_BAR ||
5017         type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
5018         type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
5019 }
5020 
IsPcOrPadEnableActivation() const5021 bool SceneSession::IsPcOrPadEnableActivation() const
5022 {
5023     auto property = GetSessionProperty();
5024     bool isPcAppInPad = false;
5025     if (property != nullptr) {
5026         isPcAppInPad = property->GetIsPcAppInPad();
5027     }
5028     return systemConfig_.IsPcWindow() || IsFreeMultiWindowMode() || isPcAppInPad;
5029 }
5030 
SetMinimizedFlagByUserSwitch(bool isMinimized)5031 void SceneSession::SetMinimizedFlagByUserSwitch(bool isMinimized)
5032 {
5033     TLOGI(WmsLogTag::WMS_MULTI_USER, "winId: %{public}d, isMinimized: %{public}d", GetPersistentId(), isMinimized);
5034     isMinimizedByUserSwitch_ = isMinimized;
5035 }
5036 
IsMinimizedByUserSwitch() const5037 bool SceneSession::IsMinimizedByUserSwitch() const
5038 {
5039     return isMinimizedByUserSwitch_;
5040 }
5041 
UnregisterSessionChangeListeners()5042 void SceneSession::UnregisterSessionChangeListeners()
5043 {
5044     auto task = [weakThis = wptr(this)] {
5045         auto session = weakThis.promote();
5046         if (session == nullptr) {
5047             WLOGFE("UnregisterSessionChangeListeners session is null");
5048             return;
5049         }
5050         if (session->sessionChangeCallback_) {
5051             session->sessionChangeCallback_->onBindDialogTarget_ = nullptr;
5052             session->sessionChangeCallback_->onSessionTopmostChange_ = nullptr;
5053             session->sessionChangeCallback_->onSessionModalTypeChange_ = nullptr;
5054             session->sessionChangeCallback_->onRaiseToTop_ = nullptr;
5055             session->sessionChangeCallback_->OnSessionEvent_ = nullptr;
5056             session->sessionChangeCallback_->OnNeedAvoid_ = nullptr;
5057             session->sessionChangeCallback_->onIsCustomAnimationPlaying_ = nullptr;
5058             session->sessionChangeCallback_->onWindowAnimationFlagChange_ = nullptr;
5059             session->sessionChangeCallback_->OnShowWhenLocked_ = nullptr;
5060             session->sessionChangeCallback_->OnRequestedOrientationChange_ = nullptr;
5061             session->sessionChangeCallback_->onRaiseAboveTarget_ = nullptr;
5062             session->sessionChangeCallback_->OnForceHideChange_ = nullptr;
5063             session->sessionChangeCallback_->OnTouchOutside_ = nullptr;
5064             session->sessionChangeCallback_->clearCallbackFunc_ = nullptr;
5065             session->sessionChangeCallback_->onPrepareClosePiPSession_ = nullptr;
5066             session->sessionChangeCallback_->onSetLandscapeMultiWindowFunc_ = nullptr;
5067             session->sessionChangeCallback_->onLayoutFullScreenChangeFunc_ = nullptr;
5068             session->sessionChangeCallback_->onRestoreMainWindowFunc_ = nullptr;
5069         }
5070         session->Session::UnregisterSessionChangeListeners();
5071     };
5072     PostTask(task, "UnregisterSessionChangeListeners");
5073 }
5074 
SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func)5075 void SceneSession::SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func)
5076 {
5077     visibilityChangedDetectFunc_ = func;
5078 }
5079 
SetDefaultDisplayIdIfNeed()5080 void SceneSession::SetDefaultDisplayIdIfNeed()
5081 {
5082     if (sessionInfo_.screenId_ == SCREEN_ID_INVALID) {
5083         auto defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5084         sessionInfo_.screenId_ = defaultDisplayId;
5085         TLOGI(WmsLogTag::WMS_LIFE, "winId: %{public}d, update screen id %{public}" PRIu64,
5086             GetPersistentId(), defaultDisplayId);
5087         auto sessionProperty = GetSessionProperty();
5088         if (sessionProperty) {
5089             sessionProperty->SetDisplayId(defaultDisplayId);
5090         }
5091     }
5092 }
5093 
GetCustomDecorHeight() const5094 int32_t SceneSession::GetCustomDecorHeight() const
5095 {
5096     std::lock_guard lock(customDecorHeightMutex_);
5097     return customDecorHeight_;
5098 }
5099 
SetCustomDecorHeight(int32_t height)5100 void SceneSession::SetCustomDecorHeight(int32_t height)
5101 {
5102     constexpr int32_t MIN_DECOR_HEIGHT = 37;
5103     constexpr int32_t MAX_DECOR_HEIGHT = 112;
5104     if (height < MIN_DECOR_HEIGHT || height > MAX_DECOR_HEIGHT) {
5105         return;
5106     }
5107     std::lock_guard lock(customDecorHeightMutex_);
5108     customDecorHeight_ = height;
5109 }
5110 
UpdateGestureBackEnabled()5111 void SceneSession::UpdateGestureBackEnabled()
5112 {
5113     if (specificCallback_ != nullptr &&
5114         specificCallback_->onUpdateGestureBackEnabled_ != nullptr) {
5115         specificCallback_->onUpdateGestureBackEnabled_(GetPersistentId());
5116     }
5117 }
5118 
CheckIdentityTokenIfMatched(const std::string& identityToken)5119 bool SceneSession::CheckIdentityTokenIfMatched(const std::string& identityToken)
5120 {
5121     if (!identityToken.empty() && !clientIdentityToken_.empty() && identityToken != clientIdentityToken_) {
5122         TLOGW(WmsLogTag::WMS_LIFE,
5123             "failed, clientIdentityToken: %{public}s, identityToken: %{public}s, bundleName: %{public}s",
5124             clientIdentityToken_.c_str(), identityToken.c_str(), GetSessionInfo().bundleName_.c_str());
5125         return false;
5126     }
5127     return true;
5128 }
5129 
CheckPidIfMatched()5130 bool SceneSession::CheckPidIfMatched()
5131 {
5132     int32_t callingPid = IPCSkeleton::GetCallingPid();
5133     if (callingPid != -1 && callingPid != GetCallingPid()) {
5134         TLOGW(WmsLogTag::WMS_LIFE,
5135             "failed, callingPid_: %{public}d, callingPid: %{public}d, bundleName: %{public}s",
5136             GetCallingPid(), callingPid, GetSessionInfo().bundleName_.c_str());
5137         return false;
5138     }
5139     return true;
5140 }
5141 } // namespace OHOS::Rosen
5142