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