diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index 13bd19ce1d67eb445e8b9e6e1ef3f0004d96bec0..134cfbe8c177b460e019e0c48a9bdf4634f5765c 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -844,9 +844,12 @@ private: const sptr& sceneSession, FocusChangeReason reason); bool IsParentSessionVisible(const sptr& session); sptr GetNextFocusableSession(DisplayId displayId, int32_t persistentId); + sptr GetTopFloatingSession(DisplayId displayGroupId, int32_t persistentId); + sptr GetNextFocusableSessionWhenFloatWindowExist(DisplayId displayGroupId, int32_t persistentId); sptr GetTopNearestBlockingFocusSession(DisplayId displayId, uint32_t zOrder, bool includingAppSession); sptr GetTopFocusableNonAppSession(); + bool CheckBlockingFocus(const sptr& session, bool includingAppSession); WSError ShiftFocus(DisplayId displayId, const sptr& nextSession, bool isProactiveUnfocus, FocusChangeReason reason = FocusChangeReason::DEFAULT); void UpdateFocusStatus(DisplayId displayId, const sptr& sceneSession, bool isFocused); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index bdc16037bd84dbb72897ce374156b3e1f731c40a..0ae8b733221956b5e311026b54fccffa14a0056f 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -6785,9 +6785,11 @@ bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(const sptrGetZOrder(); - TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\ - topNearestBlockingZOrder: %{public}d", requestSessionZOrder, focusedSessionZOrder, - topNearestBlockingZOrder); + TLOGI(WmsLogTag::WMS_FOCUS, + "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\ + topNearestBlockingZOrder: %{public}d, topNearestBlockingId: %{public}d", + requestSessionZOrder, focusedSessionZOrder, + topNearestBlockingZOrder, topNearestBlockingFocusSession->GetPersistentId()); } if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) { TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted"); @@ -6928,9 +6930,9 @@ sptr SceneSessionManager::GetNextFocusableSession(DisplayId displa { TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId); bool previousFocusedSessionFound = false; - sptr ret = nullptr; DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId); - auto func = [this, persistentId, &previousFocusedSessionFound, &ret, displayGroupId](sptr session) { + sptr nextFocusableSession = nullptr; + auto func = [this, persistentId, &previousFocusedSessionFound, &nextFocusableSession, displayGroupId](sptr session) { if (session == nullptr) { return false; } @@ -6944,7 +6946,7 @@ sptr SceneSessionManager::GetNextFocusableSession(DisplayId displa } if (previousFocusedSessionFound && session->CheckFocusable() && session->IsVisible() && IsParentSessionVisible(session)) { - ret = session; + nextFocusableSession = session; return true; } if (session->GetPersistentId() == persistentId) { @@ -6953,7 +6955,67 @@ sptr SceneSessionManager::GetNextFocusableSession(DisplayId displa return false; }; TraverseSessionTree(func, true); - return ret; + sptr topFloatingSession = GetNextFocusableSessionWhenFloatWindowExist(displayGroupId, persistentId); + if (topFloatingSession != nullptr && nextFocusableSession != nullptr && nextFocusableSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) { + TLOGI(WmsLogTag::WMS_FOCUS, "topFloatingSessionId: %{public}d", topFloatingSession->GetPersistentId()); + return topFloatingSession; + } + return nextFocusableSession; +} + +sptr SceneSessionManager::GetNextFocusableSessionWhenFloatWindowExist(DisplayId displayGroupId, + int32_t persistentId) +{ + bool isPhoneOrPad = + systemConfig_.IsPhoneWindow() || (systemConfig_.IsPadWindow() && !systemConfig_.IsFreeMultiWindowMode()); + if (!isPhoneOrPad) { + return nullptr; + } + auto topFloatingSession = GetTopFloatingSession(displayGroupId, persistentId); + auto sceneSession = GetSceneSession(persistentId); + if (topFloatingSession != nullptr && SessionHelper::IsMainWindow(sceneSession->GetWindowType()) && + sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) { + return topFloatingSession; + } + return nullptr; +} + +sptr SceneSessionManager::GetTopFloatingSession(DisplayId displayGroupId, int32_t persistentId) +{ + bool previousFocusedSessionFound = false; + sptr topFloatingSession = nullptr; + auto func = [this, persistentId, &previousFocusedSessionFound, &topFloatingSession, displayGroupId](sptr session) { + if (session == nullptr || topFloatingSession != nullptr || previousFocusedSessionFound) { + return false; + } + if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) != + displayGroupId) { + return false; + } + if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) { + TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId); + return false; + } + // need to be floating window + if (session->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) { + return false; + } + // need to be main window + if (!SessionHelper::IsMainWindow(session->GetWindowType())) { + return false; + } + + if (session->CheckFocusable() && session->IsVisible()) { + topFloatingSession = session; + return true; + } + if (session->GetPersistentId() == persistentId) { + previousFocusedSessionFound = true; + } + return false; + }; + TraverseSessionTree(func, true); + return topFloatingSession; } /** @@ -6983,19 +7045,12 @@ sptr SceneSessionManager::GetTopNearestBlockingFocusSession(Displa } auto parentSession = GetSceneSession(session->GetParentPersistentId()); if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr && - parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && - parentSession->IsTopmost()) { + parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost()) { TLOGND(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block"); return false; } - bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow(); - bool isPcOrPcMode = systemConfig_.IsPcWindow() || - (systemConfig_.IsPadWindow() && systemConfig_.IsFreeMultiWindowMode()); - bool isBlockingType = (includingAppSession && session->IsAppSession() && - !(isPcOrPcMode && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT)) || - (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) || - (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION); - if (IsSessionVisibleForeground(session) && isBlockingType) { + + if (IsSessionVisibleForeground(session) && CheckBlockingFocus(session, includingAppSession)) { ret = session; return true; } @@ -7005,6 +7060,38 @@ sptr SceneSessionManager::GetTopNearestBlockingFocusSession(Displa return ret; } +bool SceneSessionManager::CheckBlockingFocus(const sptr& session, bool includingAppSession) +{ + if (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) { + TLOGD(WmsLogTag::WMS_FOCUS, "system window blocked"); + return true; + } + + bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow(); + if (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION) { + return true; + } + if (includingAppSession && session->IsAppSession()) { + TLOGD(WmsLogTag::WMS_FOCUS, + "id: %{public}d, isFloatType: %{public}d, isFloatMode: %{public}d", session->GetPersistentId(), + session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT, + session->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING); + bool isPcOrPcMode = + systemConfig_.IsPcWindow() || (systemConfig_.IsPadWindow() && systemConfig_.IsFreeMultiWindowMode()); + + if (isPcOrPcMode && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) { + return false; + } + bool isPhoneAndPadWithoutPcMode = + systemConfig_.IsPhoneWindow() || (systemConfig_.IsPadWindow() && !systemConfig_.IsFreeMultiWindowMode()); + if (isPhoneAndPadWithoutPcMode && session->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) { + return false; + } + return true; + } + return false; +} + sptr SceneSessionManager::GetTopFocusableNonAppSession() { TLOGD(WmsLogTag::WMS_FOCUS, "in."); diff --git a/window_scene/session_manager/src/window_focus_controller.cpp b/window_scene/session_manager/src/window_focus_controller.cpp index 4c4c4217c4ac5a847f9b0569b809b04eaf832391..b2390728ef860774adce1b00ffab6244ecd06b32 100644 --- a/window_scene/session_manager/src/window_focus_controller.cpp +++ b/window_scene/session_manager/src/window_focus_controller.cpp @@ -44,7 +44,6 @@ WindowFocusController::WindowFocusController() noexcept DisplayId WindowFocusController::GetDisplayGroupId(DisplayId displayId) { - TLOGD(WmsLogTag::WMS_FOCUS, "displayId: %{public}" PRIu64, displayId); if (displayId == DEFAULT_DISPLAY_ID || virtualScreenDisplayIdSet_.size() == 0) { return DEFAULT_DISPLAY_ID; } @@ -86,8 +85,6 @@ WSError WindowFocusController::RemoveFocusGroup(DisplayId displayId) sptr WindowFocusController::GetFocusGroupInner(DisplayId displayId) { DisplayId displayGroupId = GetDisplayGroupId(displayId); - TLOGD(WmsLogTag::WMS_FOCUS, "displayId: %{public}" PRIu64 ", displayGroupId: %{public}" PRIu64, - displayId, displayGroupId); if (displayGroupId == DEFAULT_DISPLAY_ID) { return focusGroupMap_[DEFAULT_DISPLAY_ID]; } @@ -101,7 +98,6 @@ sptr WindowFocusController::GetFocusGroupInner(DisplayId displayId) int32_t WindowFocusController::GetFocusedSessionId(DisplayId displayId) { - TLOGD(WmsLogTag::WMS_FOCUS, "displayId: %{public}" PRIu64, displayId); if (displayId == DISPLAY_ID_INVALID) { TLOGE(WmsLogTag::WMS_FOCUS, "displayId invalid"); return INVALID_SESSION_ID; @@ -116,7 +112,6 @@ int32_t WindowFocusController::GetFocusedSessionId(DisplayId displayId) sptr WindowFocusController::GetFocusGroup(DisplayId displayId) { - TLOGD(WmsLogTag::WMS_FOCUS, "displayId: %{public}" PRIu64, displayId); if (displayId == DISPLAY_ID_INVALID) { TLOGE(WmsLogTag::WMS_FOCUS, "displayId invalid"); return nullptr; diff --git a/window_scene/test/unittest/scene_session_manager_test5.cpp b/window_scene/test/unittest/scene_session_manager_test5.cpp index 56bd440228c1277ecedf5eb2dd85be48e89ce809..8348e90b85f5a554029bcda0f54016b72d2cdf1d 100644 --- a/window_scene/test/unittest/scene_session_manager_test5.cpp +++ b/window_scene/test/unittest/scene_session_manager_test5.cpp @@ -1794,6 +1794,89 @@ HWTEST_F(SceneSessionManagerTest5, SetDelayRemoveSnapshot, TestSize.Level1) auto res = ssm_->GetDelayRemoveSnapshot(); ASSERT_EQ(true, res); } + +/** + * @tc.name: GetTopFloatingSession + * @tc.desc: GetTopFloatingSession Test + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerTest5, GetTopFloatingSession, TestSize.Level3) +{ + ssm_->sceneSessionMap_.clear(); + ASSERT_NE(ssm_, nullptr); + SessionInfo info; + info.abilityName_ = "GetTopFloatingSession"; + info.bundleName_ = "GetTopFloatingSession"; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + sceneSession->persistentId_ = 1; + sceneSession->zOrder_ = 1; + sceneSession->property_->SetDisplayId(DEFAULT_DISPLAY_ID); + ssm_->SetFocusedSessionId(1, DEFAULT_DISPLAY_ID); + + sptr sceneSession1 = sptr::MakeSptr(info, nullptr); + sceneSession1->persistentId_ = 2; + sceneSession1->zOrder_ = 2; + sceneSession1->property_->SetDisplayId(DEFAULT_DISPLAY_ID); + sceneSession1->SetFocusable(true); + sceneSession1->isVisible_ = true; + sptr result = ssm_->GetTopFloatingSession(DEFAULT_DISPLAY_ID, 1); + EXPECT_EQ(result, nullptr); + sceneSession1->property_->windowMode_ = WindowMode::WINDOW_MODE_FLOATING; + ssm_->sceneSessionMap_.insert(std::make_pair(sceneSession->GetPersistentId(), sceneSession)); + ssm_->sceneSessionMap_.insert(std::make_pair(sceneSession1->GetPersistentId(), sceneSession1)); + result = ssm_->GetTopFloatingSession(DEFAULT_DISPLAY_ID, 1); + ASSERT_NE(result, nullptr); + EXPECT_EQ(result->GetPersistentId(), sceneSession1->GetPersistentId()); +} + +/** + * @tc.name: GetNextFocusableSessionWhenFloatWindowExist + * @tc.desc: GetNextFocusableSessionWhenFloatWindowExist Test + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerTest5, GetNextFocusableSessionWhenFloatWindowExist, TestSize.Level3) +{ + ssm_->sceneSessionMap_.clear(); + ASSERT_NE(ssm_, nullptr); + SessionInfo info; + info.abilityName_ = "GetNextFocusableSessionWhenFloatWindowExist"; + info.bundleName_ = "GetNextFocusableSessionWhenFloatWindowExist"; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + sceneSession->persistentId_ = 1; + sceneSession->zOrder_ = 1; + sceneSession->property_->SetDisplayId(DEFAULT_DISPLAY_ID); + + ssm_->systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW; + ssm_->sceneSessionMap_.insert(std::make_pair(sceneSession->GetPersistentId(), sceneSession)); + sptr result = + ssm_->GetNextFocusableSessionWhenFloatWindowExist(DEFAULT_DISPLAY_ID, sceneSession->GetPersistentId()); + EXPECT_EQ(result, nullptr); + ssm_->systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW; + ssm_->systemConfig_.freeMultiWindowEnable_ = true; + result = ssm_->GetNextFocusableSessionWhenFloatWindowExist(DEFAULT_DISPLAY_ID, sceneSession->GetPersistentId()); + EXPECT_EQ(result, nullptr); + ssm_->systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW; + EXPECT_EQ(result, nullptr); + + sptr sceneSession1 = sptr::MakeSptr(info, nullptr); + sceneSession1->persistentId_ = 2; + sceneSession1->zOrder_ = 2; + sceneSession1->property_->SetDisplayId(DEFAULT_DISPLAY_ID); + sceneSession1->SetFocusable(true); + sceneSession1->isVisible_ = true; + sceneSession1->property_->windowMode_ = WindowMode::WINDOW_MODE_FLOATING; + + sceneSession->property_->SetWindowType(WindowType::WINDOW_TYPE_NEGATIVE_SCREEN); + ssm_->sceneSessionMap_.insert(std::make_pair(sceneSession1->GetPersistentId(), sceneSession1)); + result = ssm_->GetNextFocusableSessionWhenFloatWindowExist(DEFAULT_DISPLAY_ID, sceneSession->GetPersistentId()); + EXPECT_EQ(result, nullptr); + sceneSession->property_->SetWindowType(WindowType::APP_MAIN_WINDOW_BASE); + sceneSession->property_->windowMode_ = WindowMode::WINDOW_MODE_FULLSCREEN; + result = ssm_->GetNextFocusableSessionWhenFloatWindowExist(DEFAULT_DISPLAY_ID, sceneSession->GetPersistentId()); + ASSERT_NE(result, nullptr); + EXPECT_EQ(result->GetPersistentId(), sceneSession1->GetPersistentId()); +} + } // namespace } // namespace Rosen } // namespace OHOS