/*
 * 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 // OHOS_BUILD_ENABLE_HITRACE

#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; // s
}

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 // OHOS_BUILD_ENABLE_HITRACE
    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: // 1
                WindowUpdateAdded(infos);
                break;
            case Rosen::WindowUpdateType::WINDOW_UPDATE_REMOVED: // 2
                WindowUpdateRemoved(infos);
                break;
            case Rosen::WindowUpdateType::WINDOW_UPDATE_BOUNDS: // 4
                WindowUpdateBounds(infos);
                break;
            case Rosen::WindowUpdateType::WINDOW_UPDATE_ACTIVE: // 5
                WindowUpdateActive(infos);
                break;
            case Rosen::WindowUpdateType::WINDOW_UPDATE_FOCUSED: // 3
                WindowUpdateFocused(infos);
                break;
            case Rosen::WindowUpdateType::WINDOW_UPDATE_PROPERTY: // 6
                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(),
        [&currentBundleName](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;
    }
    // Send event
    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 // OHOS_BUILD_ENABLE_HITRACE
    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);
    }
}
} // namespace Accessibility
} // namespace OHOS