diff --git a/wm/src/window_manager.cpp b/wm/src/window_manager.cpp index 7bc769c5..83ff3abe 100644 --- a/wm/src/window_manager.cpp +++ b/wm/src/window_manager.cpp @@ -271,15 +271,15 @@ void WindowManager::Impl::NotifyAccessibilityWindowInfo(const sptrcurrentWindowInfo_->wid_, windowInfo->currentWindowInfo_->windowRect_.width_, windowInfo->currentWindowInfo_->windowRect_.height_, windowInfo->currentWindowInfo_->windowRect_.posX_, windowInfo->currentWindowInfo_->windowRect_.posY_, windowInfo->currentWindowInfo_->focused_, windowInfo->currentWindowInfo_->isDecorEnable_, windowInfo->currentWindowInfo_->displayId_, - windowInfo->currentWindowInfo_->mode_, windowInfo->currentWindowInfo_->type_); + windowInfo->currentWindowInfo_->mode_, windowInfo->currentWindowInfo_->type_, type); std::vector> windowUpdateListeners; { std::lock_guard lock(mutex_); diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 3fbff3d4..2b6f4a96 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -32,6 +32,7 @@ ohos_shared_library("libwms") { sources = [ "../wm/src/zidl/window_manager_agent_proxy.cpp", "../wm/src/zidl/window_proxy.cpp", + "src/accessibility_connection.cpp", "src/avoid_area_controller.cpp", "src/display_group_controller.cpp", "src/display_group_info.cpp", diff --git a/wmserver/include/accessibility_connection.h b/wmserver/include/accessibility_connection.h new file mode 100644 index 00000000..f9b430b0 --- /dev/null +++ b/wmserver/include/accessibility_connection.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifndef OHOS_ROSEN_ACCESSIBILITY_CONNECTION_H +#define OHOS_ROSEN_ACCESSIBILITY_CONNECTION_H + +#include +#include +#include + +#include "window_node.h" +#include "window_root.h" +#include "window_node_container.h" +#include "wm_common.h" + +namespace OHOS::Rosen { +class AccessibilityConnection : public RefBase { +public: + explicit AccessibilityConnection(sptr& root) : windowRoot_(root) {} + ~AccessibilityConnection() = default; + void NotifyAccessibilityInfo(const sptr& node, WindowUpdateType type); + void GetAccessibilityWindowInfo(sptr& windowInfo) const; + +private: + sptr windowRoot_; + std::map, uint32_t> focusedWindowMap_; + void NotifyAccessibilityWindowInfo(const sptr& container, const sptr& node, + WindowUpdateType type) const; + void GetWindowList(const sptr& container, std::vector>& windowList) const; + void FillWindowInfo(const sptr& node, uint32_t focusedWindow, sptr& windowInfo) const; +}; +} +#endif // OHOS_ROSEN_ACCESSIBILITY_CONTROLLER_H diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index 2bab9012..8eb37c22 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -18,6 +18,8 @@ #include #include + +#include "accessibility_connection.h" #include "input_window_monitor.h" #include "zidl/window_manager_agent_interface.h" #include "window_root.h" @@ -29,7 +31,7 @@ namespace Rosen { class WindowController : public RefBase { public: WindowController(sptr& root, sptr inputWindowMonitor) : windowRoot_(root), - inputWindowMonitor_(inputWindowMonitor) {} + inputWindowMonitor_(inputWindowMonitor), accessibilityConnection_(new AccessibilityConnection(windowRoot_)) {} ~WindowController() = default; WMError CreateWindow(sptr& window, sptr& property, @@ -64,6 +66,8 @@ public: sptr& finishCallback); Orientation GetWindowPreferredOrientation(DisplayId displayId); void OnScreenshot(DisplayId displayId); + WMError GetAccessibilityWindowInfo(sptr& windowInfo) const; + private: uint32_t GenWindowId(); void FlushWindowInfo(uint32_t windowId); @@ -92,6 +96,7 @@ private: sptr windowRoot_; sptr inputWindowMonitor_; + sptr accessibilityConnection_; std::atomic windowId_ { INVALID_WINDOW_ID }; // Remove 'sysBarWinId_' after SystemUI resize 'systembar', systemBar only exist on default display currently std::unordered_map sysBarWinId_ { diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index dc4510b2..dcd5a3b5 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -62,7 +62,6 @@ public: uint64_t GetScreenId(DisplayId displayId) const; Rect GetDisplayRect(DisplayId displayId) const; std::unordered_map GetExpectImmersiveProperty() const; - void NotifyAccessibilityWindowInfo(const sptr& windowId, WindowUpdateType type) const; uint32_t GetWindowCountByType(WindowType windowType); bool IsForbidDockSliceMove(DisplayId displayId) const; bool IsDockSliceInExitSplitModeArea(DisplayId displayId) const; @@ -90,7 +89,6 @@ public: Rect GetDisplayGroupRect() const; void TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom = true) const; void UpdateSizeChangeReason(sptr& node, WindowSizeChangeReason reason); - void GetWindowList(std::vector>& windowList) const; void DropShowWhenLockedWindowIfNeeded(const sptr& node); void SetMinimizedByOther(bool isMinimizedByOther); @@ -151,7 +149,6 @@ private: void UpdateRSTreeWhenShowingDisplaysChange(sptr& node, const std::vector& lastShowingDisplays, const std::vector& curShowingDisplays); - void FillWindowInfo(sptr& windowInfo, const sptr& node) const; bool CheckWindowNodeWhetherInWindowTree(const sptr& node) const; void UpdateModeSupportInfoWhenKeyguardChange(const sptr& node, bool up); diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 05874d07..73e56cf2 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -84,7 +84,6 @@ public: void SetBrightness(uint32_t windowId, float brightness); void HandleKeepScreenOn(uint32_t windowId, bool requireLock); void UpdateFocusableProperty(uint32_t windowId); - WMError GetAccessibilityWindowInfo(sptr& windowInfo); void SetMaxAppWindowNumber(int windowNum); WMError GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config); diff --git a/wmserver/src/accessibility_connection.cpp b/wmserver/src/accessibility_connection.cpp new file mode 100644 index 00000000..5c4f93a0 --- /dev/null +++ b/wmserver/src/accessibility_connection.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2022 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_connection.h" + +#include "display_manager_service_inner.h" +#include "window_manager.h" +#include "window_manager_agent_controller.h" +#include "window_manager_hilog.h" + +namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "AccessibilityConnection"}; +} + +void AccessibilityConnection::NotifyAccessibilityInfo(const sptr& node, WindowUpdateType type) +{ + auto container = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (node == nullptr || container == nullptr) { + WLOGFE("window node or container is null"); + return; + } + bool focusChange = false; + uint32_t focusWindowId = container->GetFocusWindow(); + auto iter = focusedWindowMap_.find(container); + if (iter == focusedWindowMap_.end()) { + focusedWindowMap_.insert(std::make_pair(container, focusWindowId)); + if (focusWindowId != INVALID_WINDOW_ID) { + focusChange = true; + } + } else { + if (focusWindowId != iter->second) { + focusChange = true; + iter->second = focusWindowId; + } + } + WLOGFI("notify accessibility window info: [%{public}u %{public}u %{public}d %{public}d]", + node->GetWindowId(), focusWindowId, focusChange, static_cast(type)); + // need handle focus change + switch (type) { + case WindowUpdateType::WINDOW_UPDATE_ADDED: + if (node->currentVisibility_) { + NotifyAccessibilityWindowInfo(container, node, type); + } + break; + case WindowUpdateType::WINDOW_UPDATE_REMOVED: + NotifyAccessibilityWindowInfo(container, node, type); + break; + case WindowUpdateType::WINDOW_UPDATE_PROPERTY: + NotifyAccessibilityWindowInfo(container, node, type); + break; + default: + break; + } + if (focusChange) { + auto focusWindowNode = windowRoot_->GetWindowNode(focusWindowId); + if (focusWindowNode == nullptr) { + WLOGFE("could not find window"); + return; + } + NotifyAccessibilityWindowInfo(container, focusWindowNode, WindowUpdateType::WINDOW_UPDATE_FOCUSED); + } +} + +void AccessibilityConnection::NotifyAccessibilityWindowInfo(const sptr& container, + const sptr& node, WindowUpdateType type) const +{ + sptr windowInfo = new (std::nothrow) WindowInfo(); + sptr accessibilityWindowInfo = new (std::nothrow) AccessibilityWindowInfo(); + if (windowInfo != nullptr && accessibilityWindowInfo != nullptr) { + FillWindowInfo(node, container->GetFocusWindow(), windowInfo); + accessibilityWindowInfo->currentWindowInfo_ = windowInfo; + GetWindowList(container, accessibilityWindowInfo->windowList_); + WindowManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityWindowInfo, type); + } +} + +void AccessibilityConnection::GetWindowList(const sptr& container, + std::vector>& windowList) const +{ + std::vector> nodes; + container->TraverseContainer(nodes); + for (auto& node : nodes) { + sptr windowInfo = new (std::nothrow) WindowInfo(); + if (windowInfo != nullptr) { + FillWindowInfo(node, container->GetFocusWindow(), windowInfo); + windowList.emplace_back(windowInfo); + } + } +} + +void AccessibilityConnection::FillWindowInfo(const sptr& node, uint32_t focusedWindow, + sptr& windowInfo) const +{ + windowInfo->wid_ = static_cast(node->GetWindowId()); + windowInfo->windowRect_ = node->GetWindowRect(); + windowInfo->focused_ = node->GetWindowId() == focusedWindow; + windowInfo->displayId_ = node->GetDisplayId(); + windowInfo->mode_ = node->GetWindowMode(); + windowInfo->type_ = node->GetWindowType(); + auto property = node->GetWindowProperty(); + if (property != nullptr) { + windowInfo->isDecorEnable_ = property->GetDecorEnable(); + } +} + +void AccessibilityConnection::GetAccessibilityWindowInfo(sptr& windowInfo) const +{ + std::map> windowNodeContainers; + std::vector displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds(); + for (DisplayId displayId : displayIds) { + ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); + auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); + if (windowNodeContainers.count(screenGroupId) == 0 && container != nullptr) { + windowNodeContainers.insert(std::make_pair(screenGroupId, container)); + GetWindowList(container, windowInfo->windowList_); + } + } +} +} diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index e78e78fe..2f861aeb 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -240,6 +240,7 @@ WMError WindowController::AddWindowNode(sptr& property) windowRoot_->FocusFaultDetection(); FlushWindowInfo(property->GetWindowId()); HandleTurnScreenOn(node); + accessibilityConnection_->NotifyAccessibilityInfo(node, WindowUpdateType::WINDOW_UPDATE_ADDED); if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) { @@ -348,7 +349,12 @@ void WindowController::HandleTurnScreenOn(const sptr& node) WMError WindowController::RemoveWindowNode(uint32_t windowId) { - auto removeFunc = [this, windowId]() { + auto windowNode = windowRoot_->GetWindowNode(windowId); + if (windowNode == nullptr) { + WLOGFE("windowNode is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + auto removeFunc = [this, windowId, windowNode]() { WMError res = windowRoot_->RemoveWindowNode(windowId); if (res != WMError::WM_OK) { WLOGFE("RemoveWindowNode failed"); @@ -356,13 +362,9 @@ WMError WindowController::RemoveWindowNode(uint32_t windowId) } windowRoot_->FocusFaultDetection(); FlushWindowInfo(windowId); + accessibilityConnection_->NotifyAccessibilityInfo(windowNode, WindowUpdateType::WINDOW_UPDATE_REMOVED); return res; }; - auto windowNode = windowRoot_->GetWindowNode(windowId); - if (windowNode == nullptr) { - WLOGFE("windowNode is nullptr"); - return WMError::WM_ERROR_NULLPTR; - } WMError res = WMError::WM_ERROR_NO_REMOTE_ANIMATION; if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) { if (RemoteAnimation::NotifyAnimationScreenUnlock(removeFunc) == WMError::WM_OK) { @@ -392,6 +394,7 @@ WMError WindowController::DestroyWindow(uint32_t windowId, bool onlySelf) } windowRoot_->FocusFaultDetection(); FlushWindowInfoWithDisplayId(displayId); + accessibilityConnection_->NotifyAccessibilityInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); return res; } @@ -441,7 +444,10 @@ WMError WindowController::RequestFocus(uint32_t windowId) if (windowRoot_ == nullptr) { return WMError::WM_ERROR_NULLPTR; } - return windowRoot_->RequestFocus(windowId); + WMError res = windowRoot_->RequestFocus(windowId); + accessibilityConnection_->NotifyAccessibilityInfo(windowRoot_->GetWindowNode(windowId), + WindowUpdateType::WINDOW_UPDATE_FOCUSED); + return res; } WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode) @@ -688,6 +694,8 @@ WMError WindowController::ProcessPointDown(uint32_t windowId, bool isStartDrag) windowRoot_->RequestActiveWindow(windowId); if (zOrderRes == WMError::WM_OK || focusRes == WMError::WM_OK) { FlushWindowInfo(windowId); + accessibilityConnection_->NotifyAccessibilityInfo(windowRoot_->GetWindowNode(windowId), + WindowUpdateType::WINDOW_UPDATE_FOCUSED); WLOGFI("ProcessPointDown end"); return WMError::WM_OK; } @@ -896,7 +904,8 @@ WMError WindowController::UpdateProperty(sptr& property, Propert case PropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA: { std::vector rects; property->GetTouchHotAreas(rects); - return UpdateTouchHotAreas(node, rects); + UpdateTouchHotAreas(node, rects); + break; } case PropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: { node->GetWindowProperty()->SetAnimationFlag(property->GetAnimationFlag()); @@ -912,19 +921,15 @@ WMError WindowController::UpdateProperty(sptr& property, Propert break; } if (ret == WMError::WM_OK) { - NotifyWindowPropertyChanged(node); + accessibilityConnection_->NotifyAccessibilityInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY); } return ret; } -void WindowController::NotifyWindowPropertyChanged(const sptr& node) +WMError WindowController::GetAccessibilityWindowInfo(sptr& windowInfo) const { - auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId()); - if (windowNodeContainer == nullptr) { - WLOGFE("windowNodeContainer is null"); - return; - } - windowNodeContainer->NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_PROPERTY); + accessibilityConnection_->GetAccessibilityWindowInfo(windowInfo); + return WMError::WM_OK; } WMError WindowController::GetModeChangeHotZones(DisplayId displayId, diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 92b606cc..84704794 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -659,7 +659,7 @@ WMError WindowManagerService::GetAccessibilityWindowInfo(sptrGetAccessibilityWindowInfo(windowInfo); + return windowController_->GetAccessibilityWindowInfo(windowInfo); }); } diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index fffa0704..a9d2645b 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -182,7 +182,6 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrAddWindowNode(node); NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD); DumpScreenWindowTree(); - NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_ADDED); UpdateCameraFloatWindowStatus(node, true); if (WindowHelper::IsAppWindow(node->GetWindowType())) { backupWindowIds_.clear(); @@ -295,7 +294,6 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) } NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_REMOVE); DumpScreenWindowTree(); - NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); RecoverScreenDefaultOrientationIfNeed(node->GetDisplayId()); UpdateCameraFloatWindowStatus(node, false); if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) { @@ -612,8 +610,6 @@ WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId) } UpdateFocusStatus(focusedWindow_, false); focusedWindow_ = windowId; - sptr node = FindWindowNodeById(windowId); - NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_FOCUSED); UpdateFocusStatus(focusedWindow_, true); return WMError::WM_OK; } @@ -1004,78 +1000,6 @@ void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector& windowInfo, const sptr& node) const -{ - if (windowInfo == nullptr) { - WLOGFE("windowInfo is null"); - return; - } - windowInfo->wid_ = static_cast(node->GetWindowId()); - windowInfo->windowRect_ = node->GetWindowRect(); - windowInfo->focused_ = node->GetWindowId() == focusedWindow_; - windowInfo->displayId_ = node->GetDisplayId(); - windowInfo->mode_ = node->GetWindowMode(); - windowInfo->type_ = node->GetWindowType(); - auto property = node->GetWindowProperty(); - if (property != nullptr) { - windowInfo->isDecorEnable_ = property->GetDecorEnable(); - } -} - -void WindowNodeContainer::NotifyAccessibilityWindowInfo(const sptr& node, WindowUpdateType type) const -{ - if (node == nullptr) { - WLOGFE("window node is null"); - return; - } - bool isNeedNotify = false; - switch (type) { - case WindowUpdateType::WINDOW_UPDATE_ADDED: - if (node->currentVisibility_) { - isNeedNotify = true; - } - break; - case WindowUpdateType::WINDOW_UPDATE_FOCUSED: - if (node->GetWindowId() == focusedWindow_) { - isNeedNotify = true; - } - break; - case WindowUpdateType::WINDOW_UPDATE_REMOVED: - isNeedNotify = true; - break; - case WindowUpdateType::WINDOW_UPDATE_PROPERTY: - isNeedNotify = true; - break; - default: - break; - } - if (isNeedNotify) { - std::vector> windowList; - GetWindowList(windowList); - sptr windowInfo = new (std::nothrow) WindowInfo(); - sptr accessibilityWindowInfo = new (std::nothrow) AccessibilityWindowInfo(); - if (windowInfo != nullptr && accessibilityWindowInfo != nullptr) { - FillWindowInfo(windowInfo, node); - accessibilityWindowInfo->currentWindowInfo_ = windowInfo; - accessibilityWindowInfo->windowList_ = windowList; - WindowManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityWindowInfo, type); - } - } -} - -void WindowNodeContainer::GetWindowList(std::vector>& windowList) const -{ - std::vector> windowNodes; - TraverseContainer(windowNodes); - for (auto node : windowNodes) { - sptr windowInfo = new (std::nothrow) WindowInfo(); - if (windowInfo != nullptr) { - FillWindowInfo(windowInfo, node); - windowList.emplace_back(windowInfo); - } - } -} - void WindowNodeContainer::TraverseContainer(std::vector>& windowNodes) const { for (auto& node : belowAppWindowNode_->children_) { diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 1df3e7dd..daffadb1 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -420,7 +420,7 @@ WMError WindowRoot::PostProcessAddWindowNode(sptr& node, sptr& container) { if (!node->currentVisibility_) { - WLOGFI("window is isVisible, do not need process"); + WLOGFI("window is invisible, do not need process"); return WMError::WM_DO_NOTHING; } if (WindowHelper::IsSubWindow(node->GetWindowType())) { @@ -1277,19 +1277,6 @@ Rect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const return container->GetDisplayGroupRect(); } -WMError WindowRoot::GetAccessibilityWindowInfo(sptr& windowInfo) -{ - for (auto& iter : windowNodeContainerMap_) { - auto container = iter.second; - std::vector> windowList; - container->GetWindowList(windowList); - for (auto window : windowList) { - windowInfo->windowList_.emplace_back(window); - } - } - return WMError::WM_OK; -} - void WindowRoot::SetMaxAppWindowNumber(int windowNum) { maxAppWindowNumber_ = windowNum;