* Copyright (C) 2022-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed On an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "accessibility_window_manager.h"
#ifdef OHOS_BUILD_ENABLE_HITRACE
#include <hitrace_meter.h>
#endif
#include "accessible_ability_manager_service.h"
#include "hilog_wrapper.h"
#include "utils.h"
#include "xcollie_helper.h"
namespace OHOS {
namespace Accessibility {
namespace {
const std::string TIMER_GET_ACCESSIBILITY_WINDOWS = "accessibilty:getAccessibilityWindowInfo";
const std::string SCB_SCENE_PANEL = "SCBScenePanel";
const std::string SCB_KEYBOARD_DIALOG = "SCBKeyboardDialog";
const std::set<std::string> UNFOCUSABLE_WINDOW = {
"floatingnavigation",
"SCBStatusBar",
"SCBVolumePanel"
};
constexpr int32_t WMS_TIMEOUT = 10;
}
AccessibilityWindowManager::AccessibilityWindowManager()
{
}
bool AccessibilityWindowManager::Init()
{
DeInit();
HILOG_DEBUG("deinit before start");
#ifdef OHOS_BUILD_ENABLE_HITRACE
HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryWindowInfo");
#endif
std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance(accountId_).GetAccessibilityWindowInfo(windowInfos);
if (err != Rosen::WMError::WM_OK) {
Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
return false;
}
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
HILOG_DEBUG("windowInfos size is %{public}zu", windowInfos.size());
for (auto &window : windowInfos) {
if (!window) {
HILOG_ERROR("window is nullptr");
continue;
}
int32_t realWid = GetRealWindowId(window);
if (!a11yWindows_.count(realWid)) {
auto a11yWindowInfo = CreateAccessibilityWindowInfo(window);
a11yWindows_.emplace(realWid, a11yWindowInfo);
}
if (IsSceneBoard(window)) {
subWindows_.insert({realWid, window->displayId_});
sceneBoardElementIdMap_.InsertPair(realWid, window->uiNodeId_);
}
if (a11yWindows_[realWid].IsFocused()) {
SetActiveWindow(realWid);
}
}
return true;
}
void AccessibilityWindowManager::DeInit()
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
a11yWindows_.clear();
subWindows_.clear();
sceneBoardElementIdMap_.Clear();
activeWindowId_ = INVALID_WINDOW_ID;
a11yFocusedWindowId_ = INVALID_WINDOW_ID;
}
void AccessibilityWindowManager::WinDeInit()
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
a11yWindows_.clear();
sceneBoardElementIdMap_.Clear();
activeWindowId_ = INVALID_WINDOW_ID;
}
AccessibilityWindowManager::~AccessibilityWindowManager()
{
DeregisterWindowListener();
}
void AccessibilityWindowManager::SetAccountData(int32_t accountId, const wptr<AccessibilityAccountData>& accountData)
{
accountId_ = accountId;
accountData_ = accountData;
}
bool AccessibilityWindowManager::SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
if (pointerEvent == nullptr) {
return RET_ERR_NULLPTR;
}
return true;
}
void AccessibilityWindowManager::RegisterWindowListener(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
{
DeregisterWindowListener();
HILOG_DEBUG("deregister before register");
if (windowListener_) {
HILOG_DEBUG("Window listener is already registered!");
return;
}
eventHandler_ = handler;
windowListener_ = new(std::nothrow) AccessibilityWindowListener(*this);
if (!windowListener_) {
HILOG_ERROR("Create window listener fail!");
return;
}
OHOS::Rosen::WindowManager::GetInstance(accountId_).RegisterWindowUpdateListener(windowListener_);
}
void AccessibilityWindowManager::DeregisterWindowListener()
{
if (windowListener_) {
OHOS::Rosen::WindowManager::GetInstance().UnregisterWindowUpdateListener(windowListener_);
windowListener_ = nullptr;
eventHandler_ = nullptr;
}
}
void AccessibilityWindowManager::OnWindowUpdate(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos,
Rosen::WindowUpdateType type)
{
HILOG_DEBUG("WindowUpdateType type[%{public}d]", type);
if (!eventHandler_) {
HILOG_ERROR("eventHandler_ is nullptr.");
return;
}
if (infos.size() == 0) {
HILOG_ERROR("window info is err");
return;
}
eventHandler_->PostTask([=]() {
switch (type) {
case Rosen::WindowUpdateType::WINDOW_UPDATE_ADDED:
WindowUpdateAdded(infos);
break;
case Rosen::WindowUpdateType::WINDOW_UPDATE_REMOVED:
WindowUpdateRemoved(infos);
break;
case Rosen::WindowUpdateType::WINDOW_UPDATE_BOUNDS:
WindowUpdateBounds(infos);
break;
case Rosen::WindowUpdateType::WINDOW_UPDATE_ACTIVE:
WindowUpdateActive(infos);
break;
case Rosen::WindowUpdateType::WINDOW_UPDATE_FOCUSED:
WindowUpdateFocused(infos);
break;
case Rosen::WindowUpdateType::WINDOW_UPDATE_PROPERTY:
WindowUpdateProperty(infos);
break;
case Rosen::WindowUpdateType::WINDOW_UPDATE_ALL:
WindowUpdateAll(infos);
break;
default:
break;
}
HILOG_DEBUG("a11yWindows[%{public}zu]", a11yWindows_.size());
}, "TASK_ON_WINDOW_UPDATE");
}
std::pair<int32_t, uint64_t> AccessibilityWindowManager::ConvertToRealWindowId(int32_t windowId, int32_t focusType)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
int32_t winId = windowId;
HILOG_DEBUG("ConvertToRealWindowId called, windowId[%{public}d], focusType[%{public}d]", windowId, focusType);
if (windowId == ACTIVE_WINDOW_ID) {
HILOG_DEBUG("After convert active windowId[%{public}d]", activeWindowId_);
winId = activeWindowId_;
}
if (windowId == ANY_WINDOW_ID) {
if (focusType == FOCUS_TYPE_ACCESSIBILITY) {
HILOG_DEBUG("After convert a11yFocused windowId[%{public}d] by accessibility type", a11yFocusedWindowId_);
winId = a11yFocusedWindowId_;
} else if (focusType == FOCUS_TYPE_INPUT) {
HILOG_DEBUG("After convert active windowId[%{public}d] by input type", activeWindowId_);
winId = activeWindowId_;
}
}
auto iter = std::find_if(
subWindows_.begin(), subWindows_.end(), [winId](const auto &window) { return window.first == winId; });
if (iter != subWindows_.end()) {
HILOG_ERROR("After convert normal windowId[%{public}d]", SCENE_BOARD_WINDOW_ID);
return {SCENE_BOARD_WINDOW_ID, iter->second};
}
HILOG_DEBUG("After convert windowId[%{public}d] and activeId[%{public}d]", winId, activeWindowId_);
return { winId, 0 };
}
AccessibilityWindowType ConvertWindowType(Rosen::WindowType type)
{
AccessibilityWindowType winType = TYPE_WINDOW_INVALID;
if (type < Rosen::WindowType::SYSTEM_WINDOW_BASE) {
winType = TYPE_APPLICATION;
} else if ((type >= Rosen::WindowType::SYSTEM_WINDOW_BASE) && (type <= Rosen::WindowType::SYSTEM_WINDOW_END)) {
winType = TYPE_SYSTEM;
} else {
HILOG_ERROR("Unknown windowType[%{public}d]", type);
}
return winType;
}
bool AccessibilityWindowManager::CheckIntegerOverflow(const Rosen::Rect& rect)
{
if ((rect.posX_ > 0) && (static_cast<int32_t>(rect.width_) > 0)) {
int32_t leftX = INT32_MAX - rect.posX_;
if (leftX < static_cast<int32_t>(rect.width_)) {
HILOG_ERROR("input parameter invalid posX %{public}d, width_ %{public}u", rect.posX_,
rect.width_);
return false;
}
}
if ((rect.posX_ < 0) && (static_cast<int32_t>(rect.width_) < 0)) {
int32_t leftX = INT32_MIN - rect.posX_;
if (leftX > static_cast<int32_t>(rect.width_)) {
HILOG_ERROR("input parameter invalid posX %{public}d, width_ %{public}u", rect.posX_,
rect.width_);
return false;
}
}
if ((rect.posY_ > 0) && (static_cast<int32_t>(rect.height_) > 0)) {
int32_t leftY = INT32_MAX - rect.posY_;
if (leftY < static_cast<int32_t>(rect.height_)) {
HILOG_ERROR("input parameter invalid posX %{public}d, height_ %{public}u", rect.posY_,
rect.height_);
return false;
}
}
if ((rect.posY_ < 0) && (static_cast<int32_t>(rect.height_) < 0)) {
int32_t leftY = INT32_MIN - rect.posY_;
if (leftY > static_cast<int32_t>(rect.height_)) {
HILOG_ERROR("input parameter invalid posX %{public}d, height_ %{public}u", rect.posY_,
rect.height_);
return false;
}
}
return true;
}
void AccessibilityWindowManager::UpdateAccessibilityWindowInfo(AccessibilityWindowInfo &accWindowInfo,
const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
{
if (!windowInfo) {
HILOG_ERROR("windowInfo is null");
return;
}
accWindowInfo.SetScaleVal(windowInfo->scaleVal_);
accWindowInfo.SetScaleX(windowInfo->scaleX_);
accWindowInfo.SetScaleY(windowInfo->scaleY_);
accWindowInfo.SetWindowId(windowInfo->wid_);
accWindowInfo.SetMainWindowId(windowInfo->wid_);
accWindowInfo.SetWindowType(static_cast<uint32_t>(windowInfo->type_));
accWindowInfo.SetWindowMode(static_cast<uint32_t>(windowInfo->mode_));
accWindowInfo.SetAccessibilityWindowType(ConvertWindowType(windowInfo->type_));
accWindowInfo.SetFocused(windowInfo->focused_);
accWindowInfo.SetWindowLayer(windowInfo->layer_);
if (static_cast<int32_t>(windowInfo->type_) == 1 && (static_cast<int32_t>(windowInfo->windowRect_.width_) == 0 ||
static_cast<int32_t>(windowInfo->windowRect_.height_) == 0)) {
HILOG_WARN("invalid window parameters, windowId(%{public}d), posX(%{public}d, posY(%{public}d))",
windowInfo->wid_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
} else {
Rect bound;
bound.SetLeftTopScreenPostion(windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
if (!CheckIntegerOverflow(windowInfo->windowRect_)) {
bound.SetRightBottomScreenPostion(windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
} else {
bound.SetRightBottomScreenPostion(
windowInfo->windowRect_.posX_ + static_cast<int32_t>(windowInfo->windowRect_.width_),
windowInfo->windowRect_.posY_ + static_cast<int32_t>(windowInfo->windowRect_.height_));
}
accWindowInfo.SetRectInScreen(bound);
}
accWindowInfo.SetDisplayId(windowInfo->displayId_);
accWindowInfo.SetDecorEnable(windowInfo->isDecorEnable_);
accWindowInfo.SetUiNodeId(windowInfo->uiNodeId_);
accWindowInfo.SetInnerWid(windowInfo->innerWid_);
if (accWindowInfo.GetWindowId() == SCENE_BOARD_WINDOW_ID) {
accWindowInfo.SetSceneBoard(true);
accWindowInfo.SetWindowId(windowInfo->innerWid_);
accWindowInfo.SetMainWindowId(windowInfo->innerWid_);
HILOG_DEBUG("scene board window id 1 convert inner window id[%{public}d]", windowInfo->innerWid_);
}
HILOG_DEBUG("bundle name is [%{public}s] , touchHotAreas size(%{public}zu)",
windowInfo->bundleName_.c_str(), windowInfo->touchHotAreas_.size());
accWindowInfo.SetBundleName(windowInfo->bundleName_);
HILOG_DEBUG("UpdateAccessibilityWindowInfo is set bundlename is [%{public}s]",
accWindowInfo.GetBundleName().c_str());
std::vector<Rect> tempTouchHotAreas = {};
for (auto &rect : windowInfo->touchHotAreas_) {
HILOG_DEBUG("Rosen::windowinfo x:[%{public}d], y:[%{public}d]; width:[%{public}d], height:[%{public}d]",
rect.posX_, rect.posY_, rect.width_, rect.height_);
Rect rectTemp;
rectTemp.SetLeftTopScreenPostion(rect.posX_, rect.posY_);
if (!CheckIntegerOverflow(rect)) {
rectTemp.SetRightBottomScreenPostion(rect.posX_, rect.posY_);
} else {
rectTemp.SetRightBottomScreenPostion(
rect.posX_ + static_cast<int32_t>(rect.width_),
rect.posY_ + static_cast<int32_t>(rect.height_));
}
tempTouchHotAreas.push_back(rectTemp);
}
accWindowInfo.SetTouchHotAreas(tempTouchHotAreas);
for (auto &outRect : accWindowInfo.GetTouchHotAreas()) {
HILOG_DEBUG("left_x:[%{public}d], left_y:[%{public}d]; right_x:[%{public}d], right_y:[%{public}d]",
outRect.GetLeftTopXScreenPostion(), outRect.GetLeftTopYScreenPostion(),
outRect.GetRightBottomXScreenPostion(), outRect.GetRightBottomYScreenPostion());
}
}
int32_t AccessibilityWindowManager::GetRealWindowId(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
{
if (windowInfo->wid_ == SCENE_BOARD_WINDOW_ID) {
return windowInfo->innerWid_;
}
return windowInfo->wid_;
}
bool AccessibilityWindowManager::IsSceneBoard(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
{
if (windowInfo->wid_ == SCENE_BOARD_WINDOW_ID) {
return true;
}
return false;
}
bool AccessibilityWindowManager::IsScenePanel(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
{
return windowInfo->bundleName_.find(SCB_SCENE_PANEL) != std::string::npos;
}
bool AccessibilityWindowManager::IsKeyboardDialog(const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
{
return windowInfo->bundleName_.find(SCB_KEYBOARD_DIALOG) != std::string::npos;
}
AccessibilityWindowInfo AccessibilityWindowManager::CreateAccessibilityWindowInfo(
const sptr<Rosen::AccessibilityWindowInfo> windowInfo)
{
AccessibilityWindowInfo info;
UpdateAccessibilityWindowInfo(info, windowInfo);
HILOG_DEBUG("Create WindowInfo Id(%{public}d) type(%{public}d) posX(%{public}d) posY(%{public}d)"
"witdth(%{public}d) height(%{public}d) display id(%{public}" PRIu64 ") isDecorEnable(%{public}d)"
"innerWid(%{public}d), uiNodeId(%{public}d)",
windowInfo->wid_, windowInfo->type_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_,
windowInfo->windowRect_.width_, windowInfo->windowRect_.height_, windowInfo->displayId_,
windowInfo->isDecorEnable_, windowInfo->innerWid_, windowInfo->uiNodeId_);
return info;
}
bool AccessibilityWindowManager::CheckEvents()
{
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return false;
}
std::vector<uint32_t> needEvents = accountData->GetNeedEvents();
auto isExit = std::find(needEvents.begin(), needEvents.end(), TYPE_WINDOW_UPDATE);
auto isAllEvent = std::find(needEvents.begin(), needEvents.end(), TYPES_ALL_MASK);
if (isAllEvent != needEvents.end() || isExit != needEvents.end() || (needEvents.size() == 0)) {
return true;
}
return false;
}
void AccessibilityWindowManager::SetActiveWindow(int32_t windowId, bool isSendEvent)
{
HILOG_INFO("windowId is %{public}d, activeWindowId_: %{public}d", windowId, activeWindowId_);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (windowId == INVALID_WINDOW_ID) {
ClearOldActiveWindow();
activeWindowId_ = INVALID_WINDOW_ID;
return;
}
if (!a11yWindows_.count(windowId)) {
HILOG_WARN("Window id is not found");
return;
}
bool isSendWindowEvent = CheckEvents();
HILOG_DEBUG("isSendWindowEvent is: %{public}d", isSendWindowEvent);
if (!isSendWindowEvent) {
isSendEvent = false;
}
if (activeWindowId_ != windowId) {
ClearOldActiveWindow();
activeWindowId_ = windowId;
a11yWindows_[activeWindowId_].SetActive(true);
if (!isSendEvent) {
HILOG_DEBUG("not send event, activeWindowId is %{public}d", activeWindowId_);
return;
}
auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
AccessibilityEventInfo evtInf(activeWindowId_, WINDOW_UPDATE_ACTIVE);
AccessibilityEventInfoParcel evtInfParcel(evtInf);
int32_t winId = windowId;
if (sceneBoardElementIdMap_.CheckWindowIdPair(windowId)) {
winId = SCENE_BOARD_WINDOW_ID;
}
SetEventInfoBundleName(evtInfParcel);
if (CheckWindowRegister(winId)) {
HILOG_DEBUG("send active event, windowId: %{public}d", winId);
aams.InnerSendEvent(evtInfParcel, 0, accountId_);
} else {
HILOG_DEBUG("wait for window register to process event, windowId: %{public}d", winId);
windowFocusEventMap_.EnsureInsert(winId, evtInfParcel);
}
}
HILOG_DEBUG("activeWindowId is %{public}d", activeWindowId_);
}
bool AccessibilityWindowManager::CheckWindowRegister(int32_t windowId)
{
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return false;
}
return accountData_->GetElementOperatorManager().GetAccessibilityWindowConnection(windowId) != nullptr;
}
int32_t AccessibilityWindowManager::GetActiveWindowId()
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
HILOG_DEBUG("activeWindowId_ is %{public}d", activeWindowId_);
return activeWindowId_;
}
void AccessibilityWindowManager::SetAccessibilityFocusedWindow(int32_t windowId)
{
HILOG_DEBUG("windowId is %{public}d", windowId);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (windowId == INVALID_WINDOW_ID) {
ClearAccessibilityFocused();
a11yFocusedWindowId_ = INVALID_WINDOW_ID;
return;
}
if (!a11yWindows_.count(windowId)) {
HILOG_ERROR("Window id[%{public}d] is not found", windowId);
return;
}
if (a11yFocusedWindowId_ != windowId) {
ClearAccessibilityFocused();
a11yFocusedWindowId_ = windowId;
a11yWindows_[a11yFocusedWindowId_].SetAccessibilityFocused(true);
}
HILOG_DEBUG("a11yFocusedWindowId_ is %{public}d", a11yFocusedWindowId_);
}
std::vector<AccessibilityWindowInfo> AccessibilityWindowManager::GetAccessibilityWindows()
{
XCollieHelper timer(TIMER_GET_ACCESSIBILITY_WINDOWS, WMS_TIMEOUT);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
HILOG_DEBUG("a11yWindows_ size[%{public}zu]", a11yWindows_.size());
std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
std::vector<AccessibilityWindowInfo> windows;
Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance(accountId_).GetAccessibilityWindowInfo(windowInfos);
if (err != Rosen::WMError::WM_OK) {
Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
return windows;
}
for (auto &info : windowInfos) {
if (info == nullptr) {
continue;
}
AccessibilityWindowInfo tmpWindowInfo;
UpdateAccessibilityWindowInfo(tmpWindowInfo, info);
if (tmpWindowInfo.IsFocused()) {
HILOG_DEBUG("set active windowId: %{public}d", tmpWindowInfo.GetWindowId());
tmpWindowInfo.SetActive(true);
}
windows.push_back(tmpWindowInfo);
}
return windows;
}
bool AccessibilityWindowManager::GetAccessibilityWindow(int32_t windowId, AccessibilityWindowInfo &window)
{
HILOG_DEBUG("start windowId(%{public}d)", windowId);
XCollieHelper timer(TIMER_GET_ACCESSIBILITY_WINDOWS, WMS_TIMEOUT);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
std::vector<sptr<Rosen::AccessibilityWindowInfo>> windowInfos;
Rosen::WMError err = OHOS::Rosen::WindowManager::GetInstance(accountId_).GetAccessibilityWindowInfo(windowInfos);
if (err != Rosen::WMError::WM_OK) {
Utils::RecordUnavailableEvent(A11yUnavailableEvent::QUERY_EVENT, A11yError::ERROR_QUERY_WINDOW_INFO_FAILED);
HILOG_ERROR("get window info from wms failed. err[%{public}d]", err);
return false;
}
for (auto &info : windowInfos) {
if (info == nullptr) {
continue;
}
int32_t realWidId = GetRealWindowId(info);
if (a11yWindows_.count(realWidId)) {
UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], info);
} else {
AccessibilityWindowInfo tmpWindowInfo;
UpdateAccessibilityWindowInfo(tmpWindowInfo, info);
a11yWindows_[realWidId] = tmpWindowInfo;
}
}
if (a11yWindows_.count(windowId)) {
window = a11yWindows_[windowId];
return true;
}
return false;
}
bool AccessibilityWindowManager::IsValidWindow(int32_t windowId)
{
HILOG_DEBUG("start windowId(%{public}d)", windowId);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto it = std::find_if(a11yWindows_.begin(), a11yWindows_.end(),
[windowId](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) {
return window.first == windowId;
});
if (it == a11yWindows_.end()) {
return false;
}
return true;
}
void AccessibilityWindowManager::SetWindowSize(int32_t windowId, Rect rect)
{
HILOG_DEBUG("start windowId(%{public}d)", windowId);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto it = std::find_if(a11yWindows_.begin(), a11yWindows_.end(),
[windowId](const std::map<int32_t, AccessibilityWindowInfo>::value_type &window) {
return window.first == windowId;
});
if (it != a11yWindows_.end()) {
it->second.SetRectInScreen(rect);
}
}
bool AccessibilityWindowManager::CompareRect(const Rect &rectAccessibility, const Rosen::Rect &rectWindow)
{
HILOG_DEBUG();
int32_t leftTopX_ = rectWindow.posX_;
int32_t leftTopY_ = rectWindow.posY_;
int32_t rightBottomX_ = 0;
int32_t rightBottomY_ = 0;
if (!CheckIntegerOverflow(rectWindow)) {
rightBottomX_ = rectWindow.posX_;
rightBottomY_ = rectWindow.posY_;
} else {
rightBottomX_ = rectWindow.posX_ + static_cast<int32_t>(rectWindow.width_);
rightBottomY_ = rectWindow.posY_ + static_cast<int32_t>(rectWindow.height_);
}
if (rectAccessibility.GetLeftTopXScreenPostion() == leftTopX_ &&
rectAccessibility.GetLeftTopYScreenPostion() == leftTopY_ &&
rectAccessibility.GetRightBottomXScreenPostion() == rightBottomX_ &&
rectAccessibility.GetRightBottomYScreenPostion() == rightBottomY_) {
HILOG_DEBUG("rect values are the same");
return false;
}
return true;
}
bool AccessibilityWindowManager::EqualFocus(const Accessibility::AccessibilityWindowInfo &accWindowInfo,
const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
{
HILOG_DEBUG();
if (accWindowInfo.IsFocused() == windowInfo->focused_) {
HILOG_DEBUG("focus values are the same");
return false;
}
return windowInfo->focused_;
}
bool AccessibilityWindowManager::EqualBound(const Accessibility::AccessibilityWindowInfo &accWindowInfo,
const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
{
HILOG_DEBUG();
if (static_cast<int32_t>(windowInfo->type_) == 1 && (static_cast<int32_t>(windowInfo->windowRect_.width_) == 0 ||
static_cast<int32_t>(windowInfo->windowRect_.height_) == 0)) {
HILOG_ERROR("invalid window parameters, windowId(%{public}d), posX(%{public}d, posY(%{public}d))",
windowInfo->wid_, windowInfo->windowRect_.posX_, windowInfo->windowRect_.posY_);
return false;
}
return CompareRect(accWindowInfo.GetRectInScreen(), windowInfo->windowRect_);
}
bool AccessibilityWindowManager::EqualProperty(Accessibility::AccessibilityWindowInfo &accWindowInfo,
const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
{
HILOG_DEBUG();
std::ostringstream accInfoStr;
std::ostringstream winInfoStr;
accInfoStr << accWindowInfo.GetWindowMode()
<< accWindowInfo.GetWindowLayer()
<< accWindowInfo.IsDecorEnable()
<< accWindowInfo.GetWindowType()
<< accWindowInfo.GetDisplayId()
<< accWindowInfo.GetScaleVal()
<< accWindowInfo.GetScaleX()
<< accWindowInfo.GetScaleY();
HILOG_DEBUG("Create accinfoStr windowMode_[%{public}d] Layer_[%{public}d] isDecorEnable_[%{public}d]"
"windowType_[%{public}d] displayId:%{public}" PRIu64 " get scaleVal_ [%{public}f]"
"get scaleX_ [%{public}f] get scaleY_ [%{public}f]",
accWindowInfo.GetWindowMode(), accWindowInfo.GetWindowLayer(), accWindowInfo.IsDecorEnable(),
accWindowInfo.GetWindowType(), accWindowInfo.GetDisplayId(), accWindowInfo.GetScaleVal(),
accWindowInfo.GetScaleX(), accWindowInfo.GetScaleY());
winInfoStr << static_cast<uint32_t>(windowInfo->mode_)
<< windowInfo->layer_
<< windowInfo->isDecorEnable_
<< static_cast<uint32_t>(windowInfo->type_)
<< windowInfo->displayId_
<< windowInfo->scaleVal_
<< windowInfo->scaleX_
<< windowInfo->scaleY_;
HILOG_DEBUG("Create wininfoStr Mode_[%{public}d] Layer_[%{public}d] isDecorEnable_[%{public}d]"
"Type_[%{public}d] displayId:%{public}" PRIu64 " scaleVal_ [%{public}f]"
"scaleX_ [%{public}f] scaleY_ [%{public}f]",
static_cast<uint32_t>(windowInfo->mode_), windowInfo->layer_, windowInfo->isDecorEnable_,
static_cast<uint32_t>(windowInfo->type_), windowInfo->displayId_, windowInfo->scaleVal_,
windowInfo->scaleX_, windowInfo->scaleY_);
if (accInfoStr.str() != winInfoStr.str() ||
windowInfo->touchHotAreas_.size() != accWindowInfo.GetTouchHotAreas().size()) {
HILOG_DEBUG("Property different");
return true;
}
for (uint32_t i = 0; i < accWindowInfo.GetTouchHotAreas().size(); i++) {
if (CompareRect(accWindowInfo.GetTouchHotAreas()[i], windowInfo->touchHotAreas_[i])) {
HILOG_DEBUG("touchHotAreas different");
return true;
}
}
return false;
}
bool AccessibilityWindowManager::EqualLayer(const Accessibility::AccessibilityWindowInfo &accWindowInfo,
const sptr<Rosen::AccessibilityWindowInfo> &windowInfo)
{
HILOG_DEBUG();
if (static_cast<uint32_t>(accWindowInfo.GetWindowLayer()) == windowInfo->layer_) {
HILOG_DEBUG("layer values are the same");
return false;
}
return true;
}
void AccessibilityWindowManager::WindowUpdateAdded(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
for (auto &windowInfo : infos) {
if (!windowInfo) {
HILOG_ERROR("invalid windowInfo");
return;
}
int32_t realWidId = GetRealWindowId(windowInfo);
if (!a11yWindows_.count(realWidId)) {
auto a11yWindowInfoAdded = CreateAccessibilityWindowInfo(windowInfo);
a11yWindows_.emplace(realWidId, a11yWindowInfoAdded);
} else {
UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
}
if (IsSceneBoard(windowInfo)) {
subWindows_.insert({realWidId, windowInfo->displayId_});
sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
}
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
AccessibilityEventInfo evtInfAdded(realWidId, WINDOW_UPDATE_ADDED);
AccessibilityEventInfoParcel evtInfParcel(evtInfAdded);
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
if (a11yWindows_[realWidId].IsFocused()) {
SetActiveWindow(realWidId);
}
}
}
void AccessibilityWindowManager::WindowUpdateRemoved(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
for (auto &windowInfo : infos) {
if (!windowInfo) {
HILOG_ERROR("invalid windowInfo");
return;
}
int32_t realWidId = GetRealWindowId(windowInfo);
if (!a11yWindows_.count(realWidId)) {
return;
}
if (realWidId == activeWindowId_) {
SetActiveWindow(INVALID_WINDOW_ID);
}
if (realWidId == a11yFocusedWindowId_) {
SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
}
a11yWindows_.erase(realWidId);
for (auto it = subWindows_.begin(); it != subWindows_.end();) {
if (it->first == realWidId) {
it = subWindows_.erase(it);
} else {
++it;
}
}
sceneBoardElementIdMap_.RemovePair(realWidId);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
AccessibilityEventInfo evtInfRemoved(realWidId, WINDOW_UPDATE_REMOVED);
AccessibilityEventInfoParcel evtInfParcel(evtInfRemoved);
aams.InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
}
void AccessibilityWindowManager::WindowUpdateFocused(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
for (auto &windowInfo : infos) {
if (!windowInfo) {
HILOG_ERROR("invalid windowInfo");
return;
}
int32_t realWidId = GetRealWindowId(windowInfo);
if (!a11yWindows_.count(realWidId)) {
HILOG_DEBUG("window not created");
auto a11yWindowInfoFocused = CreateAccessibilityWindowInfo(windowInfo);
a11yWindows_.emplace(realWidId, a11yWindowInfoFocused);
}
if (IsSceneBoard(windowInfo)) {
subWindows_.insert({realWidId, windowInfo->displayId_});
sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
}
SetActiveWindow(realWidId);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
AccessibilityEventInfo evtInfFocused(realWidId, WINDOW_UPDATE_FOCUSED);
AccessibilityEventInfoParcel evtInfParcel(evtInfFocused);
aams.InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
}
void AccessibilityWindowManager::WindowUpdateBounds(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
for (auto &windowInfo : infos) {
if (!windowInfo) {
HILOG_ERROR("invalid windowInfo");
return;
}
int32_t realWidId = GetRealWindowId(windowInfo);
if (a11yWindows_.count(realWidId)) {
UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
}
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
AccessibilityEventInfo evtInfBounds(realWidId, WINDOW_UPDATE_BOUNDS);
AccessibilityEventInfoParcel evtInfParcel(evtInfBounds);
aams.InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
}
void AccessibilityWindowManager::WindowUpdateActive(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
for (auto &windowInfo : infos) {
if (!windowInfo) {
HILOG_ERROR("invalid windowInfo");
return;
}
int32_t realWidId = GetRealWindowId(windowInfo);
if (!a11yWindows_.count(realWidId)) {
auto a11yWindowInfoActive = CreateAccessibilityWindowInfo(windowInfo);
a11yWindows_.emplace(realWidId, a11yWindowInfoActive);
}
if (IsSceneBoard(windowInfo)) {
subWindows_.insert({realWidId, windowInfo->displayId_});
sceneBoardElementIdMap_.InsertPair(realWidId, windowInfo->uiNodeId_);
}
SetActiveWindow(realWidId);
}
}
void AccessibilityWindowManager::WindowUpdateProperty(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
for (auto &windowInfo : infos) {
if (!windowInfo) {
HILOG_ERROR("invalid windowInfo");
return;
}
int32_t realWidId = GetRealWindowId(windowInfo);
if (a11yWindows_.count(realWidId)) {
UpdateAccessibilityWindowInfo(a11yWindows_[realWidId], windowInfo);
}
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
AccessibilityEventInfo evtInfProperty(realWidId, WINDOW_UPDATE_PROPERTY);
AccessibilityEventInfoParcel evtInfParcel(evtInfProperty);
aams.InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
}
void AccessibilityWindowManager::WindowUpdateTypeEventAdded(const int32_t realWindowId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
AccessibilityEventInfo evtInfAdded(realWindowId, WINDOW_UPDATE_ADDED);
SetEventInfoBundleNameOld(evtInfAdded, realWindowId, oldA11yWindows);
AccessibilityEventInfoParcel evtInfParcel(evtInfAdded);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
if (a11yWindows_[realWindowId].IsFocused()) {
SetActiveWindow(realWindowId);
}
}
void AccessibilityWindowManager::WindowUpdateTypeEventRemoved(const int32_t realWindowId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
if (realWindowId == activeWindowId_) {
SetActiveWindow(INVALID_WINDOW_ID);
}
if (realWindowId == a11yFocusedWindowId_) {
SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
}
AccessibilityEventInfo evtInfRemoved(realWindowId, WINDOW_UPDATE_REMOVED);
SetEventInfoBundleNameOld(evtInfRemoved, realWindowId, oldA11yWindows);
AccessibilityEventInfoParcel evtInfParcel(evtInfRemoved);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
void AccessibilityWindowManager::WindowUpdateTypeEventBounds(const int32_t realWindowId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
AccessibilityEventInfo evtInfBounds(realWindowId, WINDOW_UPDATE_BOUNDS);
SetEventInfoBundleNameOld(evtInfBounds, realWindowId, oldA11yWindows);
AccessibilityEventInfoParcel evtInfParcel(evtInfBounds);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
void AccessibilityWindowManager::WindowUpdateTypeEventFocused(const int32_t realWindowId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
SetActiveWindow(realWindowId);
AccessibilityEventInfo evtInfFocused(realWindowId, WINDOW_UPDATE_FOCUSED);
SetEventInfoBundleNameOld(evtInfFocused, realWindowId, oldA11yWindows);
AccessibilityEventInfoParcel evtInfParcel(evtInfFocused);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
void AccessibilityWindowManager::WindowUpdateTypeEventProperty(const int32_t realWindowId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
AccessibilityEventInfo evtInfProperty(realWindowId, WINDOW_UPDATE_PROPERTY);
SetEventInfoBundleNameOld(evtInfProperty, realWindowId, oldA11yWindows);
AccessibilityEventInfoParcel evtInfParcel(evtInfProperty);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
void AccessibilityWindowManager::WindowUpdateTypeEventLayer(const int32_t realWindowId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
AccessibilityEventInfo evtInfLayer(realWindowId, WINDOW_UPDATE_LAYER);
SetEventInfoBundleNameOld(evtInfLayer, realWindowId, oldA11yWindows);
AccessibilityEventInfoParcel evtInfParcel(evtInfLayer);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(evtInfParcel, 0, accountId_);
}
}
void AccessibilityWindowManager::WindowUpdateTypeEvent(const int32_t realWidId,
std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows, Accessibility::WindowUpdateType type)
{
HILOG_DEBUG();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
HILOG_DEBUG("WindowUpdateType type[%{public}d]", type);
switch (type) {
case WindowUpdateType::WINDOW_UPDATE_ADDED: {
WindowUpdateTypeEventAdded(realWidId, oldA11yWindows);
break;
}
case WindowUpdateType::WINDOW_UPDATE_REMOVED: {
WindowUpdateTypeEventRemoved(realWidId, oldA11yWindows);
break;
}
case WindowUpdateType::WINDOW_UPDATE_BOUNDS: {
WindowUpdateTypeEventBounds(realWidId, oldA11yWindows);
break;
}
case WindowUpdateType::WINDOW_UPDATE_FOCUSED: {
WindowUpdateTypeEventFocused(realWidId, oldA11yWindows);
break;
}
case WindowUpdateType::WINDOW_UPDATE_PROPERTY: {
WindowUpdateTypeEventProperty(realWidId, oldA11yWindows);
break;
}
case WindowUpdateType::WINDOW_UPDATE_LAYER: {
WindowUpdateTypeEventLayer(realWidId, oldA11yWindows);
break;
}
default:
break;
}
}
bool AccessibilityWindowManager::IsMagnificationWindow(const sptr<Rosen::AccessibilityWindowInfo>& window)
{
if (window->type_ == Rosen::WindowType::WINDOW_TYPE_MAGNIFICATION ||
window->type_ == Rosen::WindowType::WINDOW_TYPE_MAGNIFICATION_MENU) {
return true;
}
return false;
}
void AccessibilityWindowManager::SetAccessibilityFocusedWindow()
{
std::vector<AccessibilityWindowInfo> windows = GetAccessibilityWindows();
if (windows.empty()) {
HILOG_DEBUG("GetAccessibilityWindows is empty");
return;
}
for (auto& window : windows) {
const int32_t windowId = window.GetWindowId();
const std::string bundleName = window.GetBundleName();
const bool IsFocused = window.IsFocused();
if (window.IsSceneBoard()) {
subWindows_.insert({windowId, window.GetDisplayId()});
sceneBoardElementIdMap_.InsertPair(windowId, window.GetUiNodeId());
}
if (!IsFocused) {
continue;
}
if (!a11yWindows_.count(windowId)) {
a11yWindows_.emplace(windowId, window);
}
SetActiveWindow(windowId);
HILOG_INFO("Active window updated: %{public}d", activeWindowId_);
return;
}
}
bool AccessibilityWindowManager::NeedSetActive(const int32_t windowId)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (windowId == INVALID_WINDOW_ID || !a11yWindows_.count(windowId)) {
return false;
}
const std::string& currentBundleName = a11yWindows_[windowId].GetBundleName();
auto it = std::find_if(UNFOCUSABLE_WINDOW.begin(), UNFOCUSABLE_WINDOW.end(),
[¤tBundleName](const std::string& pattern) {
return currentBundleName.find(pattern) != std::string::npos;
});
if (it == UNFOCUSABLE_WINDOW.end()) {
return true;
} else {
HILOG_INFO("skip set active, current BundleName: %{public}s, windowId: %{public}d",
currentBundleName.c_str(), windowId);
return false;
}
}
void AccessibilityWindowManager::WindowUpdateAll(const std::vector<sptr<Rosen::AccessibilityWindowInfo>>& infos)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
auto oldA11yWindows_ = a11yWindows_;
const int32_t previousActiveWindowId = activeWindowId_;
bool hasFocusedWindow = false;
WinDeInit();
for (auto &window : infos) {
if (window == nullptr) {
HILOG_ERROR("window is nullptr");
continue;
}
if (IsMagnificationWindow(window)) {
continue;
}
int32_t realWid = GetRealWindowId(window);
HILOG_DEBUG("windowInfo wid: %{public}d, innerWid: %{public}d, focused: %{public}d",
window->wid_, window->innerWid_, window->focused_);
if (!a11yWindows_.count(realWid)) {
auto a11yWindowInfo = CreateAccessibilityWindowInfo(window);
a11yWindows_.emplace(realWid, a11yWindowInfo);
HILOG_DEBUG("a11yWindowInfo bundleName(%{public}s)", a11yWindowInfo.GetBundleName().c_str());
}
if (IsSceneBoard(window)) {
subWindows_.insert({realWid, window->displayId_});
sceneBoardElementIdMap_.InsertPair(realWid, window->uiNodeId_);
}
if (!window->focused_ && !IsScenePanel(window) && !IsKeyboardDialog(window)) {
WindowUpdateAllExec(oldA11yWindows_, realWid, window);
continue;
}
hasFocusedWindow = true;
if (previousActiveWindowId != realWid) {
SetActiveWindow(realWid);
} else {
activeWindowId_ = previousActiveWindowId;
}
WindowUpdateAllExec(oldA11yWindows_, realWid, window);
}
for (auto it = oldA11yWindows_.begin(); it != oldA11yWindows_.end(); ++it) {
WindowUpdateTypeEvent(it->first, oldA11yWindows_, WINDOW_UPDATE_REMOVED);
}
if (!hasFocusedWindow) {
SetAccessibilityFocusedWindow();
}
HILOG_INFO("start activeWindowId_: %{public}d, end activeWindowId_: %{public}d",
previousActiveWindowId, activeWindowId_);
}
void AccessibilityWindowManager::WindowUpdateAllExec(std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows,
int32_t realWid, const sptr<Rosen::AccessibilityWindowInfo>& window)
{
if (!oldA11yWindows.count(realWid)) {
WindowUpdateTypeEvent(realWid, oldA11yWindows, WINDOW_UPDATE_ADDED);
} else {
if (EqualFocus(oldA11yWindows[realWid], window)) {
WindowUpdateTypeEvent(realWid, oldA11yWindows, WINDOW_UPDATE_FOCUSED);
}
if (EqualBound(oldA11yWindows[realWid], window)) {
WindowUpdateTypeEvent(realWid, oldA11yWindows, WINDOW_UPDATE_BOUNDS);
}
if (EqualProperty(oldA11yWindows[realWid], window)) {
WindowUpdateTypeEvent(realWid, oldA11yWindows, WINDOW_UPDATE_PROPERTY);
}
if (EqualLayer(oldA11yWindows[realWid], window)) {
WindowUpdateTypeEvent(realWid, oldA11yWindows, WINDOW_UPDATE_LAYER);
}
auto itr = oldA11yWindows.find(realWid);
if (itr != oldA11yWindows.end()) {
oldA11yWindows.erase(itr);
}
}
}
void AccessibilityWindowManager::ClearOldActiveWindow()
{
HILOG_DEBUG("active window id is %{public}d", activeWindowId_);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (activeWindowId_ == INVALID_WINDOW_ID) {
HILOG_DEBUG("active window id is invalid");
return;
}
if (a11yWindows_.count(activeWindowId_)) {
a11yWindows_[activeWindowId_].SetActive(false);
}
if (activeWindowId_ == a11yFocusedWindowId_) {
HILOG_DEBUG("Old active window is a11yFocused window.");
SetAccessibilityFocusedWindow(INVALID_WINDOW_ID);
}
}
void AccessibilityWindowManager::ClearAccessibilityFocused()
{
HILOG_DEBUG("a11yFocused window id is %{public}d", a11yFocusedWindowId_);
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (a11yFocusedWindowId_ == INVALID_WINDOW_ID) {
HILOG_DEBUG("a11yFocused window id is invalid");
return;
}
if (a11yWindows_.count(a11yFocusedWindowId_)) {
a11yWindows_[a11yFocusedWindowId_].SetAccessibilityFocused(false);
}
int32_t windowId = a11yFocusedWindowId_;
int32_t subWindowsCount = std::count_if(subWindows_.begin(), subWindows_.end(),
[this] (const auto &window) { return window.first == a11yFocusedWindowId_; });
if (subWindowsCount) {
windowId = SCENE_BOARD_WINDOW_ID;
}
AccessibilityEventInfo eventInfo(TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT);
eventInfo.SetWindowId(a11yFocusedWindowId_);
AccessibilityEventInfoParcel eventInfoParcel(eventInfo);
bool isSendWindowEvent = CheckEvents();
if (isSendWindowEvent) {
Singleton<AccessibleAbilityManagerService>::GetInstance().InnerSendEvent(eventInfoParcel, 0, accountId_);
}
}
int64_t AccessibilityWindowManager::GetSceneBoardElementId(const int32_t windowId, const int64_t elementId)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (elementId != INVALID_SCENE_BOARD_ELEMENT_ID) {
return elementId;
}
int32_t subWindowsCount = std::count_if(
subWindows_.begin(), subWindows_.end(), [windowId](const auto &window) { return window.first == windowId; });
if (subWindowsCount) {
auto iter = a11yWindows_.find(windowId);
if (iter != a11yWindows_.end()) {
HILOG_DEBUG("GetSceneBoardElementId [%{public}" PRId64 "]", iter->second.GetUiNodeId());
return iter->second.GetUiNodeId();
}
}
return elementId;
}
void AccessibilityWindowManager::SceneBoardElementIdMap::InsertPair(const int32_t windowId, const int64_t elementId)
{
std::lock_guard<ffrt::mutex> lock(mapMutex_);
windowElementMap_[windowId] = elementId;
}
void AccessibilityWindowManager::SceneBoardElementIdMap::RemovePair(const int32_t windowId)
{
std::lock_guard<ffrt::mutex> lock(mapMutex_);
windowElementMap_.erase(windowId);
}
bool AccessibilityWindowManager::SceneBoardElementIdMap::CheckWindowIdPair(const int32_t windowId)
{
std::lock_guard<ffrt::mutex> lock(mapMutex_);
return windowElementMap_.count(windowId);
}
void AccessibilityWindowManager::SceneBoardElementIdMap::Clear()
{
std::lock_guard<ffrt::mutex> lock(mapMutex_);
windowElementMap_.clear();
}
std::map<int32_t, int64_t> AccessibilityWindowManager::SceneBoardElementIdMap::GetAllPairs()
{
std::lock_guard<ffrt::mutex> lock(mapMutex_);
return windowElementMap_;
}
void AccessibilityWindowManager::GetA11yWindowsBundleName(int32_t windowId, std::string &bundleName)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (a11yWindows_.count(windowId)) {
bundleName = a11yWindows_[windowId].GetBundleName();
HILOG_DEBUG("GetA11yWindowsBundleName windowId:[%{public}d], BundleName:[%{public}s]",
windowId, bundleName.c_str());
}
}
bool AccessibilityWindowManager::GetA11yWindowById(int32_t windowId, AccessibilityWindowInfo &window)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
if (a11yWindows_.count(windowId)) {
window = a11yWindows_[windowId];
return true;
}
return false;
}
void AccessibilityWindowManager::SetEventInfoBundleName(AccessibilityEventInfo &uiEvent)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
std::string windowsBundleNameCache = "";
GetA11yWindowsBundleName(uiEvent.GetWindowId(), windowsBundleNameCache);
if (!windowsBundleNameCache.empty()) {
uiEvent.SetBundleName(windowsBundleNameCache);
return;
}
std::vector<AccessibilityWindowInfo> windowsInfo = GetAccessibilityWindows();
if (windowsInfo.empty()) {
HILOG_DEBUG("GetAccessibilityWindows is empty");
return;
}
for (auto &window : windowsInfo) {
const std::string currentBundleName = window.GetBundleName();
int32_t currentWid = window.GetWindowId();
if (currentBundleName != "" && uiEvent.GetWindowId() == currentWid) {
uiEvent.SetBundleName(currentBundleName);
HILOG_DEBUG("GetAccessibilityWindows windowId:[%{public}d], BundleName:[%{public}s]",
currentWid, currentBundleName.c_str());
break;
}
}
}
void AccessibilityWindowManager::SetEventInfoBundleNameOld(AccessibilityEventInfo &uiEvent,
const int32_t windowId, std::map<int32_t, AccessibilityWindowInfo> &oldA11yWindows)
{
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
std::string bundNameCache = "";
if (oldA11yWindows.count(windowId)) {
bundNameCache = oldA11yWindows[windowId].GetBundleName();
HILOG_DEBUG("SetEventInfoBundleNameOld windowId:[%{public}d], BundleName:[%{public}s]",
windowId, bundNameCache.c_str());
uiEvent.SetBundleName(bundNameCache);
return;
}
SetEventInfoBundleName(uiEvent);
}
RetError AccessibilityWindowManager::GetFocusedWindowId(int32_t &focusedWindowId)
{
HILOG_DEBUG();
#ifdef OHOS_BUILD_ENABLE_HITRACE
HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "QueryFocusedWindowInfo");
#endif
Rosen::FocusChangeInfo focusedWindowInfo;
OHOS::Rosen::WindowManager::GetInstance(accountId_).GetFocusWindowInfo(focusedWindowInfo);
if (focusedWindowInfo.windowId_ == INVALID_WINDOW_ID) {
return RET_ERR_INVALID_PARAM;
}
focusedWindowId = focusedWindowInfo.windowId_;
return RET_OK;
}
bool AccessibilityWindowManager::IsInnerWindowRootElement(int64_t elementId)
{
HILOG_DEBUG("IsInnerWindowRootElement elementId: %{public}" PRId64 "", elementId);
auto mapTable = sceneBoardElementIdMap_.GetAllPairs();
for (auto iter = mapTable.begin(); iter != mapTable.end(); iter++) {
if (elementId == iter->second) {
return true;
}
}
return false;
}
void AccessibilityWindowManager::InsertTreeIdWindowIdPair(int32_t treeId, int32_t windowId)
{
if (windowId == 1) {
return;
}
windowTreeIdMap_.EnsureInsert(treeId, windowId);
}
void AccessibilityWindowManager::RemoveTreeIdWindowIdPair(int32_t treeId)
{
windowTreeIdMap_.Erase(treeId);
}
int32_t AccessibilityWindowManager::FindTreeIdWindowIdPair(int32_t treeId)
{
return windowTreeIdMap_.ReadVal(treeId);
}
void AccessibilityWindowManager::ClearSceneBoard()
{
HILOG_INFO();
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
subWindows_.clear();
sceneBoardElementIdMap_.Clear();
}
void AccessibilityWindowManager::InitSceneBoard()
{
HILOG_INFO();
std::vector<AccessibilityWindowInfo> windows = GetAccessibilityWindows();
if (windows.empty()) {
HILOG_WARN("GetAccessibilityWindows is empty");
return;
}
std::lock_guard<ffrt::recursive_mutex> lock(interfaceMutex_);
for (auto& window : windows) {
if (window.IsSceneBoard()) {
subWindows_.insert({window.GetWindowId(), window.GetDisplayId()});
sceneBoardElementIdMap_.InsertPair(window.GetWindowId(), window.GetUiNodeId());
}
}
}
bool AccessibilityWindowManager::CheckWindowIdEventExist(int32_t windowId)
{
AccessibilityEventInfo eventInfo;
return windowFocusEventMap_.Find(windowId, eventInfo);
}
void AccessibilityWindowManager::IsCheckWindowIdEventExist(int32_t windowId)
{
if (CheckWindowIdEventExist(windowId)) {
AccessibilityEventInfoParcel eventInfoParcel(windowFocusEventMap_.ReadVal(windowId));
auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
aams.InnerSendEvent(eventInfoParcel, 0, accountId_);
windowFocusEventMap_.Erase(windowId);
}
}
}
}