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
23 namespace OHOS::Rosen {
24 namespace {
25 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "AccessibilityConnection"};
26 }
27
NotifyAccessibilityWindowInfo(const sptr<WindowNode> & node,WindowUpdateType type)28 void 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
NotifyAccessibilityWindowInfo(DisplayId displayId,const std::vector<sptr<WindowNode>> & nodes,WindowUpdateType type)45 void 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
NotifyAccessibilityWindowInfo(DisplayId displayId,WindowUpdateType type)61 void 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
NotifyAccessibilityWindowInfo(const std::vector<sptr<WindowNode>> & nodes,uint32_t focusedWindow,WindowUpdateType type) const74 void 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
FillAccessibilityWindowInfo(const std::vector<sptr<WindowNode>> & nodes,uint32_t focusedWindow,std::vector<sptr<AccessibilityWindowInfo>> & infos) const86 void 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
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos) const114 void 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
UpdateFocusChangeEvent(const sptr<WindowNodeContainer> & container)130 void 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