1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "accessibility_connection.h" 17 18#include "display_manager_service_inner.h" 19#include "window_manager.h" 20#include "window_manager_agent_controller.h" 21#include "window_manager_hilog.h" 22 23namespace OHOS::Rosen { 24namespace { 25constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "AccessibilityConnection"}; 26} 27 28void AccessibilityConnection::NotifyAccessibilityWindowInfo(const sptr<WindowNode>& node, WindowUpdateType type) 29{ 30 if (node == nullptr) { 31 WLOGFE("window node is null"); 32 return; 33 } 34 auto container = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId()); 35 if (container == nullptr) { 36 WLOGFE("container is null"); 37 return; 38 } 39 std::vector<sptr<WindowNode>> nodes; 40 nodes.emplace_back(node); 41 UpdateFocusChangeEvent(container); 42 NotifyAccessibilityWindowInfo(nodes, container->GetFocusWindow(), type); 43} 44 45void AccessibilityConnection::NotifyAccessibilityWindowInfo(DisplayId displayId, 46 const std::vector<sptr<WindowNode>>& nodes, WindowUpdateType type) 47{ 48 if (nodes.empty()) { 49 WLOGFE("nodes is empty"); 50 return; 51 } 52 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); 53 if (container == nullptr) { 54 WLOGFE("container is null"); 55 return; 56 } 57 UpdateFocusChangeEvent(container); 58 NotifyAccessibilityWindowInfo(nodes, container->GetFocusWindow(), type); 59} 60 61void AccessibilityConnection::NotifyAccessibilityWindowInfo(DisplayId displayId, WindowUpdateType type) 62{ 63 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); 64 if (container == nullptr) { 65 WLOGFE("container is null"); 66 return; 67 } 68 std::vector<sptr<WindowNode>> nodes; 69 container->TraverseContainer(nodes); 70 UpdateFocusChangeEvent(container); 71 NotifyAccessibilityWindowInfo(nodes, container->GetFocusWindow(), type); 72} 73 74void AccessibilityConnection::NotifyAccessibilityWindowInfo(const std::vector<sptr<WindowNode>>& nodes, 75 uint32_t focusedWindow, WindowUpdateType type) const 76{ 77 std::vector<sptr<AccessibilityWindowInfo>> infos; 78 FillAccessibilityWindowInfo(nodes, focusedWindow, infos); 79 if (infos.empty()) { 80 WLOGFE("infos is empty"); 81 return; 82 } 83 WindowManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(infos, type); 84} 85 86void AccessibilityConnection::FillAccessibilityWindowInfo(const std::vector<sptr<WindowNode>>& nodes, 87 uint32_t focusedWindow, std::vector<sptr<AccessibilityWindowInfo>>& infos) const 88{ 89 for (auto& node : nodes) { 90 sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo(); 91 if (info == nullptr) { 92 WLOGFE("new accessibilityWindowInfo is null"); 93 return; 94 } 95 if (node == nullptr) { 96 WLOGFW("node is null"); 97 break; 98 } 99 info->wid_ = static_cast<int32_t>(node->GetWindowId()); 100 info->windowRect_ = node->GetWindowRect(); 101 info->focused_ = node->GetWindowId() == focusedWindow; 102 info->displayId_ = node->GetDisplayId(); 103 info->layer_ = node->zOrder_; 104 info->mode_ = node->GetWindowMode(); 105 info->type_ = node->GetWindowType(); 106 auto property = node->GetWindowProperty(); 107 if (property != nullptr) { 108 info->isDecorEnable_ = property->GetDecorEnable(); 109 } 110 infos.emplace_back(info); 111 } 112} 113 114void AccessibilityConnection::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos) const 115{ 116 std::map<ScreenId, sptr<WindowNodeContainer>> windowNodeContainers; 117 std::vector<DisplayId> displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds(); 118 for (DisplayId displayId : displayIds) { 119 ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); 120 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); 121 if (windowNodeContainers.count(screenGroupId) == 0 && container != nullptr) { 122 windowNodeContainers.insert(std::make_pair(screenGroupId, container)); 123 std::vector<sptr<WindowNode>> nodes; 124 container->TraverseContainer(nodes); 125 FillAccessibilityWindowInfo(nodes, container->GetFocusWindow(), infos); 126 } 127 } 128} 129 130void AccessibilityConnection::UpdateFocusChangeEvent(const sptr<WindowNodeContainer>& container) 131{ 132 if (container == nullptr) { 133 WLOGFE("container is null"); 134 return; 135 } 136 bool focusChange = false; 137 uint32_t focusWindowId = container->GetFocusWindow(); 138 auto iter = focusedWindowMap_.find(container); 139 if (iter == focusedWindowMap_.end()) { 140 focusedWindowMap_.insert(std::make_pair(container, focusWindowId)); 141 if (focusWindowId != INVALID_WINDOW_ID) { 142 focusChange = true; 143 } 144 } else { 145 if (focusWindowId != iter->second) { 146 focusChange = true; 147 iter->second = focusWindowId; 148 } 149 } 150 if (focusChange) { 151 auto focusWindowNode = windowRoot_->GetWindowNode(focusWindowId); 152 if (focusWindowNode == nullptr) { 153 WLOGFE("could not find window"); 154 return; 155 } 156 std::vector<sptr<WindowNode>> focusNodes; 157 focusNodes.emplace_back(focusWindowNode); 158 WLOGFD("notify accessibility window info: focus change, focusWindowId: %{public}u", focusWindowId); 159 NotifyAccessibilityWindowInfo(focusNodes, focusWindowId, WindowUpdateType::WINDOW_UPDATE_FOCUSED); 160 } 161} 162} 163