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