1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci 16e0dac50fSopenharmony_ci#include "window_root.h" 17e0dac50fSopenharmony_ci#include <ability_manager_client.h> 18e0dac50fSopenharmony_ci#include <cinttypes> 19e0dac50fSopenharmony_ci#include <hisysevent.h> 20e0dac50fSopenharmony_ci#include <hitrace_meter.h> 21e0dac50fSopenharmony_ci#include <transaction/rs_transaction.h> 22e0dac50fSopenharmony_ci 23e0dac50fSopenharmony_ci#ifdef POWERMGR_DISPLAY_MANAGER_ENABLE 24e0dac50fSopenharmony_ci#include <display_power_mgr_client.h> 25e0dac50fSopenharmony_ci#endif 26e0dac50fSopenharmony_ci 27e0dac50fSopenharmony_ci#include "display_manager_service_inner.h" 28e0dac50fSopenharmony_ci#include "permission.h" 29e0dac50fSopenharmony_ci#include "window_helper.h" 30e0dac50fSopenharmony_ci#include "window_inner_manager.h" 31e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 32e0dac50fSopenharmony_ci#include "window_manager_service.h" 33e0dac50fSopenharmony_ci#include "window_manager_service_utils.h" 34e0dac50fSopenharmony_ci#include "window_manager_agent_controller.h" 35e0dac50fSopenharmony_ci#include "window_system_effect.h" 36e0dac50fSopenharmony_ci#ifdef MEMMGR_WINDOW_ENABLE 37e0dac50fSopenharmony_ci#include "mem_mgr_client.h" 38e0dac50fSopenharmony_ci#include "mem_mgr_window_info.h" 39e0dac50fSopenharmony_ci#endif 40e0dac50fSopenharmony_cinamespace OHOS { 41e0dac50fSopenharmony_cinamespace Rosen { 42e0dac50fSopenharmony_cinamespace { 43e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Root"}; 44e0dac50fSopenharmony_ciint Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b) 45e0dac50fSopenharmony_ci{ 46e0dac50fSopenharmony_ci return a.first < b.first; 47e0dac50fSopenharmony_ci} 48e0dac50fSopenharmony_ci} 49e0dac50fSopenharmony_ci 50e0dac50fSopenharmony_ciuint32_t WindowRoot::GetTotalWindowNum() const 51e0dac50fSopenharmony_ci{ 52e0dac50fSopenharmony_ci return static_cast<uint32_t>(windowNodeMap_.size()); 53e0dac50fSopenharmony_ci} 54e0dac50fSopenharmony_ci 55e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::GetWindowForDumpAceHelpInfo() const 56e0dac50fSopenharmony_ci{ 57e0dac50fSopenharmony_ci for (auto& iter : windowNodeMap_) { 58e0dac50fSopenharmony_ci if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP || 59e0dac50fSopenharmony_ci iter.second->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR || 60e0dac50fSopenharmony_ci iter.second->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || 61e0dac50fSopenharmony_ci iter.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) { 62e0dac50fSopenharmony_ci return iter.second; 63e0dac50fSopenharmony_ci } 64e0dac50fSopenharmony_ci } 65e0dac50fSopenharmony_ci return nullptr; 66e0dac50fSopenharmony_ci} 67e0dac50fSopenharmony_ci 68e0dac50fSopenharmony_ciScreenId WindowRoot::GetScreenGroupId(DisplayId displayId, bool& isRecordedDisplay) 69e0dac50fSopenharmony_ci{ 70e0dac50fSopenharmony_ci for (auto iter : displayIdMap_) { 71e0dac50fSopenharmony_ci auto displayIdVec = iter.second; 72e0dac50fSopenharmony_ci if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) { 73e0dac50fSopenharmony_ci isRecordedDisplay = true; 74e0dac50fSopenharmony_ci return iter.first; 75e0dac50fSopenharmony_ci } 76e0dac50fSopenharmony_ci } 77e0dac50fSopenharmony_ci isRecordedDisplay = false; 78e0dac50fSopenharmony_ci WLOGFE("Current display is not be recorded, displayId: %{public}" PRIu64 "", displayId); 79e0dac50fSopenharmony_ci return DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); 80e0dac50fSopenharmony_ci} 81e0dac50fSopenharmony_ci 82e0dac50fSopenharmony_cisptr<WindowNodeContainer> WindowRoot::GetOrCreateWindowNodeContainer(DisplayId displayId) 83e0dac50fSopenharmony_ci{ 84e0dac50fSopenharmony_ci auto container = GetWindowNodeContainer(displayId); 85e0dac50fSopenharmony_ci if (container != nullptr) { 86e0dac50fSopenharmony_ci return container; 87e0dac50fSopenharmony_ci } 88e0dac50fSopenharmony_ci 89e0dac50fSopenharmony_ci // In case of have no container for default display, create container 90e0dac50fSopenharmony_ci WLOGI("Create container for current display, displayId: %{public}" PRIu64 "", displayId); 91e0dac50fSopenharmony_ci sptr<DisplayInfo> displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); 92e0dac50fSopenharmony_ci DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); 93e0dac50fSopenharmony_ci return CreateWindowNodeContainer(defaultDisplayId, displayInfo); 94e0dac50fSopenharmony_ci} 95e0dac50fSopenharmony_ci 96e0dac50fSopenharmony_cisptr<WindowNodeContainer> WindowRoot::GetWindowNodeContainer(DisplayId displayId) 97e0dac50fSopenharmony_ci{ 98e0dac50fSopenharmony_ci bool isRecordedDisplay; 99e0dac50fSopenharmony_ci ScreenId displayGroupId = GetScreenGroupId(displayId, isRecordedDisplay); 100e0dac50fSopenharmony_ci auto iter = windowNodeContainerMap_.find(displayGroupId); 101e0dac50fSopenharmony_ci if (iter != windowNodeContainerMap_.end()) { 102e0dac50fSopenharmony_ci // if container exist for screenGroup and display is not be recorded, process expand display 103e0dac50fSopenharmony_ci if (!isRecordedDisplay) { 104e0dac50fSopenharmony_ci sptr<DisplayInfo> displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); 105e0dac50fSopenharmony_ci // add displayId in displayId vector 106e0dac50fSopenharmony_ci displayIdMap_[displayGroupId].push_back(displayId); 107e0dac50fSopenharmony_ci auto displayRectMap = GetAllDisplayRectsByDMS(displayInfo); 108e0dac50fSopenharmony_ci DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); 109e0dac50fSopenharmony_ci ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); 110e0dac50fSopenharmony_ci } 111e0dac50fSopenharmony_ci return iter->second; 112e0dac50fSopenharmony_ci } 113e0dac50fSopenharmony_ci return nullptr; 114e0dac50fSopenharmony_ci} 115e0dac50fSopenharmony_ci 116e0dac50fSopenharmony_cisptr<WindowNodeContainer> WindowRoot::CreateWindowNodeContainer(DisplayId defaultDisplayId, 117e0dac50fSopenharmony_ci sptr<DisplayInfo> displayInfo) 118e0dac50fSopenharmony_ci{ 119e0dac50fSopenharmony_ci if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { 120e0dac50fSopenharmony_ci WLOGFE("get display failed or get invalid display info"); 121e0dac50fSopenharmony_ci return nullptr; 122e0dac50fSopenharmony_ci } 123e0dac50fSopenharmony_ci 124e0dac50fSopenharmony_ci DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId); 125e0dac50fSopenharmony_ci DisplayId displayId = displayInfo->GetDisplayId(); 126e0dac50fSopenharmony_ci ScreenId displayGroupId = displayInfo->GetScreenGroupId(); 127e0dac50fSopenharmony_ci WLOGI("create new container for display, width: %{public}d, height: %{public}d, " 128e0dac50fSopenharmony_ci "displayGroupId:%{public}" PRIu64", displayId:%{public}" PRIu64"", displayInfo->GetWidth(), 129e0dac50fSopenharmony_ci displayInfo->GetHeight(), displayGroupId, displayId); 130e0dac50fSopenharmony_ci sptr<WindowNodeContainer> container = new WindowNodeContainer(displayInfo, displayGroupId); 131e0dac50fSopenharmony_ci windowNodeContainerMap_.insert(std::make_pair(displayGroupId, container)); 132e0dac50fSopenharmony_ci std::vector<DisplayId> displayVec = { displayId }; 133e0dac50fSopenharmony_ci displayIdMap_.insert(std::make_pair(displayGroupId, displayVec)); 134e0dac50fSopenharmony_ci if (container == nullptr) { 135e0dac50fSopenharmony_ci WLOGFE("create container failed, displayId :%{public}" PRIu64 "", displayId); 136e0dac50fSopenharmony_ci return nullptr; 137e0dac50fSopenharmony_ci } 138e0dac50fSopenharmony_ci container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_); 139e0dac50fSopenharmony_ci return container; 140e0dac50fSopenharmony_ci} 141e0dac50fSopenharmony_ci 142e0dac50fSopenharmony_cibool WindowRoot::CheckDisplayInfo(const sptr<DisplayInfo>& display) 143e0dac50fSopenharmony_ci{ 144e0dac50fSopenharmony_ci const int32_t minWidth = 50; 145e0dac50fSopenharmony_ci const int32_t minHeight = 50; 146e0dac50fSopenharmony_ci const int32_t maxWidth = 7680; 147e0dac50fSopenharmony_ci const int32_t maxHeight = 7680; // 8k resolution 148e0dac50fSopenharmony_ci if (display->GetWidth() < minWidth || display->GetWidth() > maxWidth || 149e0dac50fSopenharmony_ci display->GetHeight() < minHeight || display->GetHeight() > maxHeight) { 150e0dac50fSopenharmony_ci return false; 151e0dac50fSopenharmony_ci } 152e0dac50fSopenharmony_ci return true; 153e0dac50fSopenharmony_ci} 154e0dac50fSopenharmony_ci 155e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::GetWindowNode(uint32_t windowId) const 156e0dac50fSopenharmony_ci{ 157e0dac50fSopenharmony_ci auto iter = windowNodeMap_.find(windowId); 158e0dac50fSopenharmony_ci if (iter == windowNodeMap_.end()) { 159e0dac50fSopenharmony_ci return nullptr; 160e0dac50fSopenharmony_ci } 161e0dac50fSopenharmony_ci return iter->second; 162e0dac50fSopenharmony_ci} 163e0dac50fSopenharmony_ci 164e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::GetWindowNodeByMissionId(uint32_t missionId) const 165e0dac50fSopenharmony_ci{ 166e0dac50fSopenharmony_ci using ValueType = const std::map<uint32_t, sptr<WindowNode>>::value_type&; 167e0dac50fSopenharmony_ci auto it = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), [missionId] (ValueType item) { 168e0dac50fSopenharmony_ci return item.second && item.second->abilityInfo_.missionId_ == static_cast<int32_t>(missionId); 169e0dac50fSopenharmony_ci }); 170e0dac50fSopenharmony_ci return it == windowNodeMap_.end() ? nullptr : it->second; 171e0dac50fSopenharmony_ci} 172e0dac50fSopenharmony_ci 173e0dac50fSopenharmony_civoid WindowRoot::GetBackgroundNodesByScreenId(ScreenId screenGroupId, std::vector<sptr<WindowNode>>& windowNodes) 174e0dac50fSopenharmony_ci{ 175e0dac50fSopenharmony_ci for (const auto& it : windowNodeMap_) { 176e0dac50fSopenharmony_ci if (it.second == nullptr) { 177e0dac50fSopenharmony_ci continue; 178e0dac50fSopenharmony_ci } 179e0dac50fSopenharmony_ci wptr<WindowNodeContainer> container = GetWindowNodeContainer(it.second->GetDisplayId()); 180e0dac50fSopenharmony_ci if (container == nullptr) { 181e0dac50fSopenharmony_ci continue; 182e0dac50fSopenharmony_ci } 183e0dac50fSopenharmony_ci auto iter = std::find_if(windowNodeContainerMap_.begin(), windowNodeContainerMap_.end(), 184e0dac50fSopenharmony_ci [container](const std::map<uint64_t, sptr<WindowNodeContainer>>::value_type& containerPair) { 185e0dac50fSopenharmony_ci return container.promote() == containerPair.second; 186e0dac50fSopenharmony_ci }); 187e0dac50fSopenharmony_ci ScreenId screenGroupIdOfNode = INVALID_SCREEN_ID; 188e0dac50fSopenharmony_ci if (iter != windowNodeContainerMap_.end()) { 189e0dac50fSopenharmony_ci screenGroupIdOfNode = iter->first; 190e0dac50fSopenharmony_ci } 191e0dac50fSopenharmony_ci if (screenGroupId == screenGroupIdOfNode && !it.second->currentVisibility_) { 192e0dac50fSopenharmony_ci windowNodes.push_back(it.second); 193e0dac50fSopenharmony_ci } 194e0dac50fSopenharmony_ci } 195e0dac50fSopenharmony_ci} 196e0dac50fSopenharmony_ci 197e0dac50fSopenharmony_civoid WindowRoot::GetForegroundNodes(std::vector<sptr<WindowNode>>& windowNodes) 198e0dac50fSopenharmony_ci{ 199e0dac50fSopenharmony_ci for (const auto& it : windowNodeMap_) { 200e0dac50fSopenharmony_ci if (it.second == nullptr) { 201e0dac50fSopenharmony_ci continue; 202e0dac50fSopenharmony_ci } 203e0dac50fSopenharmony_ci if (it.second->currentVisibility_) { 204e0dac50fSopenharmony_ci windowNodes.push_back(it.second); 205e0dac50fSopenharmony_ci } 206e0dac50fSopenharmony_ci } 207e0dac50fSopenharmony_ci} 208e0dac50fSopenharmony_ci 209e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::FindWindowNodeWithToken(const sptr<IRemoteObject>& token) const 210e0dac50fSopenharmony_ci{ 211e0dac50fSopenharmony_ci if (token == nullptr) { 212e0dac50fSopenharmony_ci WLOGFE("token is null"); 213e0dac50fSopenharmony_ci return nullptr; 214e0dac50fSopenharmony_ci } 215e0dac50fSopenharmony_ci auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), 216e0dac50fSopenharmony_ci [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) { 217e0dac50fSopenharmony_ci if ((WindowHelper::IsMainWindow(pair.second->GetWindowType())) || 218e0dac50fSopenharmony_ci (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP)) { 219e0dac50fSopenharmony_ci return pair.second->abilityToken_ == token; 220e0dac50fSopenharmony_ci } 221e0dac50fSopenharmony_ci return false; 222e0dac50fSopenharmony_ci }); 223e0dac50fSopenharmony_ci if (iter == windowNodeMap_.end()) { 224e0dac50fSopenharmony_ci WLOGE("cannot find windowNode"); 225e0dac50fSopenharmony_ci return nullptr; 226e0dac50fSopenharmony_ci } 227e0dac50fSopenharmony_ci return iter->second; 228e0dac50fSopenharmony_ci} 229e0dac50fSopenharmony_ci 230e0dac50fSopenharmony_civoid WindowRoot::AddDeathRecipient(sptr<WindowNode> node) 231e0dac50fSopenharmony_ci{ 232e0dac50fSopenharmony_ci if (node == nullptr || node->GetWindowToken() == nullptr) { 233e0dac50fSopenharmony_ci WLOGFE("failed, node is nullptr"); 234e0dac50fSopenharmony_ci return; 235e0dac50fSopenharmony_ci } 236e0dac50fSopenharmony_ci WLOGFD("Add for window: %{public}u", node->GetWindowId()); 237e0dac50fSopenharmony_ci 238e0dac50fSopenharmony_ci auto remoteObject = node->GetWindowToken()->AsObject(); 239e0dac50fSopenharmony_ci windowIdMap_.insert(std::make_pair(remoteObject, node->GetWindowId())); 240e0dac50fSopenharmony_ci 241e0dac50fSopenharmony_ci if (windowDeath_ == nullptr) { 242e0dac50fSopenharmony_ci WLOGE("failed to create death Recipient ptr WindowDeathRecipient"); 243e0dac50fSopenharmony_ci return; 244e0dac50fSopenharmony_ci } 245e0dac50fSopenharmony_ci if (!remoteObject->AddDeathRecipient(windowDeath_)) { 246e0dac50fSopenharmony_ci WLOGE("failed to add death recipient"); 247e0dac50fSopenharmony_ci } 248e0dac50fSopenharmony_ci} 249e0dac50fSopenharmony_ci 250e0dac50fSopenharmony_ciWMError WindowRoot::SaveWindow(const sptr<WindowNode>& node) 251e0dac50fSopenharmony_ci{ 252e0dac50fSopenharmony_ci if (node == nullptr) { 253e0dac50fSopenharmony_ci WLOGFE("add window failed, node is nullptr"); 254e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 255e0dac50fSopenharmony_ci } 256e0dac50fSopenharmony_ci 257e0dac50fSopenharmony_ci WLOGFD("save windowId %{public}u", node->GetWindowId()); 258e0dac50fSopenharmony_ci windowNodeMap_.insert(std::make_pair(node->GetWindowId(), node)); 259e0dac50fSopenharmony_ci if (node->surfaceNode_ != nullptr) { 260e0dac50fSopenharmony_ci surfaceIdWindowNodeMap_.insert(std::make_pair(node->surfaceNode_->GetId(), node)); 261e0dac50fSopenharmony_ci if (WindowHelper::IsMainWindow(node->GetWindowType())) { 262e0dac50fSopenharmony_ci // Register FirstFrame Callback to rs, inform ability to get snapshot 263e0dac50fSopenharmony_ci wptr<WindowNode> weak = node; 264e0dac50fSopenharmony_ci auto firstFrameCompleteCallback = [weak]() { 265e0dac50fSopenharmony_ci auto weakNode = weak.promote(); 266e0dac50fSopenharmony_ci if (weakNode == nullptr) { 267e0dac50fSopenharmony_ci WLOGFE("windowNode is nullptr"); 268e0dac50fSopenharmony_ci return; 269e0dac50fSopenharmony_ci } 270e0dac50fSopenharmony_ci WindowInnerManager::GetInstance().CompleteFirstFrameDrawing(weakNode); 271e0dac50fSopenharmony_ci }; 272e0dac50fSopenharmony_ci node->surfaceNode_->SetBufferAvailableCallback(firstFrameCompleteCallback); 273e0dac50fSopenharmony_ci } 274e0dac50fSopenharmony_ci } 275e0dac50fSopenharmony_ci AddDeathRecipient(node); 276e0dac50fSopenharmony_ci if (WindowHelper::IsMainWindow(node->GetWindowType())) { 277e0dac50fSopenharmony_ci WindowInfoReporter::GetInstance().InsertCreateReportInfo(node->abilityInfo_.bundleName_); 278e0dac50fSopenharmony_ci } 279e0dac50fSopenharmony_ci return WMError::WM_OK; 280e0dac50fSopenharmony_ci} 281e0dac50fSopenharmony_ci 282e0dac50fSopenharmony_ciWMError WindowRoot::MinimizeStructuredAppWindowsExceptSelf(sptr<WindowNode>& node) 283e0dac50fSopenharmony_ci{ 284e0dac50fSopenharmony_ci HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "root:MinimizeStructuredAppWindowsExceptSelf"); 285e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 286e0dac50fSopenharmony_ci if (container == nullptr) { 287e0dac50fSopenharmony_ci WLOGFE("MinimizeAbility failed, window container could not be found"); 288e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 289e0dac50fSopenharmony_ci } 290e0dac50fSopenharmony_ci return container->MinimizeStructuredAppWindowsExceptSelf(node); 291e0dac50fSopenharmony_ci} 292e0dac50fSopenharmony_ci 293e0dac50fSopenharmony_civoid WindowRoot::MinimizeTargetWindows(std::vector<uint32_t>& windowIds) 294e0dac50fSopenharmony_ci{ 295e0dac50fSopenharmony_ci for (auto& windowId : windowIds) { 296e0dac50fSopenharmony_ci if (windowNodeMap_.count(windowId) != 0) { 297e0dac50fSopenharmony_ci auto windowNode = windowNodeMap_[windowId]; 298e0dac50fSopenharmony_ci if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { 299e0dac50fSopenharmony_ci MinimizeApp::AddNeedMinimizeApp(windowNode, MinimizeReason::GESTURE_ANIMATION); 300e0dac50fSopenharmony_ci } else { 301e0dac50fSopenharmony_ci WLOGFE("Minimize window failed id: %{public}u, type: %{public}u", 302e0dac50fSopenharmony_ci windowNode->GetWindowId(), static_cast<uint32_t>(windowNode->GetWindowType())); 303e0dac50fSopenharmony_ci } 304e0dac50fSopenharmony_ci } else { 305e0dac50fSopenharmony_ci WLOGFW("Cannot find window with id: %{public}u", windowId); 306e0dac50fSopenharmony_ci } 307e0dac50fSopenharmony_ci } 308e0dac50fSopenharmony_ci} 309e0dac50fSopenharmony_ci 310e0dac50fSopenharmony_cistd::vector<sptr<WindowNode>> WindowRoot::GetSplitScreenWindowNodes(DisplayId displayId) 311e0dac50fSopenharmony_ci{ 312e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 313e0dac50fSopenharmony_ci if (container == nullptr) { 314e0dac50fSopenharmony_ci return {}; 315e0dac50fSopenharmony_ci } 316e0dac50fSopenharmony_ci auto displayGroupController = container->GetDisplayGroupController(); 317e0dac50fSopenharmony_ci if (displayGroupController == nullptr) { 318e0dac50fSopenharmony_ci return {}; 319e0dac50fSopenharmony_ci } 320e0dac50fSopenharmony_ci auto windowPair = displayGroupController->GetWindowPairByDisplayId(displayId); 321e0dac50fSopenharmony_ci if (windowPair == nullptr) { 322e0dac50fSopenharmony_ci return {}; 323e0dac50fSopenharmony_ci } 324e0dac50fSopenharmony_ci return windowPair->GetPairedWindows(); 325e0dac50fSopenharmony_ci} 326e0dac50fSopenharmony_ci 327e0dac50fSopenharmony_cibool WindowRoot::IsForbidDockSliceMove(DisplayId displayId) const 328e0dac50fSopenharmony_ci{ 329e0dac50fSopenharmony_ci auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId); 330e0dac50fSopenharmony_ci if (container == nullptr) { 331e0dac50fSopenharmony_ci WLOGFE("can't find container"); 332e0dac50fSopenharmony_ci return true; 333e0dac50fSopenharmony_ci } 334e0dac50fSopenharmony_ci return container->IsForbidDockSliceMove(displayId); 335e0dac50fSopenharmony_ci} 336e0dac50fSopenharmony_ci 337e0dac50fSopenharmony_cibool WindowRoot::IsDockSliceInExitSplitModeArea(DisplayId displayId) const 338e0dac50fSopenharmony_ci{ 339e0dac50fSopenharmony_ci auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId); 340e0dac50fSopenharmony_ci if (container == nullptr) { 341e0dac50fSopenharmony_ci WLOGFE("can't find container"); 342e0dac50fSopenharmony_ci return false; 343e0dac50fSopenharmony_ci } 344e0dac50fSopenharmony_ci return container->IsDockSliceInExitSplitModeArea(displayId); 345e0dac50fSopenharmony_ci} 346e0dac50fSopenharmony_ci 347e0dac50fSopenharmony_civoid WindowRoot::ExitSplitMode(DisplayId displayId) 348e0dac50fSopenharmony_ci{ 349e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 350e0dac50fSopenharmony_ci if (container == nullptr) { 351e0dac50fSopenharmony_ci WLOGFE("can't find container"); 352e0dac50fSopenharmony_ci return; 353e0dac50fSopenharmony_ci } 354e0dac50fSopenharmony_ci container->ExitSplitMode(displayId); 355e0dac50fSopenharmony_ci} 356e0dac50fSopenharmony_ci 357e0dac50fSopenharmony_civoid WindowRoot::AddSurfaceNodeIdWindowNodePair(uint64_t surfaceNodeId, sptr<WindowNode> node) 358e0dac50fSopenharmony_ci{ 359e0dac50fSopenharmony_ci surfaceIdWindowNodeMap_.insert(std::make_pair(surfaceNodeId, node)); 360e0dac50fSopenharmony_ci} 361e0dac50fSopenharmony_ci 362e0dac50fSopenharmony_cistatic void FillUnreliableWindowInfo(const sptr<WindowNode>& windowNode, 363e0dac50fSopenharmony_ci std::vector<sptr<UnreliableWindowInfo>>& infos) 364e0dac50fSopenharmony_ci{ 365e0dac50fSopenharmony_ci if (windowNode == nullptr) { 366e0dac50fSopenharmony_ci WLOGFW("null window node."); 367e0dac50fSopenharmony_ci return; 368e0dac50fSopenharmony_ci } 369e0dac50fSopenharmony_ci sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo(); 370e0dac50fSopenharmony_ci if (info == nullptr) { 371e0dac50fSopenharmony_ci WLOGFE("null info."); 372e0dac50fSopenharmony_ci return; 373e0dac50fSopenharmony_ci } 374e0dac50fSopenharmony_ci info->windowId_ = static_cast<int32_t>(windowNode->GetWindowId()); 375e0dac50fSopenharmony_ci info->windowRect_ = windowNode->GetWindowRect(); 376e0dac50fSopenharmony_ci info->zOrder_ = windowNode->zOrder_; 377e0dac50fSopenharmony_ci infos.emplace_back(info); 378e0dac50fSopenharmony_ci WLOGFI("windowId = %{public}d", info->windowId_); 379e0dac50fSopenharmony_ci} 380e0dac50fSopenharmony_ci 381e0dac50fSopenharmony_cistatic bool CheckUnreliableWindowType(WindowType windowType) 382e0dac50fSopenharmony_ci{ 383e0dac50fSopenharmony_ci if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW || 384e0dac50fSopenharmony_ci windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || 385e0dac50fSopenharmony_ci windowType == WindowType::WINDOW_TYPE_TOAST) { 386e0dac50fSopenharmony_ci return true; 387e0dac50fSopenharmony_ci } 388e0dac50fSopenharmony_ci WLOGFI("false, WindowType = %{public}d", windowType); 389e0dac50fSopenharmony_ci return false; 390e0dac50fSopenharmony_ci} 391e0dac50fSopenharmony_ci 392e0dac50fSopenharmony_civoid WindowRoot::GetUnreliableWindowInfo(int32_t windowId, std::vector<sptr<UnreliableWindowInfo>>& infos) const 393e0dac50fSopenharmony_ci{ 394e0dac50fSopenharmony_ci WLOGFD("Called."); 395e0dac50fSopenharmony_ci for (const auto& [winId, windowNode] : windowNodeMap_) { 396e0dac50fSopenharmony_ci if (windowNode == nullptr) { 397e0dac50fSopenharmony_ci WLOGFW("null window node"); 398e0dac50fSopenharmony_ci continue; 399e0dac50fSopenharmony_ci } 400e0dac50fSopenharmony_ci int32_t curWindowId = static_cast<int32_t>(winId); 401e0dac50fSopenharmony_ci if (curWindowId == windowId) { 402e0dac50fSopenharmony_ci WLOGFI("windowId: %{public}d is parameter chosen", curWindowId); 403e0dac50fSopenharmony_ci FillUnreliableWindowInfo(windowNode, infos); 404e0dac50fSopenharmony_ci continue; 405e0dac50fSopenharmony_ci } 406e0dac50fSopenharmony_ci if (!windowNode->currentVisibility_) { 407e0dac50fSopenharmony_ci WLOGFD("windowId: %{public}d is not visible", curWindowId); 408e0dac50fSopenharmony_ci continue; 409e0dac50fSopenharmony_ci } 410e0dac50fSopenharmony_ci WLOGFD("name = %{public}s, windowId = %{public}d, winType = %{public}d, " 411e0dac50fSopenharmony_ci "visible = %{public}d", windowNode->GetWindowName().c_str(), 412e0dac50fSopenharmony_ci curWindowId, windowNode->GetWindowType(), windowNode->currentVisibility_); 413e0dac50fSopenharmony_ci if (CheckUnreliableWindowType(windowNode->GetWindowType())) { 414e0dac50fSopenharmony_ci WLOGFI("windowId = %{public}d, WindowType = %{public}d", curWindowId, windowNode->GetWindowType()); 415e0dac50fSopenharmony_ci FillUnreliableWindowInfo(windowNode, infos); 416e0dac50fSopenharmony_ci } 417e0dac50fSopenharmony_ci } 418e0dac50fSopenharmony_ci} 419e0dac50fSopenharmony_ci 420e0dac50fSopenharmony_civoid WindowRoot::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos) const 421e0dac50fSopenharmony_ci{ 422e0dac50fSopenharmony_ci if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) { 423e0dac50fSopenharmony_ci WLOGFE("Get Visible Window Permission Denied"); 424e0dac50fSopenharmony_ci } 425e0dac50fSopenharmony_ci for (auto [surfaceId, _] : lastVisibleData_) { 426e0dac50fSopenharmony_ci auto iter = surfaceIdWindowNodeMap_.find(surfaceId); 427e0dac50fSopenharmony_ci if (iter == surfaceIdWindowNodeMap_.end()) { 428e0dac50fSopenharmony_ci continue; 429e0dac50fSopenharmony_ci } 430e0dac50fSopenharmony_ci sptr<WindowNode> node = iter->second; 431e0dac50fSopenharmony_ci if (node == nullptr) { 432e0dac50fSopenharmony_ci continue; 433e0dac50fSopenharmony_ci } 434e0dac50fSopenharmony_ci infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), 435e0dac50fSopenharmony_ci node->GetCallingUid(), node->GetVisibilityState(), node->GetWindowType())); 436e0dac50fSopenharmony_ci } 437e0dac50fSopenharmony_ci} 438e0dac50fSopenharmony_ci 439e0dac50fSopenharmony_cistd::vector<std::pair<uint64_t, WindowVisibilityState>> WindowRoot::GetWindowVisibilityChangeInfo( 440e0dac50fSopenharmony_ci std::shared_ptr<RSOcclusionData> occlusionData) 441e0dac50fSopenharmony_ci{ 442e0dac50fSopenharmony_ci std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo; 443e0dac50fSopenharmony_ci VisibleData& rsVisibleData = occlusionData->GetVisibleData(); 444e0dac50fSopenharmony_ci std::vector<std::pair<uint64_t, WindowVisibilityState> > currVisibleData; 445e0dac50fSopenharmony_ci for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) { 446e0dac50fSopenharmony_ci if (static_cast<WindowLayerState>(iter->second) < WINDOW_LAYER_DRAWING) { 447e0dac50fSopenharmony_ci currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second)); 448e0dac50fSopenharmony_ci } 449e0dac50fSopenharmony_ci } 450e0dac50fSopenharmony_ci std::sort(currVisibleData.begin(), currVisibleData.end(), Comp); 451e0dac50fSopenharmony_ci uint32_t i, j; 452e0dac50fSopenharmony_ci i = j = 0; 453e0dac50fSopenharmony_ci for (; i < lastVisibleData_.size() && j < currVisibleData.size();) { 454e0dac50fSopenharmony_ci if (lastVisibleData_[i].first < currVisibleData[j].first) { 455e0dac50fSopenharmony_ci visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION); 456e0dac50fSopenharmony_ci i++; 457e0dac50fSopenharmony_ci } else if (lastVisibleData_[i].first > currVisibleData[j].first) { 458e0dac50fSopenharmony_ci visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second); 459e0dac50fSopenharmony_ci j++; 460e0dac50fSopenharmony_ci } else { 461e0dac50fSopenharmony_ci if (lastVisibleData_[i].second != currVisibleData[j].second) { 462e0dac50fSopenharmony_ci visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second); 463e0dac50fSopenharmony_ci } 464e0dac50fSopenharmony_ci i++; 465e0dac50fSopenharmony_ci j++; 466e0dac50fSopenharmony_ci } 467e0dac50fSopenharmony_ci } 468e0dac50fSopenharmony_ci for (; i < lastVisibleData_.size(); ++i) { 469e0dac50fSopenharmony_ci visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION); 470e0dac50fSopenharmony_ci } 471e0dac50fSopenharmony_ci for (; j < currVisibleData.size(); ++j) { 472e0dac50fSopenharmony_ci visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second); 473e0dac50fSopenharmony_ci } 474e0dac50fSopenharmony_ci lastVisibleData_ = currVisibleData; 475e0dac50fSopenharmony_ci return visibilityChangeInfo; 476e0dac50fSopenharmony_ci} 477e0dac50fSopenharmony_ci 478e0dac50fSopenharmony_civoid WindowRoot::NotifyWindowVisibilityChange(std::shared_ptr<RSOcclusionData> occlusionData) 479e0dac50fSopenharmony_ci{ 480e0dac50fSopenharmony_ci std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo = 481e0dac50fSopenharmony_ci GetWindowVisibilityChangeInfo(occlusionData); 482e0dac50fSopenharmony_ci std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos; 483e0dac50fSopenharmony_ci#ifdef MEMMGR_WINDOW_ENABLE 484e0dac50fSopenharmony_ci std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos; 485e0dac50fSopenharmony_ci#endif 486e0dac50fSopenharmony_ci for (const auto& elem : visibilityChangeInfo) { 487e0dac50fSopenharmony_ci uint64_t surfaceId = elem.first; 488e0dac50fSopenharmony_ci WindowVisibilityState visibilityState = elem.second; 489e0dac50fSopenharmony_ci bool isVisible = visibilityState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION; 490e0dac50fSopenharmony_ci auto iter = surfaceIdWindowNodeMap_.find(surfaceId); 491e0dac50fSopenharmony_ci if (iter == surfaceIdWindowNodeMap_.end()) { 492e0dac50fSopenharmony_ci continue; 493e0dac50fSopenharmony_ci } 494e0dac50fSopenharmony_ci sptr<WindowNode> node = iter->second; 495e0dac50fSopenharmony_ci if (node == nullptr) { 496e0dac50fSopenharmony_ci continue; 497e0dac50fSopenharmony_ci } 498e0dac50fSopenharmony_ci node->SetVisibilityState(visibilityState); 499e0dac50fSopenharmony_ci windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), 500e0dac50fSopenharmony_ci node->GetCallingUid(), visibilityState, node->GetWindowType())); 501e0dac50fSopenharmony_ci#ifdef MEMMGR_WINDOW_ENABLE 502e0dac50fSopenharmony_ci memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(node->GetWindowId(), node->GetCallingPid(), 503e0dac50fSopenharmony_ci node->GetCallingUid(), isVisible)); 504e0dac50fSopenharmony_ci#endif 505e0dac50fSopenharmony_ci WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, visibilityState:%{public}d", 506e0dac50fSopenharmony_ci node->GetWindowId(), visibilityState); 507e0dac50fSopenharmony_ci } 508e0dac50fSopenharmony_ci CheckAndNotifyWaterMarkChangedResult(); 509e0dac50fSopenharmony_ci if (windowVisibilityInfos.size() != 0) { 510e0dac50fSopenharmony_ci WLOGI("Notify windowvisibilityinfo changed start"); 511e0dac50fSopenharmony_ci WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos); 512e0dac50fSopenharmony_ci } 513e0dac50fSopenharmony_ci#ifdef MEMMGR_WINDOW_ENABLE 514e0dac50fSopenharmony_ci if (memMgrWindowInfos.size() != 0) { 515e0dac50fSopenharmony_ci WLOGI("Notify memMgrWindowInfos changed start"); 516e0dac50fSopenharmony_ci Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos); 517e0dac50fSopenharmony_ci } 518e0dac50fSopenharmony_ci#endif 519e0dac50fSopenharmony_ci} 520e0dac50fSopenharmony_ci 521e0dac50fSopenharmony_ciAvoidArea WindowRoot::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) 522e0dac50fSopenharmony_ci{ 523e0dac50fSopenharmony_ci AvoidArea avoidArea; 524e0dac50fSopenharmony_ci sptr<WindowNode> node = GetWindowNode(windowId); 525e0dac50fSopenharmony_ci if (node == nullptr) { 526e0dac50fSopenharmony_ci WLOGFE("could not find window"); 527e0dac50fSopenharmony_ci return avoidArea; 528e0dac50fSopenharmony_ci } 529e0dac50fSopenharmony_ci sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 530e0dac50fSopenharmony_ci if (container == nullptr) { 531e0dac50fSopenharmony_ci WLOGFE("add window failed, window container could not be found"); 532e0dac50fSopenharmony_ci return avoidArea; 533e0dac50fSopenharmony_ci } 534e0dac50fSopenharmony_ci return container->GetAvoidAreaByType(node, avoidAreaType); 535e0dac50fSopenharmony_ci} 536e0dac50fSopenharmony_ci 537e0dac50fSopenharmony_civoid WindowRoot::MinimizeAllAppWindows(DisplayId displayId) 538e0dac50fSopenharmony_ci{ 539e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 540e0dac50fSopenharmony_ci if (container == nullptr) { 541e0dac50fSopenharmony_ci WLOGFE("can't find window node container, failed!"); 542e0dac50fSopenharmony_ci return; 543e0dac50fSopenharmony_ci } 544e0dac50fSopenharmony_ci return container->MinimizeAllAppWindows(displayId); 545e0dac50fSopenharmony_ci} 546e0dac50fSopenharmony_ci 547e0dac50fSopenharmony_ciWMError WindowRoot::ToggleShownStateForAllAppWindows() 548e0dac50fSopenharmony_ci{ 549e0dac50fSopenharmony_ci std::vector<DisplayId> displays = DisplayGroupInfo::GetInstance().GetAllDisplayIds(); 550e0dac50fSopenharmony_ci std::vector<sptr<WindowNodeContainer>> containers; 551e0dac50fSopenharmony_ci bool isAllAppWindowsEmpty = true; 552e0dac50fSopenharmony_ci for (auto displayId : displays) { 553e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 554e0dac50fSopenharmony_ci if (container == nullptr) { 555e0dac50fSopenharmony_ci WLOGFE("can't find window node container, failed!"); 556e0dac50fSopenharmony_ci continue; 557e0dac50fSopenharmony_ci } 558e0dac50fSopenharmony_ci containers.emplace_back(container); 559e0dac50fSopenharmony_ci isAllAppWindowsEmpty = isAllAppWindowsEmpty && container->IsAppWindowsEmpty(); 560e0dac50fSopenharmony_ci } 561e0dac50fSopenharmony_ci WMError res = WMError::WM_OK; 562e0dac50fSopenharmony_ci std::for_each(containers.begin(), containers.end(), 563e0dac50fSopenharmony_ci [this, isAllAppWindowsEmpty, &res] (sptr<WindowNodeContainer> container) { 564e0dac50fSopenharmony_ci auto restoreFunc = [this](uint32_t windowId, WindowMode mode) { 565e0dac50fSopenharmony_ci auto windowNode = GetWindowNode(windowId); 566e0dac50fSopenharmony_ci if (windowNode == nullptr) { 567e0dac50fSopenharmony_ci return false; 568e0dac50fSopenharmony_ci } 569e0dac50fSopenharmony_ci if (!windowNode->GetWindowToken()) { 570e0dac50fSopenharmony_ci return false; 571e0dac50fSopenharmony_ci } 572e0dac50fSopenharmony_ci auto property = windowNode->GetWindowToken()->GetWindowProperty(); 573e0dac50fSopenharmony_ci if (property == nullptr) { 574e0dac50fSopenharmony_ci return false; 575e0dac50fSopenharmony_ci } 576e0dac50fSopenharmony_ci if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || 577e0dac50fSopenharmony_ci mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { 578e0dac50fSopenharmony_ci property->SetWindowMode(mode); 579e0dac50fSopenharmony_ci // when change mode, need to reset shadow and radius 580e0dac50fSopenharmony_ci windowNode->SetWindowMode(mode); 581e0dac50fSopenharmony_ci WindowSystemEffect::SetWindowEffect(windowNode); 582e0dac50fSopenharmony_ci windowNode->GetWindowToken()->RestoreSplitWindowMode(static_cast<uint32_t>(mode)); 583e0dac50fSopenharmony_ci } 584e0dac50fSopenharmony_ci windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_SHOWN); 585e0dac50fSopenharmony_ci WindowManagerService::GetInstance().AddWindow(property); 586e0dac50fSopenharmony_ci return true; 587e0dac50fSopenharmony_ci }; 588e0dac50fSopenharmony_ci WMError tmpRes = container->ToggleShownStateForAllAppWindows(restoreFunc, isAllAppWindowsEmpty); 589e0dac50fSopenharmony_ci res = (res == WMError::WM_OK) ? tmpRes : res; 590e0dac50fSopenharmony_ci }); 591e0dac50fSopenharmony_ci return res; 592e0dac50fSopenharmony_ci} 593e0dac50fSopenharmony_ci 594e0dac50fSopenharmony_civoid WindowRoot::DestroyLeakStartingWindow() 595e0dac50fSopenharmony_ci{ 596e0dac50fSopenharmony_ci WLOGFD("DestroyLeakStartingWindow is called"); 597e0dac50fSopenharmony_ci std::vector<uint32_t> destroyIds; 598e0dac50fSopenharmony_ci for (auto& iter : windowNodeMap_) { 599e0dac50fSopenharmony_ci if (iter.second->startingWindowShown_ && !iter.second->GetWindowToken()) { 600e0dac50fSopenharmony_ci destroyIds.push_back(iter.second->GetWindowId()); 601e0dac50fSopenharmony_ci } 602e0dac50fSopenharmony_ci } 603e0dac50fSopenharmony_ci for (auto& id : destroyIds) { 604e0dac50fSopenharmony_ci WLOGFD("Id:%{public}u", id); 605e0dac50fSopenharmony_ci DestroyWindow(id, false); 606e0dac50fSopenharmony_ci } 607e0dac50fSopenharmony_ci} 608e0dac50fSopenharmony_ci 609e0dac50fSopenharmony_ciWMError WindowRoot::PostProcessAddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode, 610e0dac50fSopenharmony_ci sptr<WindowNodeContainer>& container) 611e0dac50fSopenharmony_ci{ 612e0dac50fSopenharmony_ci if (!node->currentVisibility_) { 613e0dac50fSopenharmony_ci WLOGW("window is invisible, do not need process"); 614e0dac50fSopenharmony_ci return WMError::WM_DO_NOTHING; 615e0dac50fSopenharmony_ci } 616e0dac50fSopenharmony_ci if (WindowHelper::IsSubWindow(node->GetWindowType())) { 617e0dac50fSopenharmony_ci if (parentNode == nullptr) { 618e0dac50fSopenharmony_ci WLOGFE("window type is invalid"); 619e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_TYPE; 620e0dac50fSopenharmony_ci } 621e0dac50fSopenharmony_ci sptr<WindowNode> parent = nullptr; 622e0dac50fSopenharmony_ci container->RaiseZOrderForAppWindow(parentNode, parent); 623e0dac50fSopenharmony_ci } 624e0dac50fSopenharmony_ci if (node->GetWindowProperty()->GetFocusable()) { 625e0dac50fSopenharmony_ci // when launcher reboot, the focus window should not change with showing a full screen window. 626e0dac50fSopenharmony_ci sptr<WindowNode> focusWin = GetWindowNode(container->GetFocusWindow()); 627e0dac50fSopenharmony_ci if (focusWin == nullptr || 628e0dac50fSopenharmony_ci !(WindowHelper::IsFullScreenWindow(focusWin->GetWindowMode()) && focusWin->zOrder_ > node->zOrder_)) { 629e0dac50fSopenharmony_ci WLOGFI("set focus window on id:%{public}d", node->GetWindowId()); 630e0dac50fSopenharmony_ci container->SetFocusWindow(node->GetWindowId()); 631e0dac50fSopenharmony_ci container->DumpScreenWindowTree(); 632e0dac50fSopenharmony_ci needCheckFocusWindow = true; 633e0dac50fSopenharmony_ci } 634e0dac50fSopenharmony_ci } 635e0dac50fSopenharmony_ci if (!WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 636e0dac50fSopenharmony_ci container->SetActiveWindow(node->GetWindowId(), false); 637e0dac50fSopenharmony_ci } 638e0dac50fSopenharmony_ci 639e0dac50fSopenharmony_ci for (auto& child : node->children_) { 640e0dac50fSopenharmony_ci if (child == nullptr || !child->currentVisibility_) { 641e0dac50fSopenharmony_ci break; 642e0dac50fSopenharmony_ci } 643e0dac50fSopenharmony_ci HandleKeepScreenOn(child->GetWindowId(), child->IsKeepScreenOn()); 644e0dac50fSopenharmony_ci } 645e0dac50fSopenharmony_ci HandleKeepScreenOn(node->GetWindowId(), node->IsKeepScreenOn()); 646e0dac50fSopenharmony_ci WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d", 647e0dac50fSopenharmony_ci node->GetWindowId(), node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()), 648e0dac50fSopenharmony_ci node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType())); 649e0dac50fSopenharmony_ci if (WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) { 650e0dac50fSopenharmony_ci if (node->stateMachine_.IsShowAnimationPlaying()) { 651e0dac50fSopenharmony_ci WLOGFD("[FixOrientation] window is playing show animation, do not update display orientation"); 652e0dac50fSopenharmony_ci return WMError::WM_OK; 653e0dac50fSopenharmony_ci } 654e0dac50fSopenharmony_ci auto topRotatableWindow = container->GetNextRotatableWindow(INVALID_WINDOW_ID); 655e0dac50fSopenharmony_ci if (topRotatableWindow == node) { 656e0dac50fSopenharmony_ci container->SetDisplayOrientationFromWindow(node, true); 657e0dac50fSopenharmony_ci } 658e0dac50fSopenharmony_ci } 659e0dac50fSopenharmony_ci 660e0dac50fSopenharmony_ci if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { 661e0dac50fSopenharmony_ci std::vector<sptr<WindowNode>> windowNodes; 662e0dac50fSopenharmony_ci container->TraverseContainer(windowNodes); 663e0dac50fSopenharmony_ci for (auto& winNode : windowNodes) { 664e0dac50fSopenharmony_ci if (winNode && WindowHelper::IsMainWindow(winNode->GetWindowType()) && 665e0dac50fSopenharmony_ci winNode->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION && 666e0dac50fSopenharmony_ci winNode->GetWindowToken()) { 667e0dac50fSopenharmony_ci winNode->GetWindowToken()->NotifyForegroundInteractiveStatus(false); 668e0dac50fSopenharmony_ci } 669e0dac50fSopenharmony_ci } 670e0dac50fSopenharmony_ci } 671e0dac50fSopenharmony_ci 672e0dac50fSopenharmony_ci return WMError::WM_OK; 673e0dac50fSopenharmony_ci} 674e0dac50fSopenharmony_ci 675e0dac50fSopenharmony_cibool WindowRoot::CheckAddingModeAndSize(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container) 676e0dac50fSopenharmony_ci{ 677e0dac50fSopenharmony_ci if (!WindowHelper::IsMainWindow(node->GetWindowType())) { 678e0dac50fSopenharmony_ci return true; 679e0dac50fSopenharmony_ci } 680e0dac50fSopenharmony_ci // intercept the node which doesn't support floating mode at tile mode 681e0dac50fSopenharmony_ci if (WindowHelper::IsInvalidWindowInTileLayoutMode(node->GetModeSupportInfo(), container->GetCurrentLayoutMode())) { 682e0dac50fSopenharmony_ci WLOGFE("window doesn't support floating mode in tile, windowId: %{public}u", node->GetWindowId()); 683e0dac50fSopenharmony_ci return false; 684e0dac50fSopenharmony_ci } 685e0dac50fSopenharmony_ci // intercept the node that the tile rect can't be applied to 686e0dac50fSopenharmony_ci WMError res = container->IsTileRectSatisfiedWithSizeLimits(node); 687e0dac50fSopenharmony_ci if (res != WMError::WM_OK) { 688e0dac50fSopenharmony_ci return false; 689e0dac50fSopenharmony_ci } 690e0dac50fSopenharmony_ci return true; 691e0dac50fSopenharmony_ci} 692e0dac50fSopenharmony_ci 693e0dac50fSopenharmony_ciRect WindowRoot::GetDisplayRectWithoutSystemBarAreas(const sptr<WindowNode> dstNode) 694e0dac50fSopenharmony_ci{ 695e0dac50fSopenharmony_ci DisplayId displayId = dstNode->GetDisplayId(); 696e0dac50fSopenharmony_ci std::map<WindowType, std::pair<bool, Rect>> systemBarRects; 697e0dac50fSopenharmony_ci for (const auto& it : windowNodeMap_) { 698e0dac50fSopenharmony_ci auto& node = it.second; 699e0dac50fSopenharmony_ci if (node && (node->GetDisplayId() == displayId) && 700e0dac50fSopenharmony_ci WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 701e0dac50fSopenharmony_ci systemBarRects[node->GetWindowType()] = std::make_pair(node->currentVisibility_, node->GetWindowRect()); 702e0dac50fSopenharmony_ci } 703e0dac50fSopenharmony_ci } 704e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 705e0dac50fSopenharmony_ci if (container == nullptr) { 706e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 707e0dac50fSopenharmony_ci return {0, 0, 0, 0}; // empty rect 708e0dac50fSopenharmony_ci } 709e0dac50fSopenharmony_ci auto displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId); 710e0dac50fSopenharmony_ci Rect targetRect = displayRect; 711e0dac50fSopenharmony_ci auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(displayId); 712e0dac50fSopenharmony_ci if (displayInfo && WmsUtils::IsExpectedRotatableWindow(dstNode->GetRequestedOrientation(), 713e0dac50fSopenharmony_ci displayInfo->GetDisplayOrientation(), dstNode->GetWindowMode(), dstNode->GetWindowFlags())) { 714e0dac50fSopenharmony_ci WLOGFD("[FixOrientation] the window is expected rotatable, pre-calculated"); 715e0dac50fSopenharmony_ci targetRect.height_ = displayRect.width_; 716e0dac50fSopenharmony_ci targetRect.width_ = displayRect.height_; 717e0dac50fSopenharmony_ci return targetRect; 718e0dac50fSopenharmony_ci } 719e0dac50fSopenharmony_ci 720e0dac50fSopenharmony_ci bool isStatusShow = true; 721e0dac50fSopenharmony_ci if (systemBarRects.count(WindowType::WINDOW_TYPE_STATUS_BAR)) { 722e0dac50fSopenharmony_ci isStatusShow = systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].first; 723e0dac50fSopenharmony_ci targetRect.posY_ = displayRect.posY_ + static_cast<int32_t>( 724e0dac50fSopenharmony_ci systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_); 725e0dac50fSopenharmony_ci targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_; 726e0dac50fSopenharmony_ci WLOGFD("after status bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]", 727e0dac50fSopenharmony_ci targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_); 728e0dac50fSopenharmony_ci } 729e0dac50fSopenharmony_ci if (systemBarRects.count(WindowType::WINDOW_TYPE_NAVIGATION_BAR)) { 730e0dac50fSopenharmony_ci if (isStatusShow && !(systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].first)) { 731e0dac50fSopenharmony_ci return targetRect; 732e0dac50fSopenharmony_ci } 733e0dac50fSopenharmony_ci targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].second.height_; 734e0dac50fSopenharmony_ci WLOGFD("after navi bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]", 735e0dac50fSopenharmony_ci targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_); 736e0dac50fSopenharmony_ci } 737e0dac50fSopenharmony_ci return targetRect; 738e0dac50fSopenharmony_ci} 739e0dac50fSopenharmony_ci 740e0dac50fSopenharmony_civoid WindowRoot::GetAllAnimationPlayingNodes(std::vector<wptr<WindowNode>>& windowNodes) 741e0dac50fSopenharmony_ci{ 742e0dac50fSopenharmony_ci for (const auto& it : windowNodeMap_) { 743e0dac50fSopenharmony_ci if (it.second) { 744e0dac50fSopenharmony_ci if (!WindowHelper::IsMainWindow(it.second->GetWindowType())) { 745e0dac50fSopenharmony_ci continue; 746e0dac50fSopenharmony_ci } 747e0dac50fSopenharmony_ci WLOGFD("id:%{public}u state:%{public}u", 748e0dac50fSopenharmony_ci it.second->GetWindowId(), static_cast<uint32_t>(it.second->stateMachine_.GetCurrentState())); 749e0dac50fSopenharmony_ci if (it.second->stateMachine_.IsRemoteAnimationPlaying() || 750e0dac50fSopenharmony_ci it.second->stateMachine_.GetAnimationCount() > 0) { 751e0dac50fSopenharmony_ci windowNodes.emplace_back(it.second); 752e0dac50fSopenharmony_ci } 753e0dac50fSopenharmony_ci } 754e0dac50fSopenharmony_ci } 755e0dac50fSopenharmony_ci} 756e0dac50fSopenharmony_ci 757e0dac50fSopenharmony_civoid WindowRoot::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation) 758e0dac50fSopenharmony_ci{ 759e0dac50fSopenharmony_ci if (node == nullptr) { 760e0dac50fSopenharmony_ci WLOGFE("failed, node is nullptr"); 761e0dac50fSopenharmony_ci return; 762e0dac50fSopenharmony_ci } 763e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 764e0dac50fSopenharmony_ci if (container == nullptr) { 765e0dac50fSopenharmony_ci WLOGFE("add window failed, window container could not be found"); 766e0dac50fSopenharmony_ci return; 767e0dac50fSopenharmony_ci } 768e0dac50fSopenharmony_ci 769e0dac50fSopenharmony_ci if (!CheckAddingModeAndSize(node, container)) { // true means stop adding 770e0dac50fSopenharmony_ci WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId()); 771e0dac50fSopenharmony_ci return; 772e0dac50fSopenharmony_ci } 773e0dac50fSopenharmony_ci 774e0dac50fSopenharmony_ci container->LayoutWhenAddWindowNode(node, afterAnimation); 775e0dac50fSopenharmony_ci return; 776e0dac50fSopenharmony_ci} 777e0dac50fSopenharmony_ci 778e0dac50fSopenharmony_ciWMError WindowRoot::BindDialogToParent(sptr<WindowNode>& node, sptr<WindowNode>& parentNode) 779e0dac50fSopenharmony_ci{ 780e0dac50fSopenharmony_ci if (node->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) { 781e0dac50fSopenharmony_ci return WMError::WM_OK; 782e0dac50fSopenharmony_ci } 783e0dac50fSopenharmony_ci sptr<WindowNode> callerNode = FindMainWindowWithToken(node->dialogTargetToken_); 784e0dac50fSopenharmony_ci parentNode = (callerNode != nullptr) ? callerNode : nullptr; 785e0dac50fSopenharmony_ci if (parentNode == nullptr) { 786e0dac50fSopenharmony_ci node->GetWindowToken()->NotifyDestroy(); 787e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_PARAM; 788e0dac50fSopenharmony_ci } 789e0dac50fSopenharmony_ci return WMError::WM_OK; 790e0dac50fSopenharmony_ci} 791e0dac50fSopenharmony_ci 792e0dac50fSopenharmony_ciWMError WindowRoot::AddWindowNode(uint32_t parentId, sptr<WindowNode>& node, bool fromStartingWin) 793e0dac50fSopenharmony_ci{ 794e0dac50fSopenharmony_ci if (node == nullptr) { 795e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 796e0dac50fSopenharmony_ci } 797e0dac50fSopenharmony_ci 798e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 799e0dac50fSopenharmony_ci if (container == nullptr) { 800e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_DISPLAY; 801e0dac50fSopenharmony_ci } 802e0dac50fSopenharmony_ci 803e0dac50fSopenharmony_ci if (!CheckAddingModeAndSize(node, container)) { // true means stop adding 804e0dac50fSopenharmony_ci /* 805e0dac50fSopenharmony_ci * Starting Window has no windowToken, which should be destroied if mode or size is invalid 806e0dac50fSopenharmony_ci */ 807e0dac50fSopenharmony_ci if (node->GetWindowToken() == nullptr) { 808e0dac50fSopenharmony_ci (void)DestroyWindow(node->GetWindowId(), false); 809e0dac50fSopenharmony_ci } 810e0dac50fSopenharmony_ci WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId()); 811e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE; 812e0dac50fSopenharmony_ci } 813e0dac50fSopenharmony_ci 814e0dac50fSopenharmony_ci if (fromStartingWin) { 815e0dac50fSopenharmony_ci if (WindowHelper::IsFullScreenWindow(node->GetWindowMode()) && 816e0dac50fSopenharmony_ci WindowHelper::IsAppWindow(node->GetWindowType()) && !node->isPlayAnimationShow_) { 817e0dac50fSopenharmony_ci WMError res = MinimizeStructuredAppWindowsExceptSelf(node); 818e0dac50fSopenharmony_ci if (res != WMError::WM_OK) { 819e0dac50fSopenharmony_ci WLOGFE("Minimize other structured window failed"); 820e0dac50fSopenharmony_ci MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW); 821e0dac50fSopenharmony_ci return res; 822e0dac50fSopenharmony_ci } 823e0dac50fSopenharmony_ci } 824e0dac50fSopenharmony_ci WMError res = container->ShowStartingWindow(node); 825e0dac50fSopenharmony_ci if (res != WMError::WM_OK) { 826e0dac50fSopenharmony_ci MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW); 827e0dac50fSopenharmony_ci } 828e0dac50fSopenharmony_ci return res; 829e0dac50fSopenharmony_ci } 830e0dac50fSopenharmony_ci if (WindowHelper::IsAppFullOrSplitWindow(node->GetWindowType(), node->GetWindowMode())) { 831e0dac50fSopenharmony_ci container->NotifyDockWindowStateChanged(node, false); 832e0dac50fSopenharmony_ci } 833e0dac50fSopenharmony_ci // limit number of main window 834e0dac50fSopenharmony_ci uint32_t mainWindowNumber = container->GetWindowCountByType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); 835e0dac50fSopenharmony_ci if (mainWindowNumber >= maxAppWindowNumber_ && node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { 836e0dac50fSopenharmony_ci container->MinimizeOldestAppWindow(); 837e0dac50fSopenharmony_ci } 838e0dac50fSopenharmony_ci 839e0dac50fSopenharmony_ci auto parentNode = GetWindowNode(parentId); 840e0dac50fSopenharmony_ci 841e0dac50fSopenharmony_ci WMError res = BindDialogToParent(node, parentNode); 842e0dac50fSopenharmony_ci if (res != WMError::WM_OK) { 843e0dac50fSopenharmony_ci return res; 844e0dac50fSopenharmony_ci } 845e0dac50fSopenharmony_ci 846e0dac50fSopenharmony_ci res = container->AddWindowNode(node, parentNode); 847e0dac50fSopenharmony_ci if (res != WMError::WM_OK) { 848e0dac50fSopenharmony_ci WLOGFE("failed with ret: %{public}u", static_cast<uint32_t>(res)); 849e0dac50fSopenharmony_ci return res; 850e0dac50fSopenharmony_ci } 851e0dac50fSopenharmony_ci return PostProcessAddWindowNode(node, parentNode, container); 852e0dac50fSopenharmony_ci} 853e0dac50fSopenharmony_ci 854e0dac50fSopenharmony_ciWMError WindowRoot::RemoveWindowNode(uint32_t windowId, bool fromAnimation) 855e0dac50fSopenharmony_ci{ 856e0dac50fSopenharmony_ci WLOGFD("begin"); 857e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 858e0dac50fSopenharmony_ci if (node == nullptr) { 859e0dac50fSopenharmony_ci WLOGFE("could not find window"); 860e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 861e0dac50fSopenharmony_ci } 862e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 863e0dac50fSopenharmony_ci if (container == nullptr) { 864e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 865e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_DISPLAY; 866e0dac50fSopenharmony_ci } 867e0dac50fSopenharmony_ci container->DropShowWhenLockedWindowIfNeeded(node); 868e0dac50fSopenharmony_ci UpdateFocusWindowWithWindowRemoved(node, container); 869e0dac50fSopenharmony_ci UpdateActiveWindowWithWindowRemoved(node, container); 870e0dac50fSopenharmony_ci UpdateBrightnessWithWindowRemoved(windowId, container); 871e0dac50fSopenharmony_ci WMError res = container->RemoveWindowNode(node, fromAnimation); 872e0dac50fSopenharmony_ci if (res == WMError::WM_OK) { 873e0dac50fSopenharmony_ci for (auto& child : node->children_) { 874e0dac50fSopenharmony_ci if (child == nullptr) { 875e0dac50fSopenharmony_ci break; 876e0dac50fSopenharmony_ci } 877e0dac50fSopenharmony_ci HandleKeepScreenOn(child->GetWindowId(), false); 878e0dac50fSopenharmony_ci } 879e0dac50fSopenharmony_ci HandleKeepScreenOn(windowId, false); 880e0dac50fSopenharmony_ci } 881e0dac50fSopenharmony_ci 882e0dac50fSopenharmony_ci if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { 883e0dac50fSopenharmony_ci std::vector<sptr<WindowNode>> windowNodes; 884e0dac50fSopenharmony_ci container->TraverseContainer(windowNodes); 885e0dac50fSopenharmony_ci for (auto& winNode : windowNodes) { 886e0dac50fSopenharmony_ci if (winNode && WindowHelper::IsMainWindow(winNode->GetWindowType()) && 887e0dac50fSopenharmony_ci winNode->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION && 888e0dac50fSopenharmony_ci winNode->GetWindowToken()) { 889e0dac50fSopenharmony_ci winNode->GetWindowToken()->NotifyForegroundInteractiveStatus(true); 890e0dac50fSopenharmony_ci } 891e0dac50fSopenharmony_ci } 892e0dac50fSopenharmony_ci } 893e0dac50fSopenharmony_ci 894e0dac50fSopenharmony_ci return res; 895e0dac50fSopenharmony_ci} 896e0dac50fSopenharmony_ci 897e0dac50fSopenharmony_civoid WindowRoot::UpdateDisplayOrientationWhenHideWindow(sptr<WindowNode>& node) 898e0dac50fSopenharmony_ci{ 899e0dac50fSopenharmony_ci if (!FIX_ORIENTATION_ENABLE) { 900e0dac50fSopenharmony_ci return; 901e0dac50fSopenharmony_ci } 902e0dac50fSopenharmony_ci WLOGFD("[FixOrientation] begin"); 903e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 904e0dac50fSopenharmony_ci if (container == nullptr) { 905e0dac50fSopenharmony_ci WLOGFE("[FixOrientation] failed, window container could not be found"); 906e0dac50fSopenharmony_ci return; 907e0dac50fSopenharmony_ci } 908e0dac50fSopenharmony_ci auto nextRotatableWindow = container->GetNextRotatableWindow(node->GetWindowId()); 909e0dac50fSopenharmony_ci if (nextRotatableWindow != nullptr) { 910e0dac50fSopenharmony_ci WLOGFD("[FixOrientation] next rotatable window: %{public}u", nextRotatableWindow->GetWindowId()); 911e0dac50fSopenharmony_ci container->SetDisplayOrientationFromWindow(nextRotatableWindow, false); 912e0dac50fSopenharmony_ci } 913e0dac50fSopenharmony_ci} 914e0dac50fSopenharmony_ci 915e0dac50fSopenharmony_ciWMError WindowRoot::SetGestureNavigationEnabled(bool enable) 916e0dac50fSopenharmony_ci{ 917e0dac50fSopenharmony_ci if (lastGestureNativeEnabled_ == enable) { 918e0dac50fSopenharmony_ci WLOGFW("Do not set gesture navigation too much times as same value and the value is %{public}d", enable); 919e0dac50fSopenharmony_ci return WMError::WM_DO_NOTHING; 920e0dac50fSopenharmony_ci } 921e0dac50fSopenharmony_ci WindowManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable); 922e0dac50fSopenharmony_ci lastGestureNativeEnabled_ = enable; 923e0dac50fSopenharmony_ci WLOGFD("Set gesture navigation enabled succeeded and notify result of %{public}d", enable); 924e0dac50fSopenharmony_ci return WMError::WM_OK; 925e0dac50fSopenharmony_ci} 926e0dac50fSopenharmony_ci 927e0dac50fSopenharmony_ciWMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason) 928e0dac50fSopenharmony_ci{ 929e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 930e0dac50fSopenharmony_ci if (node == nullptr) { 931e0dac50fSopenharmony_ci WLOGFE("could not find window"); 932e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 933e0dac50fSopenharmony_ci } 934e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 935e0dac50fSopenharmony_ci if (container == nullptr) { 936e0dac50fSopenharmony_ci WLOGFE("update window failed, window container could not be found"); 937e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_DISPLAY; 938e0dac50fSopenharmony_ci } 939e0dac50fSopenharmony_ci 940e0dac50fSopenharmony_ci auto ret = container->UpdateWindowNode(node, reason); 941e0dac50fSopenharmony_ci if (ret == WMError::WM_OK && reason == WindowUpdateReason::UPDATE_FLAGS) { 942e0dac50fSopenharmony_ci CheckAndNotifyWaterMarkChangedResult(); 943e0dac50fSopenharmony_ci } 944e0dac50fSopenharmony_ci return ret; 945e0dac50fSopenharmony_ci} 946e0dac50fSopenharmony_ci 947e0dac50fSopenharmony_ciWMError WindowRoot::UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeReason reason) 948e0dac50fSopenharmony_ci{ 949e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 950e0dac50fSopenharmony_ci if (node == nullptr) { 951e0dac50fSopenharmony_ci WLOGFE("could not find window"); 952e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 953e0dac50fSopenharmony_ci } 954e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 955e0dac50fSopenharmony_ci if (container == nullptr) { 956e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 957e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_DISPLAY; 958e0dac50fSopenharmony_ci } 959e0dac50fSopenharmony_ci container->UpdateSizeChangeReason(node, reason); 960e0dac50fSopenharmony_ci return WMError::WM_OK; 961e0dac50fSopenharmony_ci} 962e0dac50fSopenharmony_ci 963e0dac50fSopenharmony_civoid WindowRoot::SetBrightness(uint32_t windowId, float brightness) 964e0dac50fSopenharmony_ci{ 965e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 966e0dac50fSopenharmony_ci if (node == nullptr) { 967e0dac50fSopenharmony_ci WLOGFE("could not find window"); 968e0dac50fSopenharmony_ci return; 969e0dac50fSopenharmony_ci } 970e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 971e0dac50fSopenharmony_ci if (container == nullptr) { 972e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 973e0dac50fSopenharmony_ci return; 974e0dac50fSopenharmony_ci } 975e0dac50fSopenharmony_ci if (!WindowHelper::IsAppWindow(node->GetWindowType())) { 976e0dac50fSopenharmony_ci WLOGW("Only app window support set brightness"); 977e0dac50fSopenharmony_ci return; 978e0dac50fSopenharmony_ci } 979e0dac50fSopenharmony_ci if (windowId != container->GetActiveWindow()) { 980e0dac50fSopenharmony_ci WLOGE("Window is not active with windowId:%{public}d", windowId); 981e0dac50fSopenharmony_ci return; 982e0dac50fSopenharmony_ci } 983e0dac50fSopenharmony_ci if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) <= std::numeric_limits<float>::min()) { 984e0dac50fSopenharmony_ci if (std::fabs(container->GetDisplayBrightness() - brightness) > std::numeric_limits<float>::min()) { 985e0dac50fSopenharmony_ci WLOGFI("value: %{public}f to restore brightness", brightness); 986e0dac50fSopenharmony_ci#ifdef POWERMGR_DISPLAY_MANAGER_ENABLE 987e0dac50fSopenharmony_ci DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness(); 988e0dac50fSopenharmony_ci#endif 989e0dac50fSopenharmony_ci container->SetDisplayBrightness(brightness); 990e0dac50fSopenharmony_ci } 991e0dac50fSopenharmony_ci } else { 992e0dac50fSopenharmony_ci if (std::fabs(container->GetDisplayBrightness() - brightness) > std::numeric_limits<float>::min()) { 993e0dac50fSopenharmony_ci WLOGFI("value: %{public}u", container->ToOverrideBrightness(brightness)); 994e0dac50fSopenharmony_ci#ifdef POWERMGR_DISPLAY_MANAGER_ENABLE 995e0dac50fSopenharmony_ci DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness( 996e0dac50fSopenharmony_ci container->ToOverrideBrightness(brightness)); 997e0dac50fSopenharmony_ci#endif 998e0dac50fSopenharmony_ci container->SetDisplayBrightness(brightness); 999e0dac50fSopenharmony_ci } 1000e0dac50fSopenharmony_ci } 1001e0dac50fSopenharmony_ci container->SetBrightnessWindow(windowId); 1002e0dac50fSopenharmony_ci} 1003e0dac50fSopenharmony_ci 1004e0dac50fSopenharmony_civoid WindowRoot::HandleKeepScreenOn(uint32_t windowId, bool requireLock) 1005e0dac50fSopenharmony_ci{ 1006e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 1007e0dac50fSopenharmony_ci if (node == nullptr) { 1008e0dac50fSopenharmony_ci WLOGFE("could not find window"); 1009e0dac50fSopenharmony_ci return; 1010e0dac50fSopenharmony_ci } 1011e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1012e0dac50fSopenharmony_ci if (container == nullptr) { 1013e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 1014e0dac50fSopenharmony_ci return; 1015e0dac50fSopenharmony_ci } 1016e0dac50fSopenharmony_ci container->HandleKeepScreenOn(node, requireLock); 1017e0dac50fSopenharmony_ci} 1018e0dac50fSopenharmony_ci 1019e0dac50fSopenharmony_civoid WindowRoot::UpdateFocusableProperty(uint32_t windowId) 1020e0dac50fSopenharmony_ci{ 1021e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 1022e0dac50fSopenharmony_ci if (node == nullptr) { 1023e0dac50fSopenharmony_ci WLOGFE("could not find window"); 1024e0dac50fSopenharmony_ci return; 1025e0dac50fSopenharmony_ci } 1026e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1027e0dac50fSopenharmony_ci if (container == nullptr) { 1028e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 1029e0dac50fSopenharmony_ci return; 1030e0dac50fSopenharmony_ci } 1031e0dac50fSopenharmony_ci 1032e0dac50fSopenharmony_ci if (windowId != container->GetFocusWindow() || node->GetWindowProperty()->GetFocusable()) { 1033e0dac50fSopenharmony_ci return; 1034e0dac50fSopenharmony_ci } 1035e0dac50fSopenharmony_ci auto nextFocusableWindow = container->GetNextFocusableWindow(windowId); 1036e0dac50fSopenharmony_ci if (nextFocusableWindow != nullptr) { 1037e0dac50fSopenharmony_ci WLOGI("Next focus window id: %{public}u", nextFocusableWindow->GetWindowId()); 1038e0dac50fSopenharmony_ci container->SetFocusWindow(nextFocusableWindow->GetWindowId()); 1039e0dac50fSopenharmony_ci } 1040e0dac50fSopenharmony_ci} 1041e0dac50fSopenharmony_ci 1042e0dac50fSopenharmony_ciWMError WindowRoot::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode) 1043e0dac50fSopenharmony_ci{ 1044e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1045e0dac50fSopenharmony_ci if (container == nullptr) { 1046e0dac50fSopenharmony_ci WLOGFE("failed, window container could not be found"); 1047e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_DISPLAY; 1048e0dac50fSopenharmony_ci } 1049e0dac50fSopenharmony_ci WindowMode curWinMode = node->GetWindowMode(); 1050e0dac50fSopenharmony_ci if (curWinMode == dstMode) { 1051e0dac50fSopenharmony_ci return WMError::WM_OK; 1052e0dac50fSopenharmony_ci } 1053e0dac50fSopenharmony_ci auto res = container->SetWindowMode(node, dstMode); 1054e0dac50fSopenharmony_ci auto nextRotatableWindow = container->GetNextRotatableWindow(0); 1055e0dac50fSopenharmony_ci if (nextRotatableWindow != nullptr) { 1056e0dac50fSopenharmony_ci DisplayManagerServiceInner::GetInstance().SetOrientationFromWindow(nextRotatableWindow->GetDisplayId(), 1057e0dac50fSopenharmony_ci nextRotatableWindow->GetRequestedOrientation()); 1058e0dac50fSopenharmony_ci } 1059e0dac50fSopenharmony_ci return res; 1060e0dac50fSopenharmony_ci} 1061e0dac50fSopenharmony_ci 1062e0dac50fSopenharmony_ciWMError WindowRoot::DestroyWindowSelf(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container) 1063e0dac50fSopenharmony_ci{ 1064e0dac50fSopenharmony_ci for (auto& child : node->children_) { 1065e0dac50fSopenharmony_ci if (child == nullptr) { 1066e0dac50fSopenharmony_ci continue; 1067e0dac50fSopenharmony_ci } 1068e0dac50fSopenharmony_ci child->parent_ = nullptr; 1069e0dac50fSopenharmony_ci if ((child->GetWindowToken() != nullptr) && (child->abilityToken_ != node->abilityToken_) && 1070e0dac50fSopenharmony_ci (child->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) { 1071e0dac50fSopenharmony_ci child->GetWindowToken()->NotifyDestroy(); 1072e0dac50fSopenharmony_ci } 1073e0dac50fSopenharmony_ci } 1074e0dac50fSopenharmony_ci std::vector<uint32_t> windowIds; 1075e0dac50fSopenharmony_ci WMError res = container->DestroyWindowNode(node, windowIds); 1076e0dac50fSopenharmony_ci if (res != WMError::WM_OK) { 1077e0dac50fSopenharmony_ci WLOGFE("RemoveWindowNode failed"); 1078e0dac50fSopenharmony_ci } 1079e0dac50fSopenharmony_ci return DestroyWindowInner(node); 1080e0dac50fSopenharmony_ci} 1081e0dac50fSopenharmony_ci 1082e0dac50fSopenharmony_ciWMError WindowRoot::DestroyWindowWithChild(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container) 1083e0dac50fSopenharmony_ci{ 1084e0dac50fSopenharmony_ci auto token = node->abilityToken_; 1085e0dac50fSopenharmony_ci std::vector<uint32_t> windowIds; 1086e0dac50fSopenharmony_ci WMError res = container->DestroyWindowNode(node, windowIds); 1087e0dac50fSopenharmony_ci for (auto id : windowIds) { 1088e0dac50fSopenharmony_ci node = GetWindowNode(id); 1089e0dac50fSopenharmony_ci if (!node) { 1090e0dac50fSopenharmony_ci continue; 1091e0dac50fSopenharmony_ci } 1092e0dac50fSopenharmony_ci HandleKeepScreenOn(id, false); 1093e0dac50fSopenharmony_ci DestroyWindowInner(node); 1094e0dac50fSopenharmony_ci if ((node->GetWindowToken() != nullptr) && (node->abilityToken_ != token) && 1095e0dac50fSopenharmony_ci (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) { 1096e0dac50fSopenharmony_ci node->GetWindowToken()->NotifyDestroy(); 1097e0dac50fSopenharmony_ci } 1098e0dac50fSopenharmony_ci } 1099e0dac50fSopenharmony_ci return res; 1100e0dac50fSopenharmony_ci} 1101e0dac50fSopenharmony_ci 1102e0dac50fSopenharmony_ciWMError WindowRoot::DestroyWindow(uint32_t windowId, bool onlySelf) 1103e0dac50fSopenharmony_ci{ 1104e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 1105e0dac50fSopenharmony_ci if (node == nullptr) { 1106e0dac50fSopenharmony_ci WLOGFE("failed, because window node is not exist."); 1107e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1108e0dac50fSopenharmony_ci } 1109e0dac50fSopenharmony_ci WLOGI("windowId %{public}u, onlySelf:%{public}u.", windowId, onlySelf); 1110e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1111e0dac50fSopenharmony_ci if (!container) { 1112e0dac50fSopenharmony_ci WLOGFW("failed, window container could not be found"); 1113e0dac50fSopenharmony_ci return DestroyWindowInner(node); 1114e0dac50fSopenharmony_ci } 1115e0dac50fSopenharmony_ci 1116e0dac50fSopenharmony_ci UpdateFocusWindowWithWindowRemoved(node, container); 1117e0dac50fSopenharmony_ci UpdateActiveWindowWithWindowRemoved(node, container); 1118e0dac50fSopenharmony_ci UpdateBrightnessWithWindowRemoved(windowId, container); 1119e0dac50fSopenharmony_ci HandleKeepScreenOn(windowId, false); 1120e0dac50fSopenharmony_ci if (onlySelf) { 1121e0dac50fSopenharmony_ci return DestroyWindowSelf(node, container); 1122e0dac50fSopenharmony_ci } else { 1123e0dac50fSopenharmony_ci return DestroyWindowWithChild(node, container); 1124e0dac50fSopenharmony_ci } 1125e0dac50fSopenharmony_ci} 1126e0dac50fSopenharmony_ci 1127e0dac50fSopenharmony_ciWMError WindowRoot::DestroyWindowInner(sptr<WindowNode>& node) 1128e0dac50fSopenharmony_ci{ 1129e0dac50fSopenharmony_ci if (node == nullptr) { 1130e0dac50fSopenharmony_ci WLOGFE("window has been destroyed"); 1131e0dac50fSopenharmony_ci return WMError::WM_ERROR_DESTROYED_OBJECT; 1132e0dac50fSopenharmony_ci } 1133e0dac50fSopenharmony_ci 1134e0dac50fSopenharmony_ci if (node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) { 1135e0dac50fSopenharmony_ci std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos; 1136e0dac50fSopenharmony_ci node->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION); 1137e0dac50fSopenharmony_ci windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), 1138e0dac50fSopenharmony_ci node->GetCallingUid(), node->GetVisibilityState(), node->GetWindowType())); 1139e0dac50fSopenharmony_ci WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, visibilityState:%{public}d", 1140e0dac50fSopenharmony_ci node->GetWindowId(), node->GetVisibilityState()); 1141e0dac50fSopenharmony_ci WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos); 1142e0dac50fSopenharmony_ci 1143e0dac50fSopenharmony_ci CheckAndNotifyWaterMarkChangedResult(); 1144e0dac50fSopenharmony_ci } 1145e0dac50fSopenharmony_ci 1146e0dac50fSopenharmony_ci auto cmpFunc = [node](const std::map<uint64_t, sptr<WindowNode>>::value_type& pair) { 1147e0dac50fSopenharmony_ci if (pair.second == nullptr) { 1148e0dac50fSopenharmony_ci return false; 1149e0dac50fSopenharmony_ci } 1150e0dac50fSopenharmony_ci if (pair.second->GetWindowId() == node->GetWindowId()) { 1151e0dac50fSopenharmony_ci return true; 1152e0dac50fSopenharmony_ci } 1153e0dac50fSopenharmony_ci return false; 1154e0dac50fSopenharmony_ci }; 1155e0dac50fSopenharmony_ci auto iter = std::find_if(surfaceIdWindowNodeMap_.begin(), surfaceIdWindowNodeMap_.end(), cmpFunc); 1156e0dac50fSopenharmony_ci if (iter != surfaceIdWindowNodeMap_.end()) { 1157e0dac50fSopenharmony_ci surfaceIdWindowNodeMap_.erase(iter); 1158e0dac50fSopenharmony_ci } 1159e0dac50fSopenharmony_ci 1160e0dac50fSopenharmony_ci sptr<IWindow> window = node->GetWindowToken(); 1161e0dac50fSopenharmony_ci if ((window != nullptr) && (window->AsObject() != nullptr)) { 1162e0dac50fSopenharmony_ci if (windowIdMap_.count(window->AsObject()) == 0) { 1163e0dac50fSopenharmony_ci WLOGE("window remote object has been destroyed"); 1164e0dac50fSopenharmony_ci return WMError::WM_ERROR_DESTROYED_OBJECT; 1165e0dac50fSopenharmony_ci } 1166e0dac50fSopenharmony_ci 1167e0dac50fSopenharmony_ci if (window->AsObject() != nullptr) { 1168e0dac50fSopenharmony_ci window->AsObject()->RemoveDeathRecipient(windowDeath_); 1169e0dac50fSopenharmony_ci } 1170e0dac50fSopenharmony_ci windowIdMap_.erase(window->AsObject()); 1171e0dac50fSopenharmony_ci } 1172e0dac50fSopenharmony_ci windowNodeMap_.erase(node->GetWindowId()); 1173e0dac50fSopenharmony_ci WLOGI("destroy window use_count:%{public}d", node->GetSptrRefCount()); 1174e0dac50fSopenharmony_ci return WMError::WM_OK; 1175e0dac50fSopenharmony_ci} 1176e0dac50fSopenharmony_ci 1177e0dac50fSopenharmony_civoid WindowRoot::UpdateFocusWindowWithWindowRemoved(const sptr<WindowNode>& node, 1178e0dac50fSopenharmony_ci const sptr<WindowNodeContainer>& container) const 1179e0dac50fSopenharmony_ci{ 1180e0dac50fSopenharmony_ci if (node == nullptr || container == nullptr) { 1181e0dac50fSopenharmony_ci WLOGFE("window is invalid"); 1182e0dac50fSopenharmony_ci return; 1183e0dac50fSopenharmony_ci } 1184e0dac50fSopenharmony_ci if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { 1185e0dac50fSopenharmony_ci WLOGI("window is divider, do not get next focus window."); 1186e0dac50fSopenharmony_ci return; 1187e0dac50fSopenharmony_ci } 1188e0dac50fSopenharmony_ci uint32_t windowId = node->GetWindowId(); 1189e0dac50fSopenharmony_ci uint32_t focusedWindowId = container->GetFocusWindow(); 1190e0dac50fSopenharmony_ci WLOGFI("current window: %{public}u, focus window: %{public}u", windowId, focusedWindowId); 1191e0dac50fSopenharmony_ci container->DumpScreenWindowTree(); 1192e0dac50fSopenharmony_ci if (windowId != focusedWindowId) { 1193e0dac50fSopenharmony_ci auto iter = std::find_if(node->children_.begin(), node->children_.end(), 1194e0dac50fSopenharmony_ci [focusedWindowId](sptr<WindowNode> node) { 1195e0dac50fSopenharmony_ci return node->GetWindowId() == focusedWindowId; 1196e0dac50fSopenharmony_ci }); 1197e0dac50fSopenharmony_ci if (iter == node->children_.end()) { 1198e0dac50fSopenharmony_ci return; 1199e0dac50fSopenharmony_ci } 1200e0dac50fSopenharmony_ci } 1201e0dac50fSopenharmony_ci if (!node->children_.empty()) { 1202e0dac50fSopenharmony_ci auto firstChild = node->children_.front(); 1203e0dac50fSopenharmony_ci if (firstChild->priority_ < 0) { 1204e0dac50fSopenharmony_ci windowId = firstChild->GetWindowId(); 1205e0dac50fSopenharmony_ci } 1206e0dac50fSopenharmony_ci } 1207e0dac50fSopenharmony_ci 1208e0dac50fSopenharmony_ci auto nextFocusableWindow = container->GetNextFocusableWindow(windowId); 1209e0dac50fSopenharmony_ci if (nextFocusableWindow != nullptr) { 1210e0dac50fSopenharmony_ci WLOGFI("adjust focus window, next focus window id: %{public}u", nextFocusableWindow->GetWindowId()); 1211e0dac50fSopenharmony_ci container->SetFocusWindow(nextFocusableWindow->GetWindowId()); 1212e0dac50fSopenharmony_ci } else { 1213e0dac50fSopenharmony_ci WLOGFW("next focus window is invalid"); 1214e0dac50fSopenharmony_ci container->SetFocusWindow(INVALID_WINDOW_ID); 1215e0dac50fSopenharmony_ci } 1216e0dac50fSopenharmony_ci} 1217e0dac50fSopenharmony_ci 1218e0dac50fSopenharmony_civoid WindowRoot::UpdateActiveWindowWithWindowRemoved(const sptr<WindowNode>& node, 1219e0dac50fSopenharmony_ci const sptr<WindowNodeContainer>& container) const 1220e0dac50fSopenharmony_ci{ 1221e0dac50fSopenharmony_ci if (node == nullptr || container == nullptr) { 1222e0dac50fSopenharmony_ci WLOGFE("window is invalid"); 1223e0dac50fSopenharmony_ci return; 1224e0dac50fSopenharmony_ci } 1225e0dac50fSopenharmony_ci uint32_t windowId = node->GetWindowId(); 1226e0dac50fSopenharmony_ci uint32_t activeWindowId = container->GetActiveWindow(); 1227e0dac50fSopenharmony_ci WLOGFD("current window: %{public}u, active window: %{public}u", windowId, activeWindowId); 1228e0dac50fSopenharmony_ci if (windowId != activeWindowId) { 1229e0dac50fSopenharmony_ci auto iter = std::find_if(node->children_.begin(), node->children_.end(), 1230e0dac50fSopenharmony_ci [activeWindowId](sptr<WindowNode> node) { 1231e0dac50fSopenharmony_ci return node->GetWindowId() == activeWindowId; 1232e0dac50fSopenharmony_ci }); 1233e0dac50fSopenharmony_ci if (iter == node->children_.end()) { 1234e0dac50fSopenharmony_ci return; 1235e0dac50fSopenharmony_ci } 1236e0dac50fSopenharmony_ci } 1237e0dac50fSopenharmony_ci if (!node->children_.empty()) { 1238e0dac50fSopenharmony_ci auto firstChild = node->children_.front(); 1239e0dac50fSopenharmony_ci if (firstChild->priority_ < 0) { 1240e0dac50fSopenharmony_ci windowId = firstChild->GetWindowId(); 1241e0dac50fSopenharmony_ci } 1242e0dac50fSopenharmony_ci } 1243e0dac50fSopenharmony_ci 1244e0dac50fSopenharmony_ci auto nextActiveWindow = container->GetNextActiveWindow(windowId); 1245e0dac50fSopenharmony_ci if (nextActiveWindow != nullptr) { 1246e0dac50fSopenharmony_ci WLOGI("Next active window id: %{public}u", nextActiveWindow->GetWindowId()); 1247e0dac50fSopenharmony_ci container->SetActiveWindow(nextActiveWindow->GetWindowId(), true); 1248e0dac50fSopenharmony_ci } 1249e0dac50fSopenharmony_ci} 1250e0dac50fSopenharmony_ci 1251e0dac50fSopenharmony_civoid WindowRoot::UpdateBrightnessWithWindowRemoved(uint32_t windowId, const sptr<WindowNodeContainer>& container) const 1252e0dac50fSopenharmony_ci{ 1253e0dac50fSopenharmony_ci if (container == nullptr) { 1254e0dac50fSopenharmony_ci WLOGFE("window container could not be found"); 1255e0dac50fSopenharmony_ci return; 1256e0dac50fSopenharmony_ci } 1257e0dac50fSopenharmony_ci if (windowId == container->GetBrightnessWindow()) { 1258e0dac50fSopenharmony_ci WLOGFD("winId: %{public}u", container->GetActiveWindow()); 1259e0dac50fSopenharmony_ci container->UpdateBrightness(container->GetActiveWindow(), true); 1260e0dac50fSopenharmony_ci } 1261e0dac50fSopenharmony_ci} 1262e0dac50fSopenharmony_ci 1263e0dac50fSopenharmony_cibool WindowRoot::IsVerticalDisplay(sptr<WindowNode>& node) const 1264e0dac50fSopenharmony_ci{ 1265e0dac50fSopenharmony_ci auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1266e0dac50fSopenharmony_ci if (container == nullptr) { 1267e0dac50fSopenharmony_ci WLOGFE("get display direction failed, window container could not be found"); 1268e0dac50fSopenharmony_ci return false; 1269e0dac50fSopenharmony_ci } 1270e0dac50fSopenharmony_ci return container->IsVerticalDisplay(node->GetDisplayId()); 1271e0dac50fSopenharmony_ci} 1272e0dac50fSopenharmony_ci 1273e0dac50fSopenharmony_ciWMError WindowRoot::RequestFocus(uint32_t windowId) 1274e0dac50fSopenharmony_ci{ 1275e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 1276e0dac50fSopenharmony_ci if (node == nullptr) { 1277e0dac50fSopenharmony_ci WLOGFE("could not find window"); 1278e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1279e0dac50fSopenharmony_ci } 1280e0dac50fSopenharmony_ci if (!node->currentVisibility_) { 1281e0dac50fSopenharmony_ci WLOGFE("could not request focus before it does not be shown"); 1282e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_OPERATION; 1283e0dac50fSopenharmony_ci } 1284e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1285e0dac50fSopenharmony_ci if (container == nullptr) { 1286e0dac50fSopenharmony_ci WLOGFE("window container could not be found"); 1287e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1288e0dac50fSopenharmony_ci } 1289e0dac50fSopenharmony_ci if (node->GetWindowProperty()->GetFocusable()) { 1290e0dac50fSopenharmony_ci return container->SetFocusWindow(windowId); 1291e0dac50fSopenharmony_ci } 1292e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_OPERATION; 1293e0dac50fSopenharmony_ci} 1294e0dac50fSopenharmony_ci 1295e0dac50fSopenharmony_ciWMError WindowRoot::RequestActiveWindow(uint32_t windowId) 1296e0dac50fSopenharmony_ci{ 1297e0dac50fSopenharmony_ci auto node = GetWindowNode(windowId); 1298e0dac50fSopenharmony_ci if (node == nullptr) { 1299e0dac50fSopenharmony_ci WLOGFE("could not find window"); 1300e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1301e0dac50fSopenharmony_ci } 1302e0dac50fSopenharmony_ci if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) { 1303e0dac50fSopenharmony_ci WLOGFE("window could not be active window"); 1304e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_TYPE; 1305e0dac50fSopenharmony_ci } 1306e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1307e0dac50fSopenharmony_ci if (container == nullptr) { 1308e0dac50fSopenharmony_ci WLOGFE("window container could not be found"); 1309e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1310e0dac50fSopenharmony_ci } 1311e0dac50fSopenharmony_ci auto res = container->SetActiveWindow(windowId, false); 1312e0dac50fSopenharmony_ci WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d", 1313e0dac50fSopenharmony_ci windowId, node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()), 1314e0dac50fSopenharmony_ci node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType())); 1315e0dac50fSopenharmony_ci return res; 1316e0dac50fSopenharmony_ci} 1317e0dac50fSopenharmony_ci 1318e0dac50fSopenharmony_civoid WindowRoot::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason) 1319e0dac50fSopenharmony_ci{ 1320e0dac50fSopenharmony_ci for (auto& elem : windowNodeContainerMap_) { 1321e0dac50fSopenharmony_ci if (elem.second == nullptr) { 1322e0dac50fSopenharmony_ci continue; 1323e0dac50fSopenharmony_ci } 1324e0dac50fSopenharmony_ci elem.second->ProcessWindowStateChange(state, reason); 1325e0dac50fSopenharmony_ci } 1326e0dac50fSopenharmony_ci} 1327e0dac50fSopenharmony_ci 1328e0dac50fSopenharmony_civoid WindowRoot::NotifySystemBarTints() 1329e0dac50fSopenharmony_ci{ 1330e0dac50fSopenharmony_ci WLOGFD("notify current system bar tints"); 1331e0dac50fSopenharmony_ci for (auto& it : windowNodeContainerMap_) { 1332e0dac50fSopenharmony_ci if (it.second != nullptr) { 1333e0dac50fSopenharmony_ci it.second->NotifySystemBarTints(displayIdMap_[it.first]); 1334e0dac50fSopenharmony_ci } 1335e0dac50fSopenharmony_ci } 1336e0dac50fSopenharmony_ci} 1337e0dac50fSopenharmony_ci 1338e0dac50fSopenharmony_ciWMError WindowRoot::NotifyDesktopUnfrozen() 1339e0dac50fSopenharmony_ci{ 1340e0dac50fSopenharmony_ci WLOGFD("notify desktop unfrozen"); 1341e0dac50fSopenharmony_ci for (const auto& it : windowNodeMap_) { 1342e0dac50fSopenharmony_ci auto& node = it.second; 1343e0dac50fSopenharmony_ci // just need notify desktop unfrozen when desktop shown 1344e0dac50fSopenharmony_ci // since unfrozen will change window state to shown 1345e0dac50fSopenharmony_ci if (node && (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) 1346e0dac50fSopenharmony_ci && (node->GetWindowToken()) && node->currentVisibility_) { 1347e0dac50fSopenharmony_ci node->GetWindowToken()->UpdateWindowState(WindowState::STATE_UNFROZEN); 1348e0dac50fSopenharmony_ci return WMError::WM_OK; 1349e0dac50fSopenharmony_ci } 1350e0dac50fSopenharmony_ci } 1351e0dac50fSopenharmony_ci WLOGFD("notify desktop unfrozen failed, maybe no window node or windowToken!"); 1352e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_OPERATION; 1353e0dac50fSopenharmony_ci} 1354e0dac50fSopenharmony_ci 1355e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::FindWallpaperWindow() 1356e0dac50fSopenharmony_ci{ 1357e0dac50fSopenharmony_ci auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), 1358e0dac50fSopenharmony_ci [](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) { 1359e0dac50fSopenharmony_ci return pair.second->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER; 1360e0dac50fSopenharmony_ci }); 1361e0dac50fSopenharmony_ci if (iter == windowNodeMap_.end()) { 1362e0dac50fSopenharmony_ci WLOGI("cannot find windowNode"); 1363e0dac50fSopenharmony_ci return nullptr; 1364e0dac50fSopenharmony_ci } 1365e0dac50fSopenharmony_ci return iter->second; 1366e0dac50fSopenharmony_ci} 1367e0dac50fSopenharmony_ci 1368e0dac50fSopenharmony_ciWMError WindowRoot::RaiseZOrderForAppWindow(sptr<WindowNode>& node) 1369e0dac50fSopenharmony_ci{ 1370e0dac50fSopenharmony_ci if (node == nullptr) { 1371e0dac50fSopenharmony_ci WLOGFW("add window failed, node is nullptr"); 1372e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1373e0dac50fSopenharmony_ci } 1374e0dac50fSopenharmony_ci if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { 1375e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1376e0dac50fSopenharmony_ci if (container == nullptr) { 1377e0dac50fSopenharmony_ci WLOGFW("window container could not be found"); 1378e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1379e0dac50fSopenharmony_ci } 1380e0dac50fSopenharmony_ci container->RaiseSplitRelatedWindowToTop(node); 1381e0dac50fSopenharmony_ci return WMError::WM_OK; 1382e0dac50fSopenharmony_ci } 1383e0dac50fSopenharmony_ci if (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) { 1384e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1385e0dac50fSopenharmony_ci if (container == nullptr) { 1386e0dac50fSopenharmony_ci WLOGFW("window container could not be found"); 1387e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1388e0dac50fSopenharmony_ci } 1389e0dac50fSopenharmony_ci sptr<WindowNode> parentNode = FindMainWindowWithToken(node->dialogTargetToken_); 1390e0dac50fSopenharmony_ci if (parentNode != nullptr) { 1391e0dac50fSopenharmony_ci container->RaiseZOrderForAppWindow(node, parentNode); 1392e0dac50fSopenharmony_ci } 1393e0dac50fSopenharmony_ci return WMError::WM_OK; 1394e0dac50fSopenharmony_ci } 1395e0dac50fSopenharmony_ci 1396e0dac50fSopenharmony_ci if (!WindowHelper::IsAppWindow(node->GetWindowType())) { 1397e0dac50fSopenharmony_ci WLOGFW("window is not app window"); 1398e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_TYPE; 1399e0dac50fSopenharmony_ci } 1400e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1401e0dac50fSopenharmony_ci if (container == nullptr) { 1402e0dac50fSopenharmony_ci WLOGFW("add window failed, window container could not be found"); 1403e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1404e0dac50fSopenharmony_ci } 1405e0dac50fSopenharmony_ci 1406e0dac50fSopenharmony_ci auto parentNode = GetWindowNode(node->GetParentId()); 1407e0dac50fSopenharmony_ci return container->RaiseZOrderForAppWindow(node, parentNode); 1408e0dac50fSopenharmony_ci} 1409e0dac50fSopenharmony_ci 1410e0dac50fSopenharmony_civoid WindowRoot::DispatchKeyEvent(sptr<WindowNode> node, std::shared_ptr<MMI::KeyEvent> event) 1411e0dac50fSopenharmony_ci{ 1412e0dac50fSopenharmony_ci sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1413e0dac50fSopenharmony_ci if (container == nullptr) { 1414e0dac50fSopenharmony_ci WLOGFW("window container could not be found"); 1415e0dac50fSopenharmony_ci return; 1416e0dac50fSopenharmony_ci } 1417e0dac50fSopenharmony_ci std::vector<sptr<WindowNode>> windowNodes; 1418e0dac50fSopenharmony_ci container->TraverseContainer(windowNodes); 1419e0dac50fSopenharmony_ci auto iter = std::find(windowNodes.begin(), windowNodes.end(), node); 1420e0dac50fSopenharmony_ci if (iter == windowNodes.end()) { 1421e0dac50fSopenharmony_ci WLOGFE("Cannot find node"); 1422e0dac50fSopenharmony_ci return; 1423e0dac50fSopenharmony_ci } 1424e0dac50fSopenharmony_ci for (++iter; iter != windowNodes.end(); ++iter) { 1425e0dac50fSopenharmony_ci if (*iter == nullptr) { 1426e0dac50fSopenharmony_ci WLOGFE("Node is null"); 1427e0dac50fSopenharmony_ci continue; 1428e0dac50fSopenharmony_ci } 1429e0dac50fSopenharmony_ci if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) { 1430e0dac50fSopenharmony_ci WLOGFI("Skip component window: %{public}u", (*iter)->GetWindowId()); 1431e0dac50fSopenharmony_ci continue; 1432e0dac50fSopenharmony_ci } 1433e0dac50fSopenharmony_ci if (WindowHelper::IsAppWindow((*iter)->GetWindowType())) { 1434e0dac50fSopenharmony_ci WLOGFI("App window: %{public}u", (*iter)->GetWindowId()); 1435e0dac50fSopenharmony_ci if ((*iter)->GetWindowToken()) { 1436e0dac50fSopenharmony_ci (*iter)->GetWindowToken()->ConsumeKeyEvent(event); 1437e0dac50fSopenharmony_ci } 1438e0dac50fSopenharmony_ci break; 1439e0dac50fSopenharmony_ci } 1440e0dac50fSopenharmony_ci WLOGFI("Unexpected window: %{public}u", (*iter)->GetWindowId()); 1441e0dac50fSopenharmony_ci break; 1442e0dac50fSopenharmony_ci } 1443e0dac50fSopenharmony_ci} 1444e0dac50fSopenharmony_ci 1445e0dac50fSopenharmony_ciuint32_t WindowRoot::GetWindowIdByObject(const sptr<IRemoteObject>& remoteObject) 1446e0dac50fSopenharmony_ci{ 1447e0dac50fSopenharmony_ci auto iter = windowIdMap_.find(remoteObject); 1448e0dac50fSopenharmony_ci return iter == std::end(windowIdMap_) ? INVALID_WINDOW_ID : iter->second; 1449e0dac50fSopenharmony_ci} 1450e0dac50fSopenharmony_ci 1451e0dac50fSopenharmony_civoid WindowRoot::OnRemoteDied(const sptr<IRemoteObject>& remoteObject) 1452e0dac50fSopenharmony_ci{ 1453e0dac50fSopenharmony_ci callback_(Event::REMOTE_DIED, remoteObject); 1454e0dac50fSopenharmony_ci} 1455e0dac50fSopenharmony_ci 1456e0dac50fSopenharmony_ciWMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) 1457e0dac50fSopenharmony_ci{ 1458e0dac50fSopenharmony_ci if (windowNodeMap_.find(mainWinId) == windowNodeMap_.end()) { 1459e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_WINDOW; 1460e0dac50fSopenharmony_ci } 1461e0dac50fSopenharmony_ci auto node = windowNodeMap_[mainWinId]; 1462e0dac50fSopenharmony_ci if (!node->currentVisibility_) { 1463e0dac50fSopenharmony_ci return WMError::WM_ERROR_INVALID_WINDOW; 1464e0dac50fSopenharmony_ci } 1465e0dac50fSopenharmony_ci if (!node->children_.empty()) { 1466e0dac50fSopenharmony_ci auto iter = node->children_.rbegin(); 1467e0dac50fSopenharmony_ci if (WindowHelper::IsSubWindow((*iter)->GetWindowType()) || 1468e0dac50fSopenharmony_ci WindowHelper::IsSystemSubWindow((*iter)->GetWindowType())) { 1469e0dac50fSopenharmony_ci topWinId = (*iter)->GetWindowId(); 1470e0dac50fSopenharmony_ci return WMError::WM_OK; 1471e0dac50fSopenharmony_ci } 1472e0dac50fSopenharmony_ci } 1473e0dac50fSopenharmony_ci topWinId = mainWinId; 1474e0dac50fSopenharmony_ci return WMError::WM_OK; 1475e0dac50fSopenharmony_ci} 1476e0dac50fSopenharmony_ci 1477e0dac50fSopenharmony_ciWMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) 1478e0dac50fSopenharmony_ci{ 1479e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 1480e0dac50fSopenharmony_ci if (container == nullptr) { 1481e0dac50fSopenharmony_ci WLOGFE("window container could not be found"); 1482e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1483e0dac50fSopenharmony_ci } 1484e0dac50fSopenharmony_ci WMError ret = container->SwitchLayoutPolicy(mode, displayId, true); 1485e0dac50fSopenharmony_ci if (ret != WMError::WM_OK) { 1486e0dac50fSopenharmony_ci WLOGFW("set window layout mode failed displayId: %{public}" PRIu64 ", ret: %{public}d", displayId, ret); 1487e0dac50fSopenharmony_ci } 1488e0dac50fSopenharmony_ci return ret; 1489e0dac50fSopenharmony_ci} 1490e0dac50fSopenharmony_ci 1491e0dac50fSopenharmony_cistd::vector<DisplayId> WindowRoot::GetAllDisplayIds() const 1492e0dac50fSopenharmony_ci{ 1493e0dac50fSopenharmony_ci std::vector<DisplayId> displayIds; 1494e0dac50fSopenharmony_ci for (auto& it : windowNodeContainerMap_) { 1495e0dac50fSopenharmony_ci if (!it.second) { 1496e0dac50fSopenharmony_ci return {}; 1497e0dac50fSopenharmony_ci } 1498e0dac50fSopenharmony_ci std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[it.first]; 1499e0dac50fSopenharmony_ci for (auto displayId : displayIdVec) { 1500e0dac50fSopenharmony_ci displayIds.push_back(displayId); 1501e0dac50fSopenharmony_ci } 1502e0dac50fSopenharmony_ci } 1503e0dac50fSopenharmony_ci return displayIds; 1504e0dac50fSopenharmony_ci} 1505e0dac50fSopenharmony_ci 1506e0dac50fSopenharmony_cistd::string WindowRoot::GenAllWindowsLogInfo() const 1507e0dac50fSopenharmony_ci{ 1508e0dac50fSopenharmony_ci std::ostringstream os; 1509e0dac50fSopenharmony_ci WindowNodeOperationFunc func = [&os](sptr<WindowNode> node) { 1510e0dac50fSopenharmony_ci if (node == nullptr) { 1511e0dac50fSopenharmony_ci WLOGE("WindowNode is nullptr"); 1512e0dac50fSopenharmony_ci return false; 1513e0dac50fSopenharmony_ci } 1514e0dac50fSopenharmony_ci os<<"window_name:"<<node->GetWindowName()<<",id:"<<node->GetWindowId()<< 1515e0dac50fSopenharmony_ci ",focusable:"<<node->GetWindowProperty()->GetFocusable()<<";"; 1516e0dac50fSopenharmony_ci return false; 1517e0dac50fSopenharmony_ci }; 1518e0dac50fSopenharmony_ci 1519e0dac50fSopenharmony_ci for (auto& elem : windowNodeContainerMap_) { 1520e0dac50fSopenharmony_ci if (elem.second == nullptr) { 1521e0dac50fSopenharmony_ci continue; 1522e0dac50fSopenharmony_ci } 1523e0dac50fSopenharmony_ci std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[elem.first]; 1524e0dac50fSopenharmony_ci for (const auto& displayId : displayIdVec) { 1525e0dac50fSopenharmony_ci os << "Display " << displayId << ":"; 1526e0dac50fSopenharmony_ci } 1527e0dac50fSopenharmony_ci elem.second->TraverseWindowTree(func, true); 1528e0dac50fSopenharmony_ci } 1529e0dac50fSopenharmony_ci return os.str(); 1530e0dac50fSopenharmony_ci} 1531e0dac50fSopenharmony_ci 1532e0dac50fSopenharmony_civoid WindowRoot::FocusFaultDetection() const 1533e0dac50fSopenharmony_ci{ 1534e0dac50fSopenharmony_ci if (!needCheckFocusWindow) { 1535e0dac50fSopenharmony_ci return; 1536e0dac50fSopenharmony_ci } 1537e0dac50fSopenharmony_ci bool needReport = true; 1538e0dac50fSopenharmony_ci uint32_t focusWinId = INVALID_WINDOW_ID; 1539e0dac50fSopenharmony_ci for (auto& elem : windowNodeContainerMap_) { 1540e0dac50fSopenharmony_ci if (elem.second == nullptr) { 1541e0dac50fSopenharmony_ci continue; 1542e0dac50fSopenharmony_ci } 1543e0dac50fSopenharmony_ci focusWinId = elem.second->GetFocusWindow(); 1544e0dac50fSopenharmony_ci if (focusWinId != INVALID_WINDOW_ID) { 1545e0dac50fSopenharmony_ci needReport = false; 1546e0dac50fSopenharmony_ci sptr<WindowNode> windowNode = GetWindowNode(focusWinId); 1547e0dac50fSopenharmony_ci if (windowNode == nullptr || !windowNode->currentVisibility_) { 1548e0dac50fSopenharmony_ci needReport = true; 1549e0dac50fSopenharmony_ci WLOGFE("The focus windowNode is nullptr or is invisible, focusWinId: %{public}u", focusWinId); 1550e0dac50fSopenharmony_ci break; 1551e0dac50fSopenharmony_ci } 1552e0dac50fSopenharmony_ci } 1553e0dac50fSopenharmony_ci } 1554e0dac50fSopenharmony_ci if (needReport) { 1555e0dac50fSopenharmony_ci std::string windowLog(GenAllWindowsLogInfo()); 1556e0dac50fSopenharmony_ci WLOGFE("The focus window is faulty, focusWinId:%{public}u, %{public}s", focusWinId, windowLog.c_str()); 1557e0dac50fSopenharmony_ci int32_t ret = HiSysEventWrite( 1558e0dac50fSopenharmony_ci OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER, 1559e0dac50fSopenharmony_ci "NO_FOCUS_WINDOW", 1560e0dac50fSopenharmony_ci OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, 1561e0dac50fSopenharmony_ci "PID", getpid(), 1562e0dac50fSopenharmony_ci "UID", getuid(), 1563e0dac50fSopenharmony_ci "PACKAGE_NAME", "foundation", 1564e0dac50fSopenharmony_ci "PROCESS_NAME", "foundation", 1565e0dac50fSopenharmony_ci "MSG", windowLog); 1566e0dac50fSopenharmony_ci if (ret != 0) { 1567e0dac50fSopenharmony_ci WLOGFE("Write HiSysEvent error, ret:%{public}d", ret); 1568e0dac50fSopenharmony_ci } 1569e0dac50fSopenharmony_ci } 1570e0dac50fSopenharmony_ci} 1571e0dac50fSopenharmony_ci 1572e0dac50fSopenharmony_civoid WindowRoot::ProcessExpandDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1573e0dac50fSopenharmony_ci std::map<DisplayId, Rect>& displayRectMap) 1574e0dac50fSopenharmony_ci{ 1575e0dac50fSopenharmony_ci if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { 1576e0dac50fSopenharmony_ci WLOGFE("get display failed or get invalid display info"); 1577e0dac50fSopenharmony_ci return; 1578e0dac50fSopenharmony_ci } 1579e0dac50fSopenharmony_ci DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId); 1580e0dac50fSopenharmony_ci DisplayId displayId = displayInfo->GetDisplayId(); 1581e0dac50fSopenharmony_ci ScreenId displayGroupId = displayInfo->GetScreenGroupId(); 1582e0dac50fSopenharmony_ci auto container = windowNodeContainerMap_[displayGroupId]; 1583e0dac50fSopenharmony_ci if (container == nullptr) { 1584e0dac50fSopenharmony_ci WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); 1585e0dac50fSopenharmony_ci return; 1586e0dac50fSopenharmony_ci } 1587e0dac50fSopenharmony_ci 1588e0dac50fSopenharmony_ci container->GetDisplayGroupController()->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); 1589e0dac50fSopenharmony_ci container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_); 1590e0dac50fSopenharmony_ci WLOGI("Container exist, add new display, displayId: %{public}" PRIu64"", displayId); 1591e0dac50fSopenharmony_ci} 1592e0dac50fSopenharmony_ci 1593e0dac50fSopenharmony_cistd::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDMS(sptr<DisplayInfo> displayInfo) 1594e0dac50fSopenharmony_ci{ 1595e0dac50fSopenharmony_ci std::map<DisplayId, Rect> displayRectMap; 1596e0dac50fSopenharmony_ci 1597e0dac50fSopenharmony_ci if (displayInfo == nullptr) { 1598e0dac50fSopenharmony_ci return displayRectMap; 1599e0dac50fSopenharmony_ci } 1600e0dac50fSopenharmony_ci 1601e0dac50fSopenharmony_ci for (auto& displayId : displayIdMap_[displayInfo->GetScreenGroupId()]) { 1602e0dac50fSopenharmony_ci auto info = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); 1603e0dac50fSopenharmony_ci Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() }; 1604e0dac50fSopenharmony_ci displayRectMap.insert(std::make_pair(displayId, displayRect)); 1605e0dac50fSopenharmony_ci 1606e0dac50fSopenharmony_ci WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", 1607e0dac50fSopenharmony_ci displayId, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); 1608e0dac50fSopenharmony_ci } 1609e0dac50fSopenharmony_ci return displayRectMap; 1610e0dac50fSopenharmony_ci} 1611e0dac50fSopenharmony_ci 1612e0dac50fSopenharmony_cistd::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDisplayInfo( 1613e0dac50fSopenharmony_ci const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap) 1614e0dac50fSopenharmony_ci{ 1615e0dac50fSopenharmony_ci std::map<DisplayId, Rect> displayRectMap; 1616e0dac50fSopenharmony_ci 1617e0dac50fSopenharmony_ci for (const auto& iter : displayInfoMap) { 1618e0dac50fSopenharmony_ci auto id = iter.first; 1619e0dac50fSopenharmony_ci auto info = iter.second; 1620e0dac50fSopenharmony_ci Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() }; 1621e0dac50fSopenharmony_ci displayRectMap.insert(std::make_pair(id, displayRect)); 1622e0dac50fSopenharmony_ci 1623e0dac50fSopenharmony_ci WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", 1624e0dac50fSopenharmony_ci id, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); 1625e0dac50fSopenharmony_ci } 1626e0dac50fSopenharmony_ci return displayRectMap; 1627e0dac50fSopenharmony_ci} 1628e0dac50fSopenharmony_ci 1629e0dac50fSopenharmony_civoid WindowRoot::ProcessDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1630e0dac50fSopenharmony_ci const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap) 1631e0dac50fSopenharmony_ci{ 1632e0dac50fSopenharmony_ci DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId(); 1633e0dac50fSopenharmony_ci ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId(); 1634e0dac50fSopenharmony_ci auto iter = windowNodeContainerMap_.find(displayGroupId); 1635e0dac50fSopenharmony_ci if (iter == windowNodeContainerMap_.end()) { 1636e0dac50fSopenharmony_ci CreateWindowNodeContainer(defaultDisplayId, displayInfo); 1637e0dac50fSopenharmony_ci WLOGI("Create new container for display, displayId: %{public}" PRIu64"", displayId); 1638e0dac50fSopenharmony_ci } else { 1639e0dac50fSopenharmony_ci auto& displayIdVec = displayIdMap_[displayGroupId]; 1640e0dac50fSopenharmony_ci if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) { 1641e0dac50fSopenharmony_ci WLOGI("Current display is already exist, displayId: %{public}" PRIu64"", displayId); 1642e0dac50fSopenharmony_ci return; 1643e0dac50fSopenharmony_ci } 1644e0dac50fSopenharmony_ci // add displayId in displayId vector 1645e0dac50fSopenharmony_ci displayIdMap_[displayGroupId].push_back(displayId); 1646e0dac50fSopenharmony_ci auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap); 1647e0dac50fSopenharmony_ci ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); 1648e0dac50fSopenharmony_ci } 1649e0dac50fSopenharmony_ci} 1650e0dac50fSopenharmony_ci 1651e0dac50fSopenharmony_civoid WindowRoot::MoveNotShowingWindowToDefaultDisplay(DisplayId defaultDisplayId, DisplayId displayId) 1652e0dac50fSopenharmony_ci{ 1653e0dac50fSopenharmony_ci for (auto& elem : windowNodeMap_) { 1654e0dac50fSopenharmony_ci auto& windowNode = elem.second; 1655e0dac50fSopenharmony_ci if (windowNode->GetDisplayId() == displayId && !windowNode->currentVisibility_) { 1656e0dac50fSopenharmony_ci std::vector<DisplayId> newShowingDisplays = { defaultDisplayId }; 1657e0dac50fSopenharmony_ci windowNode->SetShowingDisplays(newShowingDisplays); 1658e0dac50fSopenharmony_ci windowNode->isShowingOnMultiDisplays_ = false; 1659e0dac50fSopenharmony_ci if (windowNode->GetWindowToken()) { 1660e0dac50fSopenharmony_ci windowNode->GetWindowToken()->UpdateDisplayId(windowNode->GetDisplayId(), defaultDisplayId); 1661e0dac50fSopenharmony_ci } 1662e0dac50fSopenharmony_ci windowNode->SetDisplayId(defaultDisplayId); 1663e0dac50fSopenharmony_ci } 1664e0dac50fSopenharmony_ci } 1665e0dac50fSopenharmony_ci} 1666e0dac50fSopenharmony_ci 1667e0dac50fSopenharmony_civoid WindowRoot::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1668e0dac50fSopenharmony_ci const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap) 1669e0dac50fSopenharmony_ci{ 1670e0dac50fSopenharmony_ci DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId(); 1671e0dac50fSopenharmony_ci ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId(); 1672e0dac50fSopenharmony_ci auto& displayIdVec = displayIdMap_[displayGroupId]; 1673e0dac50fSopenharmony_ci 1674e0dac50fSopenharmony_ci auto iter = windowNodeContainerMap_.find(displayGroupId); 1675e0dac50fSopenharmony_ci if (iter == windowNodeContainerMap_.end() || 1676e0dac50fSopenharmony_ci std::find(displayIdVec.begin(), displayIdVec.end(), displayId) == displayIdVec.end() || 1677e0dac50fSopenharmony_ci displayInfoMap.find(displayId) == displayInfoMap.end()) { 1678e0dac50fSopenharmony_ci WLOGFE("could not find display, destroy failed, displayId: %{public}" PRIu64"", displayId); 1679e0dac50fSopenharmony_ci return; 1680e0dac50fSopenharmony_ci } 1681e0dac50fSopenharmony_ci 1682e0dac50fSopenharmony_ci // erase displayId in displayIdMap 1683e0dac50fSopenharmony_ci auto displayIter = std::remove(displayIdVec.begin(), displayIdVec.end(), displayId); 1684e0dac50fSopenharmony_ci displayIdVec.erase(displayIter, displayIdVec.end()); 1685e0dac50fSopenharmony_ci 1686e0dac50fSopenharmony_ci // container process display destroy 1687e0dac50fSopenharmony_ci auto container = iter->second; 1688e0dac50fSopenharmony_ci if (container == nullptr) { 1689e0dac50fSopenharmony_ci WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); 1690e0dac50fSopenharmony_ci return; 1691e0dac50fSopenharmony_ci } 1692e0dac50fSopenharmony_ci WLOGI("displayId: %{public}" PRIu64"", displayId); 1693e0dac50fSopenharmony_ci 1694e0dac50fSopenharmony_ci std::vector<uint32_t> needDestroyWindows; 1695e0dac50fSopenharmony_ci auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap); 1696e0dac50fSopenharmony_ci // erase displayId in displayRectMap 1697e0dac50fSopenharmony_ci auto displayRectIter = displayRectMap.find(displayId); 1698e0dac50fSopenharmony_ci if (displayRectIter == displayRectMap.end()) { 1699e0dac50fSopenharmony_ci return; 1700e0dac50fSopenharmony_ci } 1701e0dac50fSopenharmony_ci displayRectMap.erase(displayRectIter); 1702e0dac50fSopenharmony_ci container->GetDisplayGroupController()->ProcessDisplayDestroy( 1703e0dac50fSopenharmony_ci defaultDisplayId, displayInfo, displayRectMap, needDestroyWindows); 1704e0dac50fSopenharmony_ci for (auto id : needDestroyWindows) { 1705e0dac50fSopenharmony_ci auto node = GetWindowNode(id); 1706e0dac50fSopenharmony_ci if (node != nullptr) { 1707e0dac50fSopenharmony_ci DestroyWindowInner(node); 1708e0dac50fSopenharmony_ci } 1709e0dac50fSopenharmony_ci } 1710e0dac50fSopenharmony_ci // move window which is not showing on destroyed display to default display 1711e0dac50fSopenharmony_ci MoveNotShowingWindowToDefaultDisplay(defaultDisplayId, displayId); 1712e0dac50fSopenharmony_ci WLOGI("[Display Destroy] displayId: %{public}" PRIu64" ", displayId); 1713e0dac50fSopenharmony_ci} 1714e0dac50fSopenharmony_ci 1715e0dac50fSopenharmony_civoid WindowRoot::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 1716e0dac50fSopenharmony_ci const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type) 1717e0dac50fSopenharmony_ci{ 1718e0dac50fSopenharmony_ci if (displayInfo == nullptr) { 1719e0dac50fSopenharmony_ci WLOGFE("get display failed"); 1720e0dac50fSopenharmony_ci return; 1721e0dac50fSopenharmony_ci } 1722e0dac50fSopenharmony_ci DisplayId displayId = displayInfo->GetDisplayId(); 1723e0dac50fSopenharmony_ci ScreenId displayGroupId = displayInfo->GetScreenGroupId(); 1724e0dac50fSopenharmony_ci auto& displayIdVec = displayIdMap_[displayGroupId]; 1725e0dac50fSopenharmony_ci auto iter = windowNodeContainerMap_.find(displayGroupId); 1726e0dac50fSopenharmony_ci if (iter == windowNodeContainerMap_.end() || std::find(displayIdVec.begin(), 1727e0dac50fSopenharmony_ci displayIdVec.end(), displayId) == displayIdVec.end()) { 1728e0dac50fSopenharmony_ci WLOGFE("[Display Change] could not find display, change failed, displayId: %{public}" PRIu64"", displayId); 1729e0dac50fSopenharmony_ci return; 1730e0dac50fSopenharmony_ci } 1731e0dac50fSopenharmony_ci // container process display change 1732e0dac50fSopenharmony_ci auto container = iter->second; 1733e0dac50fSopenharmony_ci if (container == nullptr) { 1734e0dac50fSopenharmony_ci WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); 1735e0dac50fSopenharmony_ci return; 1736e0dac50fSopenharmony_ci } 1737e0dac50fSopenharmony_ci 1738e0dac50fSopenharmony_ci auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap); 1739e0dac50fSopenharmony_ci container->GetDisplayGroupController()->ProcessDisplayChange(defaultDisplayId, displayInfo, displayRectMap, type); 1740e0dac50fSopenharmony_ci} 1741e0dac50fSopenharmony_ci 1742e0dac50fSopenharmony_ciRect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const 1743e0dac50fSopenharmony_ci{ 1744e0dac50fSopenharmony_ci Rect fullDisplayRect; 1745e0dac50fSopenharmony_ci auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId); 1746e0dac50fSopenharmony_ci if (container == nullptr) { 1747e0dac50fSopenharmony_ci WLOGFE("window container could not be found"); 1748e0dac50fSopenharmony_ci return fullDisplayRect; 1749e0dac50fSopenharmony_ci } 1750e0dac50fSopenharmony_ci return container->GetDisplayGroupRect(); 1751e0dac50fSopenharmony_ci} 1752e0dac50fSopenharmony_ci 1753e0dac50fSopenharmony_cibool WindowRoot::HasPrivateWindow(DisplayId displayId) 1754e0dac50fSopenharmony_ci{ 1755e0dac50fSopenharmony_ci auto container = GetWindowNodeContainer(displayId); 1756e0dac50fSopenharmony_ci return container != nullptr ? container->HasPrivateWindow() : false; 1757e0dac50fSopenharmony_ci} 1758e0dac50fSopenharmony_ci 1759e0dac50fSopenharmony_cibool WindowRoot::HasMainFullScreenWindowShown(DisplayId displayId) 1760e0dac50fSopenharmony_ci{ 1761e0dac50fSopenharmony_ci auto container = GetWindowNodeContainer(displayId); 1762e0dac50fSopenharmony_ci return container != nullptr ? container->HasMainFullScreenWindowShown() : false; 1763e0dac50fSopenharmony_ci} 1764e0dac50fSopenharmony_ci 1765e0dac50fSopenharmony_civoid WindowRoot::SetMaxAppWindowNumber(uint32_t windowNum) 1766e0dac50fSopenharmony_ci{ 1767e0dac50fSopenharmony_ci maxAppWindowNumber_ = windowNum; 1768e0dac50fSopenharmony_ci} 1769e0dac50fSopenharmony_ci 1770e0dac50fSopenharmony_civoid WindowRoot::SetSplitRatios(const std::vector<float>& splitRatioNumbers) 1771e0dac50fSopenharmony_ci{ 1772e0dac50fSopenharmony_ci auto& splitRatios = splitRatioConfig_.splitRatios; 1773e0dac50fSopenharmony_ci splitRatios.clear(); 1774e0dac50fSopenharmony_ci splitRatios = splitRatioNumbers; 1775e0dac50fSopenharmony_ci for (auto iter = splitRatios.begin(); iter != splitRatios.end();) { 1776e0dac50fSopenharmony_ci if (*iter > 0 && *iter < 1) { // valid ratio range (0, 1) 1777e0dac50fSopenharmony_ci iter++; 1778e0dac50fSopenharmony_ci } else { 1779e0dac50fSopenharmony_ci iter = splitRatios.erase(iter); 1780e0dac50fSopenharmony_ci } 1781e0dac50fSopenharmony_ci } 1782e0dac50fSopenharmony_ci std::sort(splitRatios.begin(), splitRatios.end()); 1783e0dac50fSopenharmony_ci auto iter = std::unique(splitRatios.begin(), splitRatios.end()); 1784e0dac50fSopenharmony_ci splitRatios.erase(iter, splitRatios.end()); // remove duplicate ratios 1785e0dac50fSopenharmony_ci} 1786e0dac50fSopenharmony_ci 1787e0dac50fSopenharmony_civoid WindowRoot::SetExitSplitRatios(const std::vector<float>& exitSplitRatios) 1788e0dac50fSopenharmony_ci{ 1789e0dac50fSopenharmony_ci if (exitSplitRatios.size() != 2) { // 2 is size of vector. 1790e0dac50fSopenharmony_ci return; 1791e0dac50fSopenharmony_ci } 1792e0dac50fSopenharmony_ci if (exitSplitRatios[0] > 0 && exitSplitRatios[0] < DEFAULT_SPLIT_RATIO) { 1793e0dac50fSopenharmony_ci splitRatioConfig_.exitSplitStartRatio = exitSplitRatios[0]; 1794e0dac50fSopenharmony_ci } 1795e0dac50fSopenharmony_ci if (exitSplitRatios[1] > DEFAULT_SPLIT_RATIO && exitSplitRatios[1] < 1) { 1796e0dac50fSopenharmony_ci splitRatioConfig_.exitSplitEndRatio = exitSplitRatios[1]; 1797e0dac50fSopenharmony_ci } 1798e0dac50fSopenharmony_ci} 1799e0dac50fSopenharmony_ci 1800e0dac50fSopenharmony_ciWMError WindowRoot::GetModeChangeHotZones(DisplayId displayId, 1801e0dac50fSopenharmony_ci ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config) 1802e0dac50fSopenharmony_ci{ 1803e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(displayId); 1804e0dac50fSopenharmony_ci if (container == nullptr) { 1805e0dac50fSopenharmony_ci WLOGFE("GetModeChangeHotZones failed, window container could not be found"); 1806e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1807e0dac50fSopenharmony_ci } 1808e0dac50fSopenharmony_ci container->GetModeChangeHotZones(displayId, hotZones, config); 1809e0dac50fSopenharmony_ci return WMError::WM_OK; 1810e0dac50fSopenharmony_ci} 1811e0dac50fSopenharmony_ci 1812e0dac50fSopenharmony_civoid WindowRoot::RemoveSingleUserWindowNodes(int accountId) 1813e0dac50fSopenharmony_ci{ 1814e0dac50fSopenharmony_ci std::vector<DisplayId> displayIds = GetAllDisplayIds(); 1815e0dac50fSopenharmony_ci for (auto id : displayIds) { 1816e0dac50fSopenharmony_ci sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(id); 1817e0dac50fSopenharmony_ci if (container == nullptr) { 1818e0dac50fSopenharmony_ci WLOGW("get container failed %{public}" PRIu64"", id); 1819e0dac50fSopenharmony_ci continue; 1820e0dac50fSopenharmony_ci } 1821e0dac50fSopenharmony_ci container->RemoveSingleUserWindowNodes(accountId); 1822e0dac50fSopenharmony_ci } 1823e0dac50fSopenharmony_ci} 1824e0dac50fSopenharmony_ci 1825e0dac50fSopenharmony_ciWMError WindowRoot::UpdateRsTree(uint32_t windowId, bool isAdd) 1826e0dac50fSopenharmony_ci{ 1827e0dac50fSopenharmony_ci sptr<WindowNode> node = GetWindowNode(windowId); 1828e0dac50fSopenharmony_ci if (node == nullptr) { 1829e0dac50fSopenharmony_ci WLOGFE("could not find window"); 1830e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1831e0dac50fSopenharmony_ci } 1832e0dac50fSopenharmony_ci auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); 1833e0dac50fSopenharmony_ci if (container == nullptr) { 1834e0dac50fSopenharmony_ci WLOGFE("window container could not be found"); 1835e0dac50fSopenharmony_ci return WMError::WM_ERROR_NULLPTR; 1836e0dac50fSopenharmony_ci } 1837e0dac50fSopenharmony_ci for (auto& displayId : node->GetShowingDisplays()) { 1838e0dac50fSopenharmony_ci if (isAdd) { 1839e0dac50fSopenharmony_ci container->AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE); 1840e0dac50fSopenharmony_ci } else { 1841e0dac50fSopenharmony_ci container->RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE); 1842e0dac50fSopenharmony_ci } 1843e0dac50fSopenharmony_ci } 1844e0dac50fSopenharmony_ci RSTransaction::FlushImplicitTransaction(); 1845e0dac50fSopenharmony_ci return WMError::WM_OK; 1846e0dac50fSopenharmony_ci} 1847e0dac50fSopenharmony_ci 1848e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::FindMainWindowWithToken(sptr<IRemoteObject> token) 1849e0dac50fSopenharmony_ci{ 1850e0dac50fSopenharmony_ci auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), 1851e0dac50fSopenharmony_ci [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) { 1852e0dac50fSopenharmony_ci if (WindowHelper::IsMainWindow(pair.second->GetWindowType())) { 1853e0dac50fSopenharmony_ci return pair.second->abilityToken_ == token; 1854e0dac50fSopenharmony_ci } 1855e0dac50fSopenharmony_ci return false; 1856e0dac50fSopenharmony_ci }); 1857e0dac50fSopenharmony_ci if (iter == windowNodeMap_.end()) { 1858e0dac50fSopenharmony_ci WLOGI("cannot find windowNode"); 1859e0dac50fSopenharmony_ci return nullptr; 1860e0dac50fSopenharmony_ci } 1861e0dac50fSopenharmony_ci return iter->second; 1862e0dac50fSopenharmony_ci} 1863e0dac50fSopenharmony_ci 1864e0dac50fSopenharmony_cibool WindowRoot::CheckMultiDialogWindows(WindowType type, sptr<IRemoteObject> token) 1865e0dac50fSopenharmony_ci{ 1866e0dac50fSopenharmony_ci if (type != WindowType::WINDOW_TYPE_DIALOG) { 1867e0dac50fSopenharmony_ci return false; 1868e0dac50fSopenharmony_ci } 1869e0dac50fSopenharmony_ci 1870e0dac50fSopenharmony_ci sptr<WindowNode> newCaller, oriCaller; 1871e0dac50fSopenharmony_ci 1872e0dac50fSopenharmony_ci newCaller = FindMainWindowWithToken(token); 1873e0dac50fSopenharmony_ci if (newCaller == nullptr) { 1874e0dac50fSopenharmony_ci return false; 1875e0dac50fSopenharmony_ci } 1876e0dac50fSopenharmony_ci 1877e0dac50fSopenharmony_ci for (auto& iter : windowNodeMap_) { 1878e0dac50fSopenharmony_ci if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) { 1879e0dac50fSopenharmony_ci oriCaller = FindMainWindowWithToken(iter.second->dialogTargetToken_); 1880e0dac50fSopenharmony_ci if (oriCaller == newCaller) { 1881e0dac50fSopenharmony_ci return true; 1882e0dac50fSopenharmony_ci } 1883e0dac50fSopenharmony_ci } 1884e0dac50fSopenharmony_ci } 1885e0dac50fSopenharmony_ci 1886e0dac50fSopenharmony_ci return false; 1887e0dac50fSopenharmony_ci} 1888e0dac50fSopenharmony_ci 1889e0dac50fSopenharmony_cisptr<WindowNode> WindowRoot::GetWindowNodeByAbilityToken(const sptr<IRemoteObject>& abilityToken) 1890e0dac50fSopenharmony_ci{ 1891e0dac50fSopenharmony_ci for (const auto& iter : windowNodeMap_) { 1892e0dac50fSopenharmony_ci if (iter.second != nullptr && iter.second->abilityToken_ == abilityToken) { 1893e0dac50fSopenharmony_ci return iter.second; 1894e0dac50fSopenharmony_ci } 1895e0dac50fSopenharmony_ci } 1896e0dac50fSopenharmony_ci WLOGFE("could not find required abilityToken!"); 1897e0dac50fSopenharmony_ci return nullptr; 1898e0dac50fSopenharmony_ci} 1899e0dac50fSopenharmony_ci 1900e0dac50fSopenharmony_cibool WindowRoot::TakeWindowPairSnapshot(DisplayId displayId) 1901e0dac50fSopenharmony_ci{ 1902e0dac50fSopenharmony_ci auto container = GetWindowNodeContainer(displayId); 1903e0dac50fSopenharmony_ci return container == nullptr ? false : container->TakeWindowPairSnapshot(displayId); 1904e0dac50fSopenharmony_ci} 1905e0dac50fSopenharmony_ci 1906e0dac50fSopenharmony_civoid WindowRoot::ClearWindowPairSnapshot(DisplayId displayId) 1907e0dac50fSopenharmony_ci{ 1908e0dac50fSopenharmony_ci auto container = GetWindowNodeContainer(displayId); 1909e0dac50fSopenharmony_ci if (container == nullptr) { 1910e0dac50fSopenharmony_ci WLOGFE("clear window pair snapshot failed, because container in null"); 1911e0dac50fSopenharmony_ci return; 1912e0dac50fSopenharmony_ci } 1913e0dac50fSopenharmony_ci return container->ClearWindowPairSnapshot(displayId); 1914e0dac50fSopenharmony_ci} 1915e0dac50fSopenharmony_ci 1916e0dac50fSopenharmony_civoid WindowRoot::CheckAndNotifyWaterMarkChangedResult() 1917e0dac50fSopenharmony_ci{ 1918e0dac50fSopenharmony_ci auto searchWaterMarkWindow = [](wptr<WindowNode> node) { 1919e0dac50fSopenharmony_ci return (node != nullptr && node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION && 1920e0dac50fSopenharmony_ci (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK))); 1921e0dac50fSopenharmony_ci }; 1922e0dac50fSopenharmony_ci bool currentWaterMarkState = false; 1923e0dac50fSopenharmony_ci for (auto& containerPair : windowNodeContainerMap_) { 1924e0dac50fSopenharmony_ci auto container = containerPair.second; 1925e0dac50fSopenharmony_ci if (container == nullptr) { 1926e0dac50fSopenharmony_ci continue; 1927e0dac50fSopenharmony_ci } 1928e0dac50fSopenharmony_ci std::vector<sptr<WindowNode>> allWindowNode; 1929e0dac50fSopenharmony_ci container->TraverseContainer(allWindowNode); 1930e0dac50fSopenharmony_ci auto itor = std::find_if(allWindowNode.begin(), allWindowNode.end(), searchWaterMarkWindow); 1931e0dac50fSopenharmony_ci if (itor != allWindowNode.end()) { 1932e0dac50fSopenharmony_ci currentWaterMarkState = true; 1933e0dac50fSopenharmony_ci break; 1934e0dac50fSopenharmony_ci } 1935e0dac50fSopenharmony_ci } 1936e0dac50fSopenharmony_ci if (lastWaterMarkShowStates_ != currentWaterMarkState) { 1937e0dac50fSopenharmony_ci WLOGFD("WaterMarkWindows has been changed. lastWaterMarkState : %{public}d, newState:%{public}d", 1938e0dac50fSopenharmony_ci lastWaterMarkShowStates_, currentWaterMarkState); 1939e0dac50fSopenharmony_ci WindowManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(currentWaterMarkState); 1940e0dac50fSopenharmony_ci lastWaterMarkShowStates_ = currentWaterMarkState; 1941e0dac50fSopenharmony_ci } 1942e0dac50fSopenharmony_ci} 1943e0dac50fSopenharmony_ci} // namespace Rosen 1944e0dac50fSopenharmony_ci} // namespace OHOS 1945