1 /*
2 * Copyright (C) 2022-2025 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 #ifdef OHOS_BUILD_ENABLE_HITRACE
19 #include <hitrace_meter.h>
20 #endif // OHOS_BUILD_ENABLE_HITRACE
21
22 #include "accessible_ability_manager_service.h"
23 #include "hilog_wrapper.h"
24 #include "utils.h"
25 #include "xcollie_helper.h"
26
27 namespace OHOS {
28 namespace Accessibility {
29 namespace {
30 const std::string TIMER_GET_ACCESSIBILITY_WINDOWS = "accessibilty:getAccessibilityWindowInfo";
31 const std::string SCB_SCENE_PANEL = "SCBScenePanel";
32 constexpr int32_t WMS_TIMEOUT = 10; // s
33 }
34
AccessibilityWindowManager()35 AccessibilityWindowManager::AccessibilityWindowManager()
36 {
37 }
38
Init()39 bool AccessibilityWindowManager::Init()
40 {
41 DeInit();
42 HILOG_DEBUG("deinit before start");
43 #ifdef OHOS_BUILD_ENABLE_HITRACE
44 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryWindowInfo");
45 #endif // OHOS_BUILD_ENABLE_HITRACE
46 std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
47 Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(windowInfos);
48 if (err != Rosen::WMError::WM_OK) {
49 Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
50 HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
51 return false;
52 }
53 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
54 HILOG_DEBUG("windowInfos size is %{public}zu", windowInfos.size());
55 for (auto &window : windowInfos) {
56 if (!window) {
57 HILOG_ERROR("window is nullptr");
58 continue;
59 }
60
61 int32_t realWid = GetRealWindowId(window);
62 if (!a11yWindows_.count(realWid)) {
63 auto a11yWindowInfo = CreateAccessibilityWindowInfo(window);
64 a11yWindows_.emplace(realWid, a11yWindowInfo);
65 }
66
67 if (IsSceneBoard(window)) {
68 subWindows_.insert(realWid);
69 sceneBoardElementIdMap_.InsertPair(realWid, window->uiNodeId_);
70 }
71
72 if (a11yWindows_[realWid].IsFocused()) {
73 SetActiveWindow(realWid);
74 }
75 }
76 return true;
77 }
78
DeInit()79 void AccessibilityWindowManager::DeInit()
80 {
81 HILOG_DEBUG();
82 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
83 a11yWindows_.clear();
84 subWindows_.clear();
85 sceneBoardElementIdMap_.Clear();
86 activeWindowId_ = INVALID_WINDOW_ID;
87 a11yFocusedWindowId_ = INVALID_WINDOW_ID;
88 }
89
WinDeInit()90 void AccessibilityWindowManager::WinDeInit()
91 {
92 HILOG_DEBUG();
93 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
94 a11yWindows_.clear();
95 sceneBoardElementIdMap_.Clear();
96 activeWindowId_ = INVALID_WINDOW_ID;
97 }
98
~AccessibilityWindowManager()99 AccessibilityWindowManager::~AccessibilityWindowManager()
100 {
101 DeregisterWindowListener();
102 }
103
RegisterWindowListener(const std::shared_ptr<AppExecFwk::EventHandler> & handler)104 void AccessibilityWindowManager::RegisterWindowListener(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
105 {
106 DeregisterWindowListener();
107 HILOG_DEBUG("deregister before register");
108 if (windowListener_) {
109 HILOG_DEBUG("Window listener is already registered!");
110 return;
111 }
112
113 eventHandler_ = handler;
114 windowListener_ = new(std::nothrow) AccessibilityWindowListener(*this);
115 if (!windowListener_) {
116 HILOG_ERROR("Create window listener fail!");
117 return;
118 }
119 OHOS::Rosen::WindowManager::GetInstance().RegisterWindowUpdateListener(windowListener_);
120 }
121
DeregisterWindowListener()122 void AccessibilityWindowManager::DeregisterWindowListener()
123 {
124 if (windowListener_) {
125 OHOS::Rosen::WindowManager::GetInstance().UnregisterWindowUpdateListener(windowListener_);
126 windowListener_ = nullptr;
127 eventHandler_ = nullptr;
128 }
129 }
130
OnWindowUpdate(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos,Rosen::WindowUpdateType type)131 void AccessibilityWindowManager::OnWindowUpdate(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos,
132 Rosen::WindowUpdateType type)
133 {
134 HILOG_DEBUG("WindowUpdateType type[%{public}d]", type);
135 if (!eventHandler_) {
136 HILOG_ERROR("eventHandler_ is nullptr.");
137 return;
138 }
139 if (infos.size() == 0) {
140 HILOG_ERROR("window info is err");
141 return;
142 }
143 eventHandler_->PostTask([=]() {
144 switch (type) {
145 case Rosen::WindowUpdateType::WINDOW_UPDATE_ADDED: // 1
146 WindowUpdateAdded(infos);
147 break;
148 case Rosen::WindowUpdateType::WINDOW_UPDATE_REMOVED: // 2
149 WindowUpdateRemoved(infos);
150 break;
151 case Rosen::WindowUpdateType::WINDOW_UPDATE_BOUNDS: // 4
152 WindowUpdateBounds(infos);
153 break;
154 case Rosen::WindowUpdateType::WINDOW_UPDATE_ACTIVE: // 5
155 WindowUpdateActive(infos);
156 break;
157 case Rosen::WindowUpdateType::WINDOW_UPDATE_FOCUSED: // 3
158 WindowUpdateFocused(infos);
159 break;
160 case Rosen::WindowUpdateType::WINDOW_UPDATE_PROPERTY: // 6
161 WindowUpdateProperty(infos);
162 break;
163 case Rosen::WindowUpdateType::WINDOW_UPDATE_ALL:
164 WindowUpdateAll(infos);
165 break;
166 default:
167 break;
168 }
169 HILOG_DEBUG("a11yWindows[%{public}zu]", a11yWindows_.size());
170 }, "TASK_ON_WINDOW_UPDATE");
171 }
172
ConvertToRealWindowId(int32_t windowId,int32_t focusType)173 int32_t AccessibilityWindowManager::ConvertToRealWindowId(int32_t windowId, int32_t focusType)
174 {
175 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
176 int32_t winId = windowId;
177 HILOG_DEBUG("ConvertToRealWindowId called, windowId[%{public}d], focusType[%{public}d]", windowId, focusType);
178 if (windowId == ACTIVE_WINDOW_ID) {
179 HILOG_DEBUG("After convert active windowId[%{public}d]", activeWindowId_);
180 winId = activeWindowId_;
181 }
182
183 if (windowId == ANY_WINDOW_ID) {
184 if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
185 HILOG_DEBUG("After convert a11yFocused windowId[%{public}d] by accessibility type", a11yFocusedWindowId_);
186 winId = a11yFocusedWindowId_;
187 } else if (focusType == FOCUS_TYPE_INPUT) {
188 HILOG_DEBUG("After convert active windowId[%{public}d] by input type", activeWindowId_);
189 winId = activeWindowId_;
190 }
191 }
192
193 if (subWindows_.count(winId)) {
194 HILOG_DEBUG("After convert normal windowId[%{public}d]", SCENE_BOARD_WINDOW_ID);
195 return SCENE_BOARD_WINDOW_ID;
196 }
197 HILOG_DEBUG("After convert windowId[%{public}d] and activeId[%{public}d]", winId, activeWindowId_);
198 return winId;
199 }
200
ConvertWindowType(Rosen::WindowType type)201 AccessibilityWindowType ConvertWindowType(Rosen::WindowType type)
202 {
203 AccessibilityWindowType winType = TYPE_WINDOW_INVALID;
204
205 if (type < Rosen::WindowType::SYSTEM_WINDOW_BASE) {
206 winType = TYPE_APPLICATION;
207 } else if ((type >= Rosen::WindowType::SYSTEM_WINDOW_BASE) && (type <= Rosen::WindowType::SYSTEM_WINDOW_END)) {
208 winType = TYPE_SYSTEM;
209 } else {
210 HILOG_ERROR("Unknown windowType[%{public}d]", type);
211 }
212 return winType;
213 }
214
CheckIntegerOverflow(const Rosen::Rect & rect)215 bool AccessibilityWindowManager::CheckIntegerOverflow(const Rosen::Rect& rect)
216 {
217 if ((rect.posX_ > 0) && (static_cast<int32_t>(rect.width_) > 0)) {
218 int32_t leftX = INT32_MAX - rect.posX_;
219 if (leftX < static_cast<int32_t>(rect.width_)) {
220 HILOG_ERROR("input parameter invalid posX %{public}d, width_ %{public}u", rect.posX_,
221 rect.width_);
222 return false;
223 }
224 }
225
226 if ((rect.posX_ < 0) && (static_cast<int32_t>(rect.width_) < 0)) {
227 int32_t leftX = INT32_MIN - rect.posX_;
228 if (leftX > static_cast<int32_t>(rect.width_)) {
229 HILOG_ERROR("input parameter invalid posX %{public}d, width_ %{public}u", rect.posX_,
230 rect.width_);
231 return false;
232 }
233 }
234
235 if ((rect.posY_ > 0) && (static_cast<int32_t>(rect.height_) > 0)) {
236 int32_t leftY = INT32_MAX - rect.posY_;
237 if (leftY < static_cast<int32_t>(rect.height_)) {
238 HILOG_ERROR("input parameter invalid posX %{public}d, height_ %{public}u", rect.posY_,
239 rect.height_);
240 return false;
241 }
242 }
243
244 if ((rect.posY_ < 0) && (static_cast<int32_t>(rect.height_) < 0)) {
245 int32_t leftY = INT32_MIN - rect.posY_;
246 if (leftY > static_cast<int32_t>(rect.height_)) {
247 HILOG_ERROR("input parameter invalid posX %{public}d, height_ %{public}u", rect.posY_,
248 rect.height_);
249 return false;
250 }
251 }
252 return true;
253 }
254
UpdateAccessibilityWindowInfo(AccessibilityWindowInfo & accWindowInfo,const sptr<Rosen::AccessibilityWindowInfo> windowInfo)255 void AccessibilityWindowManager::UpdateAccessibilityWindowInfo(AccessibilityWindowInfo &accWindowInfo,
256 const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
257 {
258 accWindowInfo.SetScaleVal(windowInfo->scaleVal_);
259 accWindowInfo.SetScaleX(windowInfo->scaleX_);
260 accWindowInfo.SetScaleY(windowInfo->scaleY_);
261 accWindowInfo.SetWindowId(windowInfo->wid_);
262 accWindowInfo.SetMainWindowId(windowInfo->wid_);
263 accWindowInfo.SetWindowType(static_cast<uint32_t>(windowInfo->type_));
264 accWindowInfo.SetWindowMode(static_cast<uint32_t>(windowInfo->mode_));
265 accWindowInfo.SetAccessibilityWindowType(ConvertWindowType(windowInfo->type_));
266 accWindowInfo.SetFocused(windowInfo->focused_);
267 accWindowInfo.SetWindowLayer(windowInfo->layer_);
268 if (static_cast<int32_t>(windowInfo->type_) == 1 && (static_cast<int32_t>(windowInfo->windowRect_.width_) == 0 ||
269 static_cast<int32_t>(windowInfo->windowRect_.height_) == 0)) {
270 HILOG_WARN("invalid window parameters, windowId(%{public}d), posX(%{public}d, posY(%{public}d))",
271 windowInfo->wid_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
272 } else {
273 Rect bound;
274 bound.SetLeftTopScreenPostion(windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
275 if (!CheckIntegerOverflow(windowInfo->windowRect_)) {
276 bound.SetRightBottomScreenPostion(windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
277 } else {
278 bound.SetRightBottomScreenPostion(
279 windowInfo->windowRect_.posX_ + static_cast<int32_t>(windowInfo->windowRect_.width_),
280 windowInfo->windowRect_.posY_ + static_cast<int32_t>(windowInfo->windowRect_.height_));
281 }
282 accWindowInfo.SetRectInScreen(bound);
283 }
284 accWindowInfo.SetDisplayId(windowInfo->displayId_);
285 accWindowInfo.SetDecorEnable(windowInfo->isDecorEnable_);
286 accWindowInfo.SetUiNodeId(windowInfo->uiNodeId_);
287 accWindowInfo.SetInnerWid(windowInfo->innerWid_);
288 if (accWindowInfo.GetWindowId() == SCENE_BOARD_WINDOW_ID) {
289 accWindowInfo.SetWindowId(windowInfo->innerWid_);
290 accWindowInfo.SetMainWindowId(windowInfo->innerWid_);
291 HILOG_DEBUG("scene board window id 1 convert inner window id[%{public}d]", windowInfo->innerWid_);
292 }
293 HILOG_DEBUG("bundle name is [%{public}s] , touchHotAreas size(%{public}zu)",
294 windowInfo->bundleName_.c_str(), windowInfo->touchHotAreas_.size());
295 accWindowInfo.SetBundleName(windowInfo->bundleName_);
296 HILOG_DEBUG("UpdateAccessibilityWindowInfo is set bundlename is [%{public}s]",
297 accWindowInfo.GetBundleName().c_str());
298 std::vector<Rect> tempTouchHotAreas = {};
299 for (auto &rect : windowInfo->touchHotAreas_) {
300 HILOG_DEBUG("Rosen::windowinfo x:[%{public}d], y:[%{public}d]; width:[%{public}d], height:[%{public}d]",
301 rect.posX_, rect.posY_, rect.width_, rect.height_);
302 Rect rectTemp;
303 rectTemp.SetLeftTopScreenPostion(rect.posX_, rect.posY_);
304 if (!CheckIntegerOverflow(rect)) {
305 rectTemp.SetRightBottomScreenPostion(rect.posX_, rect.posY_);
306 } else {
307 rectTemp.SetRightBottomScreenPostion(
308 rect.posX_ + static_cast<int32_t>(rect.width_),
309 rect.posY_ + static_cast<int32_t>(rect.height_));
310 }
311 tempTouchHotAreas.push_back(rectTemp);
312 }
313 accWindowInfo.SetTouchHotAreas(tempTouchHotAreas);
314 for (auto &outRect : accWindowInfo.GetTouchHotAreas()) {
315 HILOG_DEBUG("left_x:[%{public}d], left_y:[%{public}d]; right_x:[%{public}d], right_y:[%{public}d]",
316 outRect.GetLeftTopXScreenPostion(), outRect.GetLeftTopYScreenPostion(),
317 outRect.GetRightBottomXScreenPostion(), outRect.GetRightBottomYScreenPostion());
318 }
319 }
320
GetRealWindowId(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)321 int32_t AccessibilityWindowManager::GetRealWindowId(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
322 {
323 if (windowInfo->wid_ == SCENE_BOARD_WINDOW_ID) {
324 return windowInfo->innerWid_;
325 }
326 return windowInfo->wid_;
327 }
328
IsSceneBoard(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)329 bool AccessibilityWindowManager::IsSceneBoard(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
330 {
331 if (windowInfo->wid_ == SCENE_BOARD_WINDOW_ID) {
332 return true;
333 }
334 return false;
335 }
336
IsScenePanel(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)337 bool AccessibilityWindowManager::IsScenePanel(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
338 {
339 return windowInfo->bundleName_.find(SCB_SCENE_PANEL) != std::string::npos;
340 }
341
CreateAccessibilityWindowInfo(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)342 AccessibilityWindowInfo AccessibilityWindowManager::CreateAccessibilityWindowInfo(
343 const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
344 {
345 AccessibilityWindowInfo info;
346 UpdateAccessibilityWindowInfo(info, windowInfo);
347 HILOG_DEBUG("Create WindowInfo Id(%{public}d) type(%{public}d) posX(%{public}d) posY(%{public}d)"
348 "witdth(%{public}d) height(%{public}d) display id(%{public}" PRIu64 ") isDecorEnable(%{public}d)"
349 "innerWid(%{public}d), uiNodeId(%{public}d)",
350 windowInfo->wid_, windowInfo->type_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_,
351 windowInfo->windowRect_.width_, windowInfo->windowRect_.height_, windowInfo->displayId_,
352 windowInfo->isDecorEnable_, windowInfo->innerWid_, windowInfo->uiNodeId_);
353 return info;
354 }
355
CheckEvents()356 bool AccessibilityWindowManager::CheckEvents()
357 {
358 sptr<AccessibilityAccountData> accountData =
359 Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
360 if (!accountData) {
361 HILOG_ERROR("accountData is nullptr");
362 return false;
363 }
364 std::vector<uint32_t> needEvents;
365 needEvents = accountData->GetNeedEvents();
366
367 auto isExit = std::find(needEvents.begin(), needEvents.end(), TYPE_WINDOW_UPDATE);
368 auto isAllEvent = std::find(needEvents.begin(), needEvents.end(), TYPES_ALL_MASK);
369 if (isAllEvent != needEvents.end() || isExit != needEvents.end()) {
370 return true;
371 }
372 return false;
373 }
374
SetActiveWindow(int32_t windowId,bool isSendEvent)375 void AccessibilityWindowManager::SetActiveWindow(int32_t windowId, bool isSendEvent)
376 {
377 HILOG_INFO("windowId is %{public}d, activeWindowId_: %{public}d", windowId, activeWindowId_);
378 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
379 if (windowId == INVALID_WINDOW_ID) {
380 ClearOldActiveWindow();
381 activeWindowId_ = INVALID_WINDOW_ID;
382 return;
383 }
384
385 if (!a11yWindows_.count(windowId)) {
386 HILOG_WARN("Window id is not found");
387 return;
388 }
389
390 bool isSendWindowEvent = CheckEvents();
391 HILOG_DEBUG("isSendWindowEvent is: %{public}d", isSendWindowEvent);
392 if (!isSendWindowEvent) {
393 isSendEvent = false;
394 }
395
396 if (activeWindowId_ != windowId) {
397 ClearOldActiveWindow();
398 activeWindowId_ = windowId;
399 a11yWindows_[activeWindowId_].SetActive(true);
400 if (!isSendEvent) {
401 HILOG_DEBUG("not send event, activeWindowId is %{public}d", activeWindowId_);
402 return;
403 }
404 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
405 AccessibilityEventInfo evtInf(activeWindowId_, WINDOW_UPDATE_ACTIVE);
406 AccessibilityEventInfoParcel evtInfParcel(evtInf);
407 int32_t winId = windowId;
408 if (sceneBoardElementIdMap_.CheckWindowIdPair(windowId)) {
409 winId = SCENE_BOARD_WINDOW_ID;
410 }
411 SetEventInfoBundleName(evtInfParcel);
412 if (aams.CheckWindowRegister(winId)) {
413 HILOG_DEBUG("send active event, windowId: %{public}d", winId);
414 aams.SendEvent(evtInfParcel, 0);
415 } else {
416 HILOG_DEBUG("wait for window register to process event, windowId: %{public}d", winId);
417 aams.InsertWindowIdEventPair(winId, evtInfParcel);
418 }
419 }
420 HILOG_DEBUG("activeWindowId is %{public}d", activeWindowId_);
421 }
422
GetActiveWindowId()423 int32_t AccessibilityWindowManager::GetActiveWindowId()
424 {
425 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
426 HILOG_DEBUG("activeWindowId_ is %{public}d", activeWindowId_);
427 return activeWindowId_;
428 }
429
SetAccessibilityFocusedWindow(int32_t windowId)430 void AccessibilityWindowManager::SetAccessibilityFocusedWindow(int32_t windowId)
431 {
432 HILOG_DEBUG("windowId is %{public}d", windowId);
433 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
434 if (windowId == INVALID_WINDOW_ID) {
435 ClearAccessibilityFocused();
436 a11yFocusedWindowId_ = INVALID_WINDOW_ID;
437 return;
438 }
439
440 if (!a11yWindows_.count(windowId)) {
441 HILOG_ERROR("Window id[%{public}d] is not found", windowId);
442 return;
443 }
444
445 if (a11yFocusedWindowId_ != windowId) {
446 ClearAccessibilityFocused();
447 a11yFocusedWindowId_ = windowId;
448 a11yWindows_[a11yFocusedWindowId_].SetAccessibilityFocused(true);
449 }
450 HILOG_DEBUG("a11yFocusedWindowId_ is %{public}d", a11yFocusedWindowId_);
451 }
452
GetAccessibilityWindows()453 std::vector<AccessibilityWindowInfo> AccessibilityWindowManager::GetAccessibilityWindows()
454 {
455 HILOG_DEBUG("a11yWindows_ size[%{public}zu]", a11yWindows_.size());
456 XCollieHelper timer(TIMER_GET_ACCESSIBILITY_WINDOWS, WMS_TIMEOUT);
457 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
458 std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
459 std::vector<AccessibilityWindowInfo> windows;
460 Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(windowInfos);
461 if (err != Rosen::WMError::WM_OK) {
462 Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
463 HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
464 return windows;
465 }
466 for (auto &info : windowInfos) {
467 if (info == nullptr) {
468 continue;
469 }
470 AccessibilityWindowInfo tmpWindowInfo;
471 UpdateAccessibilityWindowInfo(tmpWindowInfo, info);
472 if (tmpWindowInfo.IsFocused()) {
473 HILOG_DEBUG("set active windowId: %{public}d", tmpWindowInfo.GetWindowId());
474 tmpWindowInfo.SetActive(true);
475 }
476 windows.push_back(tmpWindowInfo);
477 }
478 return windows;
479 }
480
GetAccessibilityWindow(int32_t windowId,AccessibilityWindowInfo & window)481 bool AccessibilityWindowManager::GetAccessibilityWindow(int32_t windowId, AccessibilityWindowInfo &window)
482 {
483 HILOG_DEBUG("start windowId(%{public}d)", windowId);
484 XCollieHelper timer(TIMER_GET_ACCESSIBILITY_WINDOWS, WMS_TIMEOUT);
485 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
486 std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
487 Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(windowInfos);
488 if (err != Rosen::WMError::WM_OK) {
489 Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
490 HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
491 return false;
492 }
493 for (auto &info : windowInfos) {
494 if (info == nullptr) {
495 continue;
496 }
497
498 int32_t realWidId = GetRealWindowId(info);
499 if (a11yWindows_.count(realWidId)) {
500 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], info);
501 } else {
502 AccessibilityWindowInfo tmpWindowInfo;
503 UpdateAccessibilityWindowInfo(tmpWindowInfo, info);
504 a11yWindows_[realWidId] = tmpWindowInfo;
505 }
506 }
507 if (a11yWindows_.count(windowId)) {
508 window = a11yWindows_[windowId];
509 return true;
510 }
511 return false;
512 }
513
IsValidWindow(int32_t windowId)514 bool AccessibilityWindowManager::IsValidWindow(int32_t windowId)
515 {
516 HILOG_DEBUG("start windowId(%{public}d)", windowId);
517 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
518 auto it = std::find_if(a11yWindows_.begin(), a11yWindows_.end(),
519 [windowId](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) {
520 return window.first == windowId;
521 });
522 if (it == a11yWindows_.end()) {
523 return false;
524 }
525 return true;
526 }
527
SetWindowSize(int32_t windowId,Rect rect)528 void AccessibilityWindowManager::SetWindowSize(int32_t windowId, Rect rect)
529 {
530 HILOG_DEBUG("start windowId(%{public}d)", windowId);
531 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
532 auto it = std::find_if(a11yWindows_.begin(), a11yWindows_.end(),
533 [windowId](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) {
534 return window.first == windowId;
535 });
536 if (it != a11yWindows_.end()) {
537 it->second.SetRectInScreen(rect);
538 }
539 }
540
CompareRect(const Rect & rectAccessibility,const Rosen::Rect & rectWindow)541 bool AccessibilityWindowManager::CompareRect(const Rect &rectAccessibility, const Rosen::Rect &rectWindow)
542 {
543 HILOG_DEBUG();
544 int32_t leftTopX_ = rectWindow.posX_;
545 int32_t leftTopY_ = rectWindow.posY_;
546 int32_t rightBottomX_ = 0;
547 int32_t rightBottomY_ = 0;
548
549 if (!CheckIntegerOverflow(rectWindow)) {
550 rightBottomX_ = rectWindow.posX_;
551 rightBottomY_ = rectWindow.posY_;
552 } else {
553 rightBottomX_ = rectWindow.posX_ + static_cast<int32_t>(rectWindow.width_);
554 rightBottomY_ = rectWindow.posY_ + static_cast<int32_t>(rectWindow.height_);
555 }
556
557 if (rectAccessibility.GetLeftTopXScreenPostion() == leftTopX_ &&
558 rectAccessibility.GetLeftTopYScreenPostion() == leftTopY_ &&
559 rectAccessibility.GetRightBottomXScreenPostion() == rightBottomX_ &&
560 rectAccessibility.GetRightBottomYScreenPostion() == rightBottomY_) {
561 HILOG_DEBUG("rect values are the same");
562 return false;
563 }
564 return true;
565 }
566
EqualFocus(const Accessibility::AccessibilityWindowInfo & accWindowInfo,const sptr<Rosen::AccessibilityWindowInfo> & windowInfo)567 bool AccessibilityWindowManager::EqualFocus(const Accessibility::AccessibilityWindowInfo &accWindowInfo,
568 const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
569 {
570 HILOG_DEBUG();
571 if (accWindowInfo.IsFocused() == windowInfo->focused_) {
572 HILOG_DEBUG("focus values are the same");
573 return false;
574 }
575 return windowInfo->focused_;
576 }
577
EqualBound(const Accessibility::AccessibilityWindowInfo & accWindowInfo,const sptr<Rosen::AccessibilityWindowInfo> & windowInfo)578 bool AccessibilityWindowManager::EqualBound(const Accessibility::AccessibilityWindowInfo &accWindowInfo,
579 const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
580 {
581 HILOG_DEBUG();
582 if (static_cast<int32_t>(windowInfo->type_) == 1 && (static_cast<int32_t>(windowInfo->windowRect_.width_) == 0 ||
583 static_cast<int32_t>(windowInfo->windowRect_.height_) == 0)) {
584 HILOG_ERROR("invalid window parameters, windowId(%{public}d), posX(%{public}d, posY(%{public}d))",
585 windowInfo->wid_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
586 return false;
587 }
588 return CompareRect(accWindowInfo.GetRectInScreen(), windowInfo->windowRect_);
589 }
590
EqualProperty(Accessibility::AccessibilityWindowInfo & accWindowInfo,const sptr<Rosen::AccessibilityWindowInfo> & windowInfo)591 bool AccessibilityWindowManager::EqualProperty(Accessibility::AccessibilityWindowInfo &accWindowInfo,
592 const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
593 {
594 HILOG_DEBUG();
595 std::ostringstream accInfoStr;
596 std::ostringstream winInfoStr;
597
598 accInfoStr << accWindowInfo.GetWindowMode()
599 << accWindowInfo.GetWindowLayer()
600 << accWindowInfo.IsDecorEnable()
601 << accWindowInfo.GetWindowType()
602 << accWindowInfo.GetDisplayId()
603 << accWindowInfo.GetScaleVal()
604 << accWindowInfo.GetScaleX()
605 << accWindowInfo.GetScaleY();
606 HILOG_DEBUG("Create accinfoStr windowMode_[%{public}d] Layer_[%{public}d] isDecorEnable_[%{public}d]"
607 "windowType_[%{public}d] displayId:%{public}" PRIu64 " get scaleVal_ [%{public}f]"
608 "get scaleX_ [%{public}f] get scaleY_ [%{public}f]",
609 accWindowInfo.GetWindowMode(), accWindowInfo.GetWindowLayer(), accWindowInfo.IsDecorEnable(),
610 accWindowInfo.GetWindowType(), accWindowInfo.GetDisplayId(), accWindowInfo.GetScaleVal(),
611 accWindowInfo.GetScaleX(), accWindowInfo.GetScaleY());
612
613 winInfoStr << static_cast<uint32_t>(windowInfo->mode_)
614 << windowInfo->layer_
615 << windowInfo->isDecorEnable_
616 << static_cast<uint32_t>(windowInfo->type_)
617 << windowInfo->displayId_
618 << windowInfo->scaleVal_
619 << windowInfo->scaleX_
620 << windowInfo->scaleY_;
621 HILOG_DEBUG("Create wininfoStr Mode_[%{public}d] Layer_[%{public}d] isDecorEnable_[%{public}d]"
622 "Type_[%{public}d] displayId:%{public}" PRIu64 " scaleVal_ [%{public}f]"
623 "scaleX_ [%{public}f] scaleY_ [%{public}f]",
624 static_cast<uint32_t>(windowInfo->mode_), windowInfo->layer_, windowInfo->isDecorEnable_,
625 static_cast<uint32_t>(windowInfo->type_), windowInfo->displayId_, windowInfo->scaleVal_,
626 windowInfo->scaleX_, windowInfo->scaleY_);
627
628 if (accInfoStr.str() != winInfoStr.str() ||
629 windowInfo->touchHotAreas_.size() != accWindowInfo.GetTouchHotAreas().size()) {
630 HILOG_DEBUG("Property different");
631 return true;
632 }
633 for (uint32_t i = 0; i < accWindowInfo.GetTouchHotAreas().size(); i++) {
634 if (CompareRect(accWindowInfo.GetTouchHotAreas()[i], windowInfo->touchHotAreas_[i])) {
635 HILOG_DEBUG("touchHotAreas different");
636 return true;
637 }
638 }
639 return false;
640 }
641
EqualLayer(const Accessibility::AccessibilityWindowInfo & accWindowInfo,const sptr<Rosen::AccessibilityWindowInfo> & windowInfo)642 bool AccessibilityWindowManager::EqualLayer(const Accessibility::AccessibilityWindowInfo &accWindowInfo,
643 const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
644 {
645 HILOG_DEBUG();
646 if (static_cast<uint32_t>(accWindowInfo.GetWindowLayer()) == windowInfo->layer_) {
647 HILOG_DEBUG("layer values are the same");
648 return false;
649 }
650 return true;
651 }
652
WindowUpdateAdded(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)653 void AccessibilityWindowManager::WindowUpdateAdded(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
654 {
655 HILOG_DEBUG();
656 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
657 for (auto &windowInfo : infos) {
658 if (!windowInfo) {
659 HILOG_ERROR("invalid windowInfo");
660 return;
661 }
662
663 int32_t realWidId = GetRealWindowId(windowInfo);
664 if (!a11yWindows_.count(realWidId)) {
665 auto a11yWindowInfoAdded = CreateAccessibilityWindowInfo(windowInfo);
666 a11yWindows_.emplace(realWidId, a11yWindowInfoAdded);
667 } else {
668 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
669 }
670
671 if (IsSceneBoard(windowInfo)) {
672 subWindows_.insert(realWidId);
673 sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
674 }
675 bool isSendWindowEvent = CheckEvents();
676 if (isSendWindowEvent) {
677 AccessibilityEventInfo evtInfAdded(realWidId, WINDOW_UPDATE_ADDED);
678 AccessibilityEventInfoParcel evtInfParcel(evtInfAdded);
679 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
680 }
681 if (a11yWindows_[realWidId].IsFocused()) {
682 SetActiveWindow(realWidId);
683 }
684 }
685 }
686
WindowUpdateRemoved(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)687 void AccessibilityWindowManager::WindowUpdateRemoved(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
688 {
689 HILOG_DEBUG();
690 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
691 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
692 for (auto &windowInfo : infos) {
693 if (!windowInfo) {
694 HILOG_ERROR("invalid windowInfo");
695 return;
696 }
697
698 int32_t realWidId = GetRealWindowId(windowInfo);
699 if (!a11yWindows_.count(realWidId)) {
700 return;
701 }
702 if (realWidId == activeWindowId_) {
703 SetActiveWindow(INVALID_WINDOW_ID);
704 }
705 if (realWidId == a11yFocusedWindowId_) {
706 SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
707 }
708 a11yWindows_.erase(realWidId);
709 subWindows_.erase(realWidId);
710 sceneBoardElementIdMap_.RemovePair(realWidId);
711 bool isSendWindowEvent = CheckEvents();
712 if (isSendWindowEvent) {
713 AccessibilityEventInfo evtInfRemoved(realWidId, WINDOW_UPDATE_REMOVED);
714 AccessibilityEventInfoParcel evtInfParcel(evtInfRemoved);
715 aams.SendEvent(evtInfParcel, 0);
716 }
717 }
718 }
719
WindowUpdateFocused(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)720 void AccessibilityWindowManager::WindowUpdateFocused(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
721 {
722 HILOG_DEBUG();
723 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
724 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
725 for (auto &windowInfo : infos) {
726 if (!windowInfo) {
727 HILOG_ERROR("invalid windowInfo");
728 return;
729 }
730
731 int32_t realWidId = GetRealWindowId(windowInfo);
732 if (!a11yWindows_.count(realWidId)) {
733 HILOG_DEBUG("window not created");
734 auto a11yWindowInfoFocused = CreateAccessibilityWindowInfo(windowInfo);
735 a11yWindows_.emplace(realWidId, a11yWindowInfoFocused);
736 }
737
738 if (IsSceneBoard(windowInfo)) {
739 subWindows_.insert(realWidId);
740 sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
741 }
742 SetActiveWindow(realWidId);
743 bool isSendWindowEvent = CheckEvents();
744 if (isSendWindowEvent) {
745 AccessibilityEventInfo evtInfFocused(realWidId, WINDOW_UPDATE_FOCUSED);
746 AccessibilityEventInfoParcel evtInfParcel(evtInfFocused);
747 aams.SendEvent(evtInfParcel, 0);
748 }
749 }
750 }
751
WindowUpdateBounds(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)752 void AccessibilityWindowManager::WindowUpdateBounds(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
753 {
754 HILOG_DEBUG();
755 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
756 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
757 for (auto &windowInfo : infos) {
758 if (!windowInfo) {
759 HILOG_ERROR("invalid windowInfo");
760 return;
761 }
762
763 int32_t realWidId = GetRealWindowId(windowInfo);
764 if (a11yWindows_.count(realWidId)) {
765 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
766 }
767
768 bool isSendWindowEvent = CheckEvents();
769 if (isSendWindowEvent) {
770 AccessibilityEventInfo evtInfBounds(realWidId, WINDOW_UPDATE_BOUNDS);
771 AccessibilityEventInfoParcel evtInfParcel(evtInfBounds);
772 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
773 }
774 }
775 }
776
WindowUpdateActive(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)777 void AccessibilityWindowManager::WindowUpdateActive(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
778 {
779 HILOG_DEBUG();
780 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
781 for (auto &windowInfo : infos) {
782 if (!windowInfo) {
783 HILOG_ERROR("invalid windowInfo");
784 return;
785 }
786
787 int32_t realWidId = GetRealWindowId(windowInfo);
788 if (!a11yWindows_.count(realWidId)) {
789 auto a11yWindowInfoActive = CreateAccessibilityWindowInfo(windowInfo);
790 a11yWindows_.emplace(realWidId, a11yWindowInfoActive);
791 }
792
793 if (IsSceneBoard(windowInfo)) {
794 subWindows_.insert(realWidId);
795 sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
796 }
797 SetActiveWindow(realWidId);
798 }
799 }
800
WindowUpdateProperty(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)801 void AccessibilityWindowManager::WindowUpdateProperty(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
802 {
803 HILOG_DEBUG();
804 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
805 auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
806 for (auto &windowInfo : infos) {
807 if (!windowInfo) {
808 HILOG_ERROR("invalid windowInfo");
809 return;
810 }
811
812 int32_t realWidId = GetRealWindowId(windowInfo);
813 if (a11yWindows_.count(realWidId)) {
814 UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
815 }
816 bool isSendWindowEvent = CheckEvents();
817 if (isSendWindowEvent) {
818 AccessibilityEventInfo evtInfProperty(realWidId, WINDOW_UPDATE_PROPERTY);
819 AccessibilityEventInfoParcel evtInfParcel(evtInfProperty);
820 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
821 }
822 }
823 }
824
WindowUpdateTypeEventAdded(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)825 void AccessibilityWindowManager::WindowUpdateTypeEventAdded(const int32_t realWidId,
826 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
827 {
828 AccessibilityEventInfo evtInfAdded(realWidId, WINDOW_UPDATE_ADDED);
829 SetEventInfoBundleNameOld(evtInfAdded, realWidId, oldA11yWindows_);
830 AccessibilityEventInfoParcel evtInfParcel(evtInfAdded);
831 bool isSendWindowEvent = CheckEvents();
832 if (isSendWindowEvent) {
833 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
834 }
835 if (a11yWindows_[realWidId].IsFocused()) {
836 SetActiveWindow(realWidId);
837 }
838 }
839
WindowUpdateTypeEventRemoved(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)840 void AccessibilityWindowManager::WindowUpdateTypeEventRemoved(const int32_t realWidId,
841 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
842 {
843 if (realWidId == activeWindowId_) {
844 SetActiveWindow(INVALID_WINDOW_ID);
845 }
846 if (realWidId == a11yFocusedWindowId_) {
847 SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
848 }
849
850 AccessibilityEventInfo evtInfRemoved(realWidId, WINDOW_UPDATE_REMOVED);
851 SetEventInfoBundleNameOld(evtInfRemoved, realWidId, oldA11yWindows_);
852 AccessibilityEventInfoParcel evtInfParcel(evtInfRemoved);
853 bool isSendWindowEvent = CheckEvents();
854 if (isSendWindowEvent) {
855 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
856 }
857 }
858
WindowUpdateTypeEventBounds(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)859 void AccessibilityWindowManager::WindowUpdateTypeEventBounds(const int32_t realWidId,
860 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
861 {
862 AccessibilityEventInfo evtInfBounds(realWidId, WINDOW_UPDATE_BOUNDS);
863 SetEventInfoBundleNameOld(evtInfBounds, realWidId, oldA11yWindows_);
864 AccessibilityEventInfoParcel evtInfParcel(evtInfBounds);
865 bool isSendWindowEvent = CheckEvents();
866 if (isSendWindowEvent) {
867 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
868 }
869 }
870
WindowUpdateTypeEventFocused(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)871 void AccessibilityWindowManager::WindowUpdateTypeEventFocused(const int32_t realWidId,
872 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
873 {
874 SetActiveWindow(realWidId);
875 AccessibilityEventInfo evtInfFocused(realWidId, WINDOW_UPDATE_FOCUSED);
876 SetEventInfoBundleNameOld(evtInfFocused, realWidId, oldA11yWindows_);
877 AccessibilityEventInfoParcel evtInfParcel(evtInfFocused);
878 bool isSendWindowEvent = CheckEvents();
879 if (isSendWindowEvent) {
880 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
881 }
882 }
883
WindowUpdateTypeEventProperty(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)884 void AccessibilityWindowManager::WindowUpdateTypeEventProperty(const int32_t realWidId,
885 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
886 {
887 AccessibilityEventInfo evtInfProperty(realWidId, WINDOW_UPDATE_PROPERTY);
888 SetEventInfoBundleNameOld(evtInfProperty, realWidId, oldA11yWindows_);
889 AccessibilityEventInfoParcel evtInfParcel(evtInfProperty);
890 bool isSendWindowEvent = CheckEvents();
891 if (isSendWindowEvent) {
892 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
893 }
894 }
895
WindowUpdateTypeEventLayer(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)896 void AccessibilityWindowManager::WindowUpdateTypeEventLayer(const int32_t realWidId,
897 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
898 {
899 AccessibilityEventInfo evtInfLayer(realWidId, WINDOW_UPDATE_LAYER);
900 SetEventInfoBundleNameOld(evtInfLayer, realWidId, oldA11yWindows_);
901 AccessibilityEventInfoParcel evtInfParcel(evtInfLayer);
902 bool isSendWindowEvent = CheckEvents();
903 if (isSendWindowEvent) {
904 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(evtInfParcel, 0);
905 }
906 }
907
WindowUpdateTypeEvent(const int32_t realWidId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_,Accessibility::WindowUpdateType type)908 void AccessibilityWindowManager::WindowUpdateTypeEvent(const int32_t realWidId,
909 std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_, Accessibility::WindowUpdateType type)
910 {
911 HILOG_DEBUG();
912 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
913 HILOG_DEBUG("WindowUpdateType type[%{public}d]", type);
914 switch (type) {
915 case WindowUpdateType::WINDOW_UPDATE_ADDED: {
916 WindowUpdateTypeEventAdded(realWidId, oldA11yWindows_);
917 break;
918 }
919 case WindowUpdateType::WINDOW_UPDATE_REMOVED: {
920 WindowUpdateTypeEventRemoved(realWidId, oldA11yWindows_);
921 break;
922 }
923 case WindowUpdateType::WINDOW_UPDATE_BOUNDS: {
924 WindowUpdateTypeEventBounds(realWidId, oldA11yWindows_);
925 break;
926 }
927 case WindowUpdateType::WINDOW_UPDATE_FOCUSED: {
928 WindowUpdateTypeEventFocused(realWidId, oldA11yWindows_);
929 break;
930 }
931 case WindowUpdateType::WINDOW_UPDATE_PROPERTY: {
932 WindowUpdateTypeEventProperty(realWidId, oldA11yWindows_);
933 break;
934 }
935 case WindowUpdateType::WINDOW_UPDATE_LAYER: {
936 WindowUpdateTypeEventLayer(realWidId, oldA11yWindows_);
937 break;
938 }
939 default:
940 break;
941 }
942 }
943
WindowUpdateAll(const std::vector<sptr<Rosen::AccessibilityWindowInfo>> & infos)944 void AccessibilityWindowManager::WindowUpdateAll(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
945 {
946 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
947 auto oldA11yWindows_ = a11yWindows_;
948 int32_t oldActiveWindowId = activeWindowId_;
949 HILOG_INFO("WindowUpdateAll start activeWindowId_: %{public}d", activeWindowId_);
950 WinDeInit();
951 for (auto &window : infos) {
952 if (window == nullptr) {
953 HILOG_ERROR("window is nullptr");
954 continue;
955 }
956 int32_t realWid = GetRealWindowId(window);
957 HILOG_DEBUG("windowInfo wid: %{public}d, innerWid: %{public}d, focused: %{public}d",
958 window->wid_, window->innerWid_, window->focused_);
959 if (!a11yWindows_.count(realWid)) {
960 auto a11yWindowInfo = CreateAccessibilityWindowInfo(window);
961 a11yWindows_.emplace(realWid, a11yWindowInfo);
962 HILOG_DEBUG("a11yWindowInfo bundleName(%{public}s)", a11yWindowInfo.GetBundleName().c_str());
963 }
964 if (IsSceneBoard(window)) {
965 subWindows_.insert(realWid);
966 sceneBoardElementIdMap_.InsertPair(realWid, window->uiNodeId_);
967 }
968
969 // IsScenePanel for recent-task window
970 if (window->focused_ || IsScenePanel(window)) {
971 SetActiveWindow(realWid);
972 }
973
974 WindowUpdateAllExec(oldA11yWindows_, realWid, window);
975 }
976
977 for (auto it = oldA11yWindows_.begin(); it != oldA11yWindows_.end(); ++it) {
978 WindowUpdateTypeEvent(it->first, oldA11yWindows_, WINDOW_UPDATE_REMOVED);
979 }
980 HILOG_INFO("WindowUpdateAll end activeWindowId_: %{public}d", activeWindowId_);
981 }
982
WindowUpdateAllExec(std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_,int32_t realWid,const sptr<Rosen::AccessibilityWindowInfo> & window)983 void AccessibilityWindowManager::WindowUpdateAllExec(std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_,
984 int32_t realWid, const sptr<Rosen::AccessibilityWindowInfo>& window)
985 {
986 if (!oldA11yWindows_.count(realWid)) {
987 WindowUpdateTypeEvent(realWid, oldA11yWindows_, WINDOW_UPDATE_ADDED);
988 } else {
989 if (EqualFocus(oldA11yWindows_[realWid], window)) {
990 WindowUpdateTypeEvent(realWid, oldA11yWindows_, WINDOW_UPDATE_FOCUSED);
991 }
992 if (EqualBound(oldA11yWindows_[realWid], window)) {
993 WindowUpdateTypeEvent(realWid, oldA11yWindows_, WINDOW_UPDATE_BOUNDS);
994 }
995 if (EqualProperty(oldA11yWindows_[realWid], window)) {
996 WindowUpdateTypeEvent(realWid, oldA11yWindows_, WINDOW_UPDATE_PROPERTY);
997 }
998 if (EqualLayer(oldA11yWindows_[realWid], window)) {
999 WindowUpdateTypeEvent(realWid, oldA11yWindows_, WINDOW_UPDATE_LAYER);
1000 }
1001 auto itr = oldA11yWindows_.find(realWid);
1002 if (itr != oldA11yWindows_.end()) {
1003 oldA11yWindows_.erase(itr);
1004 }
1005 }
1006 }
1007
ClearOldActiveWindow()1008 void AccessibilityWindowManager::ClearOldActiveWindow()
1009 {
1010 HILOG_DEBUG("active window id is %{public}d", activeWindowId_);
1011 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1012 if (activeWindowId_ == INVALID_WINDOW_ID) {
1013 HILOG_DEBUG("active window id is invalid");
1014 return;
1015 }
1016
1017 if (a11yWindows_.count(activeWindowId_)) {
1018 a11yWindows_[activeWindowId_].SetActive(false);
1019 }
1020 if (activeWindowId_ == a11yFocusedWindowId_) {
1021 HILOG_DEBUG("Old active window is a11yFocused window.");
1022 SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
1023 }
1024 }
1025
ClearAccessibilityFocused()1026 void AccessibilityWindowManager::ClearAccessibilityFocused()
1027 {
1028 HILOG_DEBUG("a11yFocused window id is %{public}d", a11yFocusedWindowId_);
1029 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1030 if (a11yFocusedWindowId_ == INVALID_WINDOW_ID) {
1031 HILOG_DEBUG("a11yFocused window id is invalid");
1032 return;
1033 }
1034
1035 if (a11yWindows_.count(a11yFocusedWindowId_)) {
1036 a11yWindows_[a11yFocusedWindowId_].SetAccessibilityFocused(false);
1037 }
1038
1039 int32_t windowId = a11yFocusedWindowId_;
1040 if (subWindows_.count(a11yFocusedWindowId_)) {
1041 windowId = SCENE_BOARD_WINDOW_ID;
1042 }
1043 sptr<AccessibilityAccountData> accountData =
1044 Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
1045 if (!accountData) {
1046 HILOG_ERROR("accountData is nullptr");
1047 return;
1048 }
1049 sptr<AccessibilityWindowConnection> connection =
1050 accountData->GetAccessibilityWindowConnection(windowId);
1051 if (!connection) {
1052 HILOG_ERROR("windowId[%{public}d] has no connection", windowId);
1053 return;
1054 }
1055 if (!connection->GetProxy()) {
1056 HILOG_ERROR("windowId[%{public}d] has no proxy", windowId);
1057 return;
1058 }
1059 connection->GetProxy()->ClearFocus();
1060
1061 // Send event
1062 AccessibilityEventInfo eventInfo(TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT);
1063 eventInfo.SetWindowId(a11yFocusedWindowId_);
1064 AccessibilityEventInfoParcel eventInfoParcel(eventInfo);
1065 bool isSendWindowEvent = CheckEvents();
1066 if (isSendWindowEvent) {
1067 Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfoParcel, 0);
1068 }
1069 }
1070
GetSceneBoardElementId(const int32_t windowId,const int64_t elementId)1071 int64_t AccessibilityWindowManager::GetSceneBoardElementId(const int32_t windowId, const int64_t elementId)
1072 {
1073 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1074 if (elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
1075 return elementId;
1076 }
1077 if (subWindows_.count(windowId)) {
1078 auto iter = a11yWindows_.find(windowId);
1079 if (iter != a11yWindows_.end()) {
1080 HILOG_DEBUG("GetSceneBoardElementId [%{public}" PRId64 "]", iter->second.GetUiNodeId());
1081 return iter->second.GetUiNodeId();
1082 }
1083 }
1084 return elementId;
1085 }
1086
GetRealWindowAndElementId(int32_t & windowId,int64_t & elementId)1087 void AccessibilityWindowManager::GetRealWindowAndElementId(int32_t& windowId, int64_t& elementId)
1088 {
1089 // sceneboard window id, element id is not equal -1
1090 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1091 if (subWindows_.count(windowId) && elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
1092 windowId = SCENE_BOARD_WINDOW_ID;
1093 HILOG_INFO("windowId %{public}d, elementId %{public}" PRId64 "", windowId, elementId);
1094 return;
1095 }
1096
1097 if (elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
1098 return;
1099 }
1100
1101 if (subWindows_.count(windowId)) {
1102 auto iter = a11yWindows_.find(windowId);
1103 if (iter != a11yWindows_.end()) {
1104 HILOG_DEBUG("GetRealWindowAndElementId [%{public}" PRId64 "]", iter->second.GetUiNodeId());
1105 windowId = SCENE_BOARD_WINDOW_ID;
1106 elementId = iter->second.GetUiNodeId();
1107 return;
1108 }
1109 }
1110 }
1111
GetSceneBoardInnerWinId(int32_t windowId,int64_t elementId,int32_t & innerWid)1112 void AccessibilityWindowManager::GetSceneBoardInnerWinId(int32_t windowId, int64_t elementId,
1113 int32_t& innerWid)
1114 {
1115 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1116 if (windowId != SCENE_BOARD_WINDOW_ID) {
1117 return;
1118 }
1119
1120 for (auto iter = a11yWindows_.begin(); iter != a11yWindows_.end(); iter++) {
1121 if (iter->second.GetUiNodeId() == elementId) {
1122 innerWid = iter->second.GetInnerWid();
1123 }
1124 }
1125
1126 return;
1127 }
1128
InsertPair(const int32_t windowId,const int64_t elementId)1129 void AccessibilityWindowManager::SceneBoardElementIdMap::InsertPair(const int32_t windowId, const int64_t elementId)
1130 {
1131 std::lock_guard<ffrt::mutex> lock(mapMutex_);
1132 windowElementMap_[windowId] = elementId;
1133 }
1134
RemovePair(const int32_t windowId)1135 void AccessibilityWindowManager::SceneBoardElementIdMap::RemovePair(const int32_t windowId)
1136 {
1137 std::lock_guard<ffrt::mutex> lock(mapMutex_);
1138 windowElementMap_.erase(windowId);
1139 }
1140
CheckWindowIdPair(const int32_t windowId)1141 bool AccessibilityWindowManager::SceneBoardElementIdMap::CheckWindowIdPair(const int32_t windowId)
1142 {
1143 std::lock_guard<ffrt::mutex> lock(mapMutex_);
1144 return windowElementMap_.count(windowId);
1145 }
1146
Clear()1147 void AccessibilityWindowManager::SceneBoardElementIdMap::Clear()
1148 {
1149 std::lock_guard<ffrt::mutex> lock(mapMutex_);
1150 windowElementMap_.clear();
1151 }
1152
GetAllPairs()1153 std::map<int32_t, int64_t> AccessibilityWindowManager::SceneBoardElementIdMap::GetAllPairs()
1154 {
1155 std::lock_guard<ffrt::mutex> lock(mapMutex_);
1156 return windowElementMap_;
1157 }
1158
GetA11yWindowsBundleName(int32_t windowId,std::string bundleName)1159 std::string AccessibilityWindowManager::GetA11yWindowsBundleName(int32_t windowId, std::string bundleName)
1160 {
1161 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1162 for (auto iter = a11yWindows_.begin(); iter != a11yWindows_.end(); iter++) {
1163 if (iter->first == windowId) {
1164 AccessibilityWindowInfo tempWindowInfo = iter->second;
1165 HILOG_DEBUG("GetA11yWindowsBundleName windowId:[%{public}d], BundleName:[%{public}s]",
1166 windowId, tempWindowInfo.GetBundleName().c_str());
1167 bundleName = tempWindowInfo.GetBundleName();
1168 break;
1169 }
1170 }
1171 return bundleName;
1172 }
1173
SetEventInfoBundleName(const AccessibilityEventInfo & uiEvent)1174 void AccessibilityWindowManager::SetEventInfoBundleName(const AccessibilityEventInfo &uiEvent)
1175 {
1176 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1177 std::string windowsBundleNameCache = "";
1178 windowsBundleNameCache = GetA11yWindowsBundleName(uiEvent.GetWindowId(), windowsBundleNameCache);
1179 if (windowsBundleNameCache != "") {
1180 const_cast<AccessibilityEventInfo&>(uiEvent).SetBundleName(windowsBundleNameCache);
1181 return;
1182 }
1183
1184 std::vector<AccessibilityWindowInfo> windowsInfo = GetAccessibilityWindows();
1185 if (windowsInfo.empty()) {
1186 HILOG_DEBUG("GetAccessibilityWindows is empty");
1187 return;
1188 }
1189 for (auto &window : windowsInfo) {
1190 const std::string currentBundleName = window.GetBundleName();
1191 int32_t currentWid = window.GetWindowId();
1192 if (currentBundleName != "" && uiEvent.GetWindowId() == currentWid) {
1193 const_cast<AccessibilityEventInfo&>(uiEvent).SetBundleName(currentBundleName);
1194 HILOG_DEBUG("GetAccessibilityWindows windowId:[%{public}d], BundleName:[%{public}s]",
1195 currentWid, currentBundleName.c_str());
1196 break;
1197 }
1198 }
1199 }
1200
SetEventInfoBundleNameOld(const AccessibilityEventInfo & uiEvent,const int32_t windowId,std::map<int32_t,AccessibilityWindowInfo> & oldA11yWindows_)1201 void AccessibilityWindowManager::SetEventInfoBundleNameOld(const AccessibilityEventInfo &uiEvent,
1202 const int32_t windowId, std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows_)
1203 {
1204 std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
1205 std::string bundNameCache = "";
1206 if (oldA11yWindows_.count(windowId)) {
1207 bundNameCache = oldA11yWindows_[windowId].GetBundleName();
1208 HILOG_DEBUG("SetEventInfoBundleNameOld windowId:[%{public}d], BundleName:[%{public}s]",
1209 windowId, bundNameCache.c_str());
1210 const_cast<AccessibilityEventInfo&>(uiEvent).SetBundleName(bundNameCache);
1211 return;
1212 }
1213 SetEventInfoBundleName(uiEvent);
1214 }
1215
GetFocusedWindowId(int32_t & focusedWindowId)1216 RetError AccessibilityWindowManager::GetFocusedWindowId(int32_t &focusedWindowId)
1217 {
1218 HILOG_DEBUG();
1219 #ifdef OHOS_BUILD_ENABLE_HITRACE
1220 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryFocusedWindowInfo");
1221 #endif // OHOS_BUILD_ENABLE_HITRACE
1222 Rosen::FocusChangeInfo focusedWindowInfo;
1223 OHOS::Rosen::WindowManager::GetInstance().GetFocusWindowInfo(focusedWindowInfo);
1224 if (focusedWindowInfo.windowId_ == INVALID_WINDOW_ID) {
1225 return RET_ERR_INVALID_PARAM;
1226 }
1227 focusedWindowId = focusedWindowInfo.windowId_;
1228 return RET_OK;
1229 }
1230
IsInnerWindowRootElement(int64_t elementId)1231 bool AccessibilityWindowManager::IsInnerWindowRootElement(int64_t elementId)
1232 {
1233 HILOG_DEBUG("IsInnerWindowRootElement elementId: %{public}" PRId64 "", elementId);
1234 auto mapTable = sceneBoardElementIdMap_.GetAllPairs();
1235 for (auto iter = mapTable.begin(); iter != mapTable.end(); iter++) {
1236 if (elementId == iter->second) {
1237 return true;
1238 }
1239 }
1240 return false;
1241 }
1242
InsertTreeIdWindowIdPair(int32_t treeId,int32_t windowId)1243 void AccessibilityWindowManager::InsertTreeIdWindowIdPair(int32_t treeId, int32_t windowId)
1244 {
1245 windowTreeIdMap_.EnsureInsert(treeId, windowId);
1246 }
1247
RemoveTreeIdWindowIdPair(int32_t treeId)1248 void AccessibilityWindowManager::RemoveTreeIdWindowIdPair(int32_t treeId)
1249 {
1250 windowTreeIdMap_.Erase(treeId);
1251 }
1252
FindTreeIdWindowIdPair(int32_t treeId)1253 int32_t AccessibilityWindowManager::FindTreeIdWindowIdPair(int32_t treeId)
1254 {
1255 return windowTreeIdMap_.ReadVal(treeId);
1256 }
1257 } // namespace Accessibility
1258 } // namespace OHOS