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_window_manager.h"
17
18 #include <hitrace_meter.h>
19
20 #include "accessible_ability_manager_service.h"
21 #include "hilog_wrapper.h"
22 #include "utils.h"
23
24 namespace OHOS {
25 namespace Accessibility {
AccessibilityWindowManager()26 AccessibilityWindowManager::AccessibilityWindowManager()
27 {
28 }
29
Init()30 bool AccessibilityWindowManager::Init()
31 {
32 DeInit();
33 HILOG_DEBUG("deinit before start");
34 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryWindowInfo");
35 std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
36 Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(windowInfos);
37 if (err != Rosen::WMError::WM_OK) {
38 Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
39 HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
40 return false;
41 }
42 HILOG_DEBUG("windowInfos size is %{public}zu", windowInfos.size());
43 for (auto &window : windowInfos) {
44 if (!window) {
45 HILOG_ERROR("window is nullptr");
46 continue;
47 }
48
49 int32_t realWid = GetRealWindowId(window);
50 if (!a11yWindows_.count(realWid)) {
51 auto a11yWindowInfo = CreateAccessibilityWindowInfo(window);
52 a11yWindows_.emplace(realWid, a11yWindowInfo);
53 }
54
55 if (IsSceneBoard(window)) {
56 subWindows_.insert(realWid);
57 sceneBoardElementIdMap_.InsertPair(realWid, window->uiNodeId_);
58 }
59
60 if (a11yWindows_[realWid].IsFocused()) {
61 SetActiveWindow(realWid);
62 }
63 }
64 return true;
65 }
66
DeInit()67 void AccessibilityWindowManager::DeInit()
68 {
69 HILOG_DEBUG();
70 a11yWindows_.clear();
71 subWindows_.clear();
72 sceneBoardElementIdMap_.Clear();
73 activeWindowId_ = INVALID_WINDOW_ID;
74 a11yFocusedWindowId_ = INVALID_WINDOW_ID;
75 }
76
~AccessibilityWindowManager()77 AccessibilityWindowManager::~AccessibilityWindowManager()
78 {
79 DeregisterWindowListener();
80 }
81
RegisterWindowListener(const std::shared_ptr<AppExecFwk::EventHandler> & handler)82 void AccessibilityWindowManager::RegisterWindowListener(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
83 {
84 DeregisterWindowListener();
85 HILOG_DEBUG("deregister before register");
86 if (windowListener_) {
87 HILOG_DEBUG("Window listener is already registered!");
88 return;
89 }
90
91 eventHandler_ = handler;
92 windowListener_ = new(std::nothrow) AccessibilityWindowListener(*this);
93 if (!windowListener_) {
94 HILOG_ERROR("Create window listener fail!");
95 return;
96 }
97 OHOS::Rosen::WindowManager::GetInstance().RegisterWindowUpdateListener(windowListener_);
98 }
99
DeregisterWindowListener()100 void AccessibilityWindowManager::DeregisterWindowListener()
101 {
102 if (windowListener_) {
103 OHOS::Rosen::WindowManager::GetInstance().UnregisterWindowUpdateListener(windowListener_);
104 windowListener_ = nullptr;
105 eventHandler_ = nullptr;
106 }
107 }
108
OnWindowUpdate(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos,Rosen::WindowUpdateType type)109 void AccessibilityWindowManager::OnWindowUpdate(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos,
110 Rosen::WindowUpdateType type)
111 {
112 HILOG_DEBUG("WindowUpdateType type[%{public}d]", type);
113 if (!eventHandler_) {
114 HILOG_ERROR("eventHandler_ is nullptr.");
115 return;
116 }
117 if (infos.size() == 0) {
118 HILOG_ERROR("window info is err");
119 return;
120 }
121 eventHandler_->PostTask(std::bind([=]() -> void {
122 switch (type) {
123 case Rosen::WindowUpdateType::WINDOW_UPDATE_ADDED: // 1
124 WindowUpdateAdded(infos);
125 break;
126 case Rosen::WindowUpdateType::WINDOW_UPDATE_REMOVED: // 2
127 WindowUpdateRemoved(infos);
128 break;
129 case Rosen::WindowUpdateType::WINDOW_UPDATE_BOUNDS: // 4
130 WindowUpdateBounds(infos);
131 break;
132 case Rosen::WindowUpdateType::WINDOW_UPDATE_ACTIVE: // 5
133 WindowUpdateActive(infos);
134 break;
135 case Rosen::WindowUpdateType::WINDOW_UPDATE_FOCUSED: // 3
136 WindowUpdateFocused(infos);
137 break;
138 case Rosen::WindowUpdateType::WINDOW_UPDATE_PROPERTY: // 6
139 WindowUpdateProperty(infos);
140 break;
141 default:
142 break;
143 }
144 HILOG_DEBUG("a11yWindows[%{public}zu]", a11yWindows_.size());
145 }), "TASK_ON_WINDOW_UPDATE");
146 }
147
ConvertToRealWindowId(int32_t windowId,int32_t focusType)148 int32_t AccessibilityWindowManager::ConvertToRealWindowId(int32_t windowId, int32_t focusType)
149 {
150 int32_t winId = windowId;
151 HILOG_DEBUG("ConvertToRealWindowId called, windowId[%{public}d], focusType[%{public}d]", windowId, focusType);
152 if (windowId == ACTIVE_WINDOW_ID) {
153 HILOG_DEBUG("After convert active windowId[%{public}d]", activeWindowId_);
154 winId = activeWindowId_;
155 }
156
157 if (windowId == ANY_WINDOW_ID) {
158 if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
159 HILOG_DEBUG("After convert a11yFocused windowId[%{public}d] by accessibility type", a11yFocusedWindowId_);
160 winId = a11yFocusedWindowId_;
161 } else if (focusType == FOCUS_TYPE_INPUT) {
162 HILOG_DEBUG("After convert active windowId[%{public}d] by input type", activeWindowId_);
163 winId = activeWindowId_;
164 }
165 }
166
167 if (subWindows_.count(winId)) {
168 HILOG_DEBUG("After convert normal windowId[%{public}d]", SCENE_BOARD_WINDOW_ID);
169 return SCENE_BOARD_WINDOW_ID;
170 }
171 HILOG_DEBUG("After convert windowId[%{public}d] and activeId[%{public}d]", winId, activeWindowId_);
172 return winId;
173 }
174
ConvertWindowType(Rosen::WindowType type)175 AccessibilityWindowType ConvertWindowType(Rosen::WindowType type)
176 {
177 AccessibilityWindowType winType = TYPE_WINDOW_INVALID;
178
179 if (type < Rosen::WindowType::SYSTEM_WINDOW_BASE) {
180 winType = TYPE_APPLICATION;
181 } else if ((type >= Rosen::WindowType::SYSTEM_WINDOW_BASE) && (type <= Rosen::WindowType::SYSTEM_WINDOW_END)) {
182 winType = TYPE_SYSTEM;
183 } else {
184 HILOG_ERROR("Unknown windowType[%{public}d]", type);
185 }
186 return winType;
187 }
188
CheckIntegerOverflow(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)189 bool AccessibilityWindowManager::CheckIntegerOverflow(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
190 {
191 if ((windowInfo->windowRect_.posX_ > 0) && (static_cast<int32_t>(windowInfo->windowRect_.width_) > 0)) {
192 int32_t leftX = INT32_MAX - windowInfo->windowRect_.posX_;
193 if (leftX < static_cast<int32_t>(windowInfo->windowRect_.width_)) {
194 HILOG_ERROR("input parameter invalid posX %{public}d, width_ %{public}u", windowInfo->windowRect_.posX_,
195 windowInfo->windowRect_.width_);
196 return false;
197 }
198 }
199
200 if ((windowInfo->windowRect_.posX_ < 0) && (static_cast<int32_t>(windowInfo->windowRect_.width_) < 0)) {
201 int32_t leftX = INT32_MIN - windowInfo->windowRect_.posX_;
202 if (leftX > static_cast<int32_t>(windowInfo->windowRect_.width_)) {
203 HILOG_ERROR("input parameter invalid posX %{public}d, width_ %{public}u", windowInfo->windowRect_.posX_,
204 windowInfo->windowRect_.width_);
205 return false;
206 }
207 }
208
209 if ((windowInfo->windowRect_.posY_ > 0) && (static_cast<int32_t>(windowInfo->windowRect_.height_) > 0)) {
210 int32_t leftY = INT32_MAX - windowInfo->windowRect_.posY_;
211 if (leftY < static_cast<int32_t>(windowInfo->windowRect_.height_)) {
212 HILOG_ERROR("input parameter invalid posX %{public}d, height_ %{public}u", windowInfo->windowRect_.posY_,
213 windowInfo->windowRect_.height_);
214 return false;
215 }
216 }
217
218 if ((windowInfo->windowRect_.posY_ < 0) && (static_cast<int32_t>(windowInfo->windowRect_.height_) < 0)) {
219 int32_t leftY = INT32_MIN - windowInfo->windowRect_.posY_;
220 if (leftY > static_cast<int32_t>(windowInfo->windowRect_.height_)) {
221 HILOG_ERROR("input parameter invalid posX %{public}d, height_ %{public}u", windowInfo->windowRect_.posY_,
222 windowInfo->windowRect_.height_);
223 return false;
224 }
225 }
226
227 return true;
228 }
229
UpdateAccessibilityWindowInfo(AccessibilityWindowInfo & accWindowInfo,const sptr<Rosen::AccessibilityWindowInfo> windowInfo)230 void AccessibilityWindowManager::UpdateAccessibilityWindowInfo(AccessibilityWindowInfo &accWindowInfo,
231 const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
232 {
233 accWindowInfo.SetWindowId(windowInfo->wid_);
234 accWindowInfo.SetWindowType(static_cast<uint32_t>(windowInfo->type_));
235 accWindowInfo.SetWindowMode(static_cast<uint32_t>(windowInfo->mode_));
236 accWindowInfo.SetAccessibilityWindowType(ConvertWindowType(windowInfo->type_));
237 accWindowInfo.SetFocused(windowInfo->focused_);
238 accWindowInfo.SetWindowLayer(windowInfo->layer_);
239 if (static_cast<int32_t>(windowInfo->type_) == 1 && (static_cast<int32_t>(windowInfo->windowRect_.width_) == 0 ||
240 static_cast<int32_t>(windowInfo->windowRect_.height_) == 0)) {
241 HILOG_ERROR("invalid window parameters, windowId(%{public}d), posX(%{public}d, posY(%{public}d))",
242 windowInfo->wid_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
243 } else {
244 Rect bound;
245 bound.SetLeftTopScreenPostion(windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
246 if (!CheckIntegerOverflow(windowInfo)) {
247 bound.SetRightBottomScreenPostion(windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
248 } else {
249 bound.SetRightBottomScreenPostion(
250 windowInfo->windowRect_.posX_ + static_cast<int32_t>(windowInfo->windowRect_.width_),
251 windowInfo->windowRect_.posY_ + static_cast<int32_t>(windowInfo->windowRect_.height_));
252 }
253 accWindowInfo.SetRectInScreen(bound);
254 }
255 accWindowInfo.SetDisplayId(windowInfo->displayId_);
256 accWindowInfo.SetDecorEnable(windowInfo->isDecorEnable_);
257 accWindowInfo.SetUiNodeId(windowInfo->uiNodeId_);
258 accWindowInfo.SetInnerWid(windowInfo->innerWid_);
259 if (accWindowInfo.GetWindowId() == SCENE_BOARD_WINDOW_ID) {
260 accWindowInfo.SetWindowId(windowInfo->innerWid_);
261 HILOG_INFO("scene board window id 1 convert inner window id[%{public}d]", windowInfo->innerWid_);
262 }
263 }
264
GetRealWindowId(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)265 int32_t AccessibilityWindowManager::GetRealWindowId(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
266 {
267 if (windowInfo->wid_ == SCENE_BOARD_WINDOW_ID) {
268 return windowInfo->innerWid_;
269 }
270 return windowInfo->wid_;
271 }
272
IsSceneBoard(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)273 bool AccessibilityWindowManager::IsSceneBoard(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
274 {
275 if (windowInfo->wid_ == SCENE_BOARD_WINDOW_ID) {
276 return true;
277 }
278 return false;
279 }
280
CreateAccessibilityWindowInfo(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)281 AccessibilityWindowInfo AccessibilityWindowManager::CreateAccessibilityWindowInfo(
282 const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
283 {
284 AccessibilityWindowInfo info;
285 UpdateAccessibilityWindowInfo(info, windowInfo);
286 HILOG_DEBUG("Create WindowInfo Id(%{public}d) type(%{public}d) posX(%{public}d) posY(%{public}d)"
287 "witdth(%{public}d) height(%{public}d) display id(%{public}" PRIu64 ") isDecorEnable(%{public}d)"
288 "innerWid(%{public}d), uiNodeId(%{public}d)",
289 windowInfo->wid_, windowInfo->type_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_,
290 windowInfo->windowRect_.width_, windowInfo->windowRect_.height_, windowInfo->displayId_,
291 windowInfo->isDecorEnable_, windowInfo->innerWid_, windowInfo->uiNodeId_);
292 return info;
293 }
294
SetActiveWindow(int32_t windowId)295 void AccessibilityWindowManager::SetActiveWindow(int32_t windowId)
296 {
297 HILOG_DEBUG("windowId is %{public}d", windowId);
298 if (windowId == INVALID_WINDOW_ID) {
299 ClearOldActiveWindow();
300 activeWindowId_ = INVALID_WINDOW_ID;
301 return;
302 }
303
304 if (!a11yWindows_.count(windowId)) {
305 HILOG_WARN("Window id is not found");
306 return;
307 }
308
309 if (activeWindowId_ != windowId) {
310 ClearOldActiveWindow();
311 activeWindowId_ = windowId;
312 a11yWindows_[activeWindowId_].SetActive(true);
313 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
314 AccessibilityEventInfo evtInf(activeWindowId_, WINDOW_UPDATE_ACTIVE);
315 aams.SendEvent(evtInf);
316 }
317 HILOG_DEBUG("activeWindowId is %{public}d", activeWindowId_);
318 }
319
SetAccessibilityFocusedWindow(int32_t windowId)320 void AccessibilityWindowManager::SetAccessibilityFocusedWindow(int32_t windowId)
321 {
322 HILOG_DEBUG("windowId is %{public}d", windowId);
323 if (windowId == INVALID_WINDOW_ID) {
324 ClearAccessibilityFocused();
325 a11yFocusedWindowId_ = INVALID_WINDOW_ID;
326 return;
327 }
328
329 if (!a11yWindows_.count(windowId)) {
330 HILOG_ERROR("Window id[%{public}d] is not found", windowId);
331 return;
332 }
333
334 if (a11yFocusedWindowId_ != windowId) {
335 ClearAccessibilityFocused();
336 a11yFocusedWindowId_ = windowId;
337 a11yWindows_[a11yFocusedWindowId_].SetAccessibilityFocused(true);
338 }
339 HILOG_DEBUG("a11yFocusedWindowId_ is %{public}d", a11yFocusedWindowId_);
340 }
341
GetAccessibilityWindows()342 std::vector<AccessibilityWindowInfo> AccessibilityWindowManager::GetAccessibilityWindows()
343 {
344 HILOG_DEBUG("a11yWindows_ size[%{public}zu]", a11yWindows_.size());
345 std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
346 std::vector<AccessibilityWindowInfo> windows;
347 Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(windowInfos);
348 if (err != Rosen::WMError::WM_OK) {
349 HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
350 return windows;
351 }
352 for (auto &info : windowInfos) {
353 if (info == nullptr) {
354 continue;
355 }
356
357 int32_t realWidId = GetRealWindowId(info);
358 if (a11yWindows_.count(realWidId)) {
359 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], info);
360 }
361 }
362 std::transform(a11yWindows_.begin(), a11yWindows_.end(), std::back_inserter(windows),
363 [](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) { return window.second; });
364
365 HILOG_DEBUG("window size[%{public}zu]", windows.size());
366 for (auto &logWindow : windows) {
367 HILOG_DEBUG("logWindow id[%{public}d]", logWindow.GetWindowId());
368 }
369 return windows;
370 }
371
GetAccessibilityWindow(int32_t windowId,AccessibilityWindowInfo & window)372 bool AccessibilityWindowManager::GetAccessibilityWindow(int32_t windowId, AccessibilityWindowInfo &window)
373 {
374 HILOG_DEBUG("start windowId(%{public}d)", windowId);
375 std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
376 Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(windowInfos);
377 if (err != Rosen::WMError::WM_OK) {
378 HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
379 return false;
380 }
381 for (auto &info : windowInfos) {
382 if (info == nullptr) {
383 continue;
384 }
385
386 int32_t realWidId = GetRealWindowId(info);
387 if (info != nullptr && a11yWindows_.count(realWidId)) {
388 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], info);
389 }
390 }
391 if (a11yWindows_.count(windowId)) {
392 window = a11yWindows_[windowId];
393 return true;
394 }
395 return false;
396 }
397
IsValidWindow(int32_t windowId)398 bool AccessibilityWindowManager::IsValidWindow(int32_t windowId)
399 {
400 HILOG_DEBUG("start windowId(%{public}d)", windowId);
401
402 auto it = std::find_if(a11yWindows_.begin(), a11yWindows_.end(),
403 [windowId](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) {
404 return window.first == windowId;
405 });
406 if (it == a11yWindows_.end()) {
407 return false;
408 }
409 return true;
410 }
411
SetWindowSize(int32_t windowId,Rect rect)412 void AccessibilityWindowManager::SetWindowSize(int32_t windowId, Rect rect)
413 {
414 HILOG_DEBUG("start windowId(%{public}d)", windowId);
415 auto it = std::find_if(a11yWindows_.begin(), a11yWindows_.end(),
416 [windowId](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) {
417 return window.first == windowId;
418 });
419 if (it != a11yWindows_.end()) {
420 it->second.SetRectInScreen(rect);
421 }
422 }
423
WindowUpdateAdded(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)424 void AccessibilityWindowManager::WindowUpdateAdded(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
425 {
426 HILOG_DEBUG();
427 for (auto &windowInfo : infos) {
428 if (!windowInfo) {
429 HILOG_ERROR("invalid windowInfo");
430 return;
431 }
432
433 int32_t realWidId = GetRealWindowId(windowInfo);
434 if (!a11yWindows_.count(realWidId)) {
435 auto a11yWindowInfoAdded = CreateAccessibilityWindowInfo(windowInfo);
436 a11yWindows_.emplace(realWidId, a11yWindowInfoAdded);
437 } else {
438 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
439 }
440
441 if (IsSceneBoard(windowInfo)) {
442 subWindows_.insert(realWidId);
443 sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
444 }
445 AccessibilityEventInfo evtInfAdded(realWidId, WINDOW_UPDATE_ADDED);
446 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfAdded);
447 if (a11yWindows_[realWidId].IsFocused()) {
448 SetActiveWindow(realWidId);
449 }
450 }
451 }
452
WindowUpdateRemoved(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)453 void AccessibilityWindowManager::WindowUpdateRemoved(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
454 {
455 HILOG_DEBUG();
456 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
457 for (auto &windowInfo : infos) {
458 if (!windowInfo) {
459 HILOG_ERROR("invalid windowInfo");
460 return;
461 }
462
463 int32_t realWidId = GetRealWindowId(windowInfo);
464 if (!a11yWindows_.count(realWidId)) {
465 return;
466 }
467 if (realWidId == activeWindowId_) {
468 SetActiveWindow(INVALID_WINDOW_ID);
469 }
470 if (realWidId == a11yFocusedWindowId_) {
471 SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
472 }
473 a11yWindows_.erase(realWidId);
474 subWindows_.erase(realWidId);
475 sceneBoardElementIdMap_.RemovePair(realWidId);
476 AccessibilityEventInfo evtInfRemoved(realWidId, WINDOW_UPDATE_REMOVED);
477 aams.SendEvent(evtInfRemoved);
478 }
479 }
480
WindowUpdateFocused(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)481 void AccessibilityWindowManager::WindowUpdateFocused(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
482 {
483 HILOG_DEBUG();
484 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
485 for (auto &windowInfo : infos) {
486 if (!windowInfo) {
487 HILOG_ERROR("invalid windowInfo");
488 return;
489 }
490
491 int32_t realWidId = GetRealWindowId(windowInfo);
492 if (!a11yWindows_.count(realWidId)) {
493 HILOG_WARN("window not created");
494 auto a11yWindowInfoFocused = CreateAccessibilityWindowInfo(windowInfo);
495 a11yWindows_.emplace(realWidId, a11yWindowInfoFocused);
496 }
497
498 if (IsSceneBoard(windowInfo)) {
499 subWindows_.insert(realWidId);
500 sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
501 }
502 SetActiveWindow(realWidId);
503 AccessibilityEventInfo evtInfFocused(realWidId, WINDOW_UPDATE_FOCUSED);
504 aams.SendEvent(evtInfFocused);
505 }
506 }
507
WindowUpdateBounds(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)508 void AccessibilityWindowManager::WindowUpdateBounds(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
509 {
510 HILOG_DEBUG();
511 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
512 for (auto &windowInfo : infos) {
513 if (!windowInfo) {
514 HILOG_ERROR("invalid windowInfo");
515 return;
516 }
517
518 int32_t realWidId = GetRealWindowId(windowInfo);
519 if (a11yWindows_.count(realWidId)) {
520 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
521 }
522
523 AccessibilityEventInfo evtInfBounds(realWidId, WINDOW_UPDATE_BOUNDS);
524 aams.SendEvent(evtInfBounds);
525 }
526 }
527
WindowUpdateActive(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)528 void AccessibilityWindowManager::WindowUpdateActive(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
529 {
530 HILOG_DEBUG();
531 for (auto &windowInfo : infos) {
532 if (!windowInfo) {
533 HILOG_ERROR("invalid windowInfo");
534 return;
535 }
536
537 int32_t realWidId = GetRealWindowId(windowInfo);
538 if (!a11yWindows_.count(realWidId)) {
539 auto a11yWindowInfoActive = CreateAccessibilityWindowInfo(windowInfo);
540 a11yWindows_.emplace(realWidId, a11yWindowInfoActive);
541 }
542
543 if (IsSceneBoard(windowInfo)) {
544 subWindows_.insert(realWidId);
545 sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
546 }
547 SetActiveWindow(realWidId);
548 }
549 }
550
WindowUpdateProperty(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)551 void AccessibilityWindowManager::WindowUpdateProperty(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
552 {
553 HILOG_DEBUG();
554 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
555 for (auto &windowInfo : infos) {
556 if (!windowInfo) {
557 HILOG_ERROR("invalid windowInfo");
558 return;
559 }
560
561 int32_t realWidId = GetRealWindowId(windowInfo);
562 if (a11yWindows_.count(realWidId)) {
563 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
564 }
565 AccessibilityEventInfo evtInfProperty(realWidId, WINDOW_UPDATE_PROPERTY);
566 aams.SendEvent(evtInfProperty);
567 }
568 }
569
ClearOldActiveWindow()570 void AccessibilityWindowManager::ClearOldActiveWindow()
571 {
572 HILOG_DEBUG("active window id is %{public}d", activeWindowId_);
573 if (activeWindowId_ == INVALID_WINDOW_ID) {
574 HILOG_DEBUG("active window id is invalid");
575 return;
576 }
577
578 if (a11yWindows_.count(activeWindowId_)) {
579 a11yWindows_[activeWindowId_].SetActive(false);
580 }
581 if (activeWindowId_ == a11yFocusedWindowId_) {
582 HILOG_DEBUG("Old active window is a11yFocused window.");
583 SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
584 }
585 }
586
ClearAccessibilityFocused()587 void AccessibilityWindowManager::ClearAccessibilityFocused()
588 {
589 HILOG_DEBUG("a11yFocused window id is %{public}d", a11yFocusedWindowId_);
590 if (a11yFocusedWindowId_ == INVALID_WINDOW_ID) {
591 HILOG_DEBUG("a11yFocused window id is invalid");
592 return;
593 }
594
595 if (a11yWindows_.count(a11yFocusedWindowId_)) {
596 a11yWindows_[a11yFocusedWindowId_].SetAccessibilityFocused(false);
597 }
598
599 int32_t windowId = a11yFocusedWindowId_;
600 if (subWindows_.count(a11yFocusedWindowId_)) {
601 windowId = SCENE_BOARD_WINDOW_ID;
602 }
603 sptr<AccessibilityAccountData> accountData =
604 Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
605 if (!accountData) {
606 HILOG_ERROR("accountData is nullptr");
607 return;
608 }
609 sptr<AccessibilityWindowConnection> connection =
610 accountData->GetAccessibilityWindowConnection(windowId);
611 if (!connection) {
612 HILOG_ERROR("windowId[%{public}d] has no connection", windowId);
613 return;
614 }
615 if (!connection->GetProxy()) {
616 HILOG_ERROR("windowId[%{public}d] has no proxy", windowId);
617 return;
618 }
619 connection->GetProxy()->ClearFocus();
620
621 // Send event
622 AccessibilityEventInfo eventInfo(TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT);
623 eventInfo.SetWindowId(a11yFocusedWindowId_);
624 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
625 }
626
GetSceneBoardElementId(const int32_t windowId,const int64_t elementId)627 int64_t AccessibilityWindowManager::GetSceneBoardElementId(const int32_t windowId, const int64_t elementId)
628 {
629 if (elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
630 return elementId;
631 }
632 if (subWindows_.count(windowId)) {
633 auto iter = a11yWindows_.find(windowId);
634 if (iter != a11yWindows_.end()) {
635 HILOG_DEBUG("GetSceneBoardElementId [%{public}" PRId64 "]", iter->second.GetUiNodeId());
636 return iter->second.GetUiNodeId();
637 }
638 }
639 return elementId;
640 }
641
GetRealWindowAndElementId(int32_t & windowId,int64_t & elementId)642 void AccessibilityWindowManager::GetRealWindowAndElementId(int32_t& windowId, int64_t& elementId)
643 {
644 // sceneboard window id, element id is not equal -1
645 if (subWindows_.count(windowId) && elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
646 windowId = SCENE_BOARD_WINDOW_ID;
647 HILOG_INFO("windowId %{public}d, elementId %{public}" PRId64 "", windowId, elementId);
648 return;
649 }
650
651 if (elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
652 return;
653 }
654
655 if (subWindows_.count(windowId)) {
656 auto iter = a11yWindows_.find(windowId);
657 if (iter != a11yWindows_.end()) {
658 HILOG_DEBUG("GetRealWindowAndElementId [%{public}" PRId64 "]", iter->second.GetUiNodeId());
659 windowId = SCENE_BOARD_WINDOW_ID;
660 elementId = iter->second.GetUiNodeId();
661 return;
662 }
663 }
664 }
665
GetSceneBoardInnerWinId(int32_t windowId,int64_t elementId,int32_t & innerWid)666 void AccessibilityWindowManager::GetSceneBoardInnerWinId(int32_t windowId, int64_t elementId,
667 int32_t& innerWid)
668 {
669 if (windowId != SCENE_BOARD_WINDOW_ID) {
670 return;
671 }
672
673 for (auto iter = a11yWindows_.begin(); iter != a11yWindows_.end(); iter++) {
674 if (iter->second.GetUiNodeId() == elementId) {
675 innerWid = iter->second.GetInnerWid();
676 }
677 }
678
679 return;
680 }
681
InsertPair(const int32_t windowId,const int64_t elementId)682 void AccessibilityWindowManager::SceneBoardElementIdMap::InsertPair(const int32_t windowId, const int64_t elementId)
683 {
684 std::lock_guard<std::mutex> lock(mapMutex_);
685 windowElementMap_[windowId] = elementId;
686 }
687
RemovePair(const int32_t windowId)688 void AccessibilityWindowManager::SceneBoardElementIdMap::RemovePair(const int32_t windowId)
689 {
690 std::lock_guard<std::mutex> lock(mapMutex_);
691 windowElementMap_.erase(windowId);
692 }
693
Clear()694 void AccessibilityWindowManager::SceneBoardElementIdMap::Clear()
695 {
696 std::lock_guard<std::mutex> lock(mapMutex_);
697 windowElementMap_.clear();
698 }
699
GetAllPairs()700 std::map<int32_t, int64_t> AccessibilityWindowManager::SceneBoardElementIdMap::GetAllPairs()
701 {
702 std::lock_guard<std::mutex> lock(mapMutex_);
703 return windowElementMap_;
704 }
705
GetFocusedWindowId(int32_t & focusedWindowId)706 RetError AccessibilityWindowManager::GetFocusedWindowId(int32_t &focusedWindowId)
707 {
708 HILOG_DEBUG();
709 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryFocusedWindowInfo");
710 Rosen::FocusChangeInfo focusedWindowInfo;
711 OHOS::Rosen::WindowManager::GetInstance().GetFocusWindowInfo(focusedWindowInfo);
712 if (focusedWindowInfo.windowId_ == INVALID_WINDOW_ID) {
713 return RET_ERR_INVALID_PARAM;
714 }
715 focusedWindowId = focusedWindowInfo.windowId_;
716 return RET_OK;
717 }
718 } // namespace Accessibility
719 } // namespace OHOS