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