diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index bd797a1a..416682de 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -1212,6 +1212,7 @@ void WindowImpl::SetDefaultOption() property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); break; } + case WindowType::SYSTEM_WINDOW_END: // SYSTEM_WINDOW_END is for boot animation, is unfocusable. case WindowType::WINDOW_TYPE_POINTER: { property_->SetFocusable(false); break; diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 7224420b..86758ba4 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -93,6 +93,7 @@ ohos_shared_library("libwms") { "ces_standard:cesfwk_innerkits", "graphic_standard:surface", "hilog_native:libhilog", + "hisysevent_native:libhisysevent", "ipc:ipc_core", "multimodalinput_base:libmmi-client", "safwk:system_ability_fwk", diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 9cd558f1..4f965cdd 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -62,6 +62,7 @@ public: void NotifyDisplayDestroy(DisplayId displayId); void NotifySystemBarTints(); WMError RaiseZOrderForAppWindow(sptr& node); + void FocusFaultDetection() const; float GetVirtualPixelRatio(DisplayId displayId) const; private: @@ -69,12 +70,14 @@ private: WMError DestroyWindowInner(sptr& node); void UpdateFocusWindowWithWindowRemoved(const sptr& node, const sptr& container) const; + std::string GenAllWindowsLogInfo() const; bool CheckDisplayInfo(const sptr& display); std::recursive_mutex& mutex_; std::map> windowNodeContainerMap_; std::map> windowNodeMap_; std::map, uint32_t> windowIdMap_; + bool needCheckFocusWindow = false; std::map>> windowManagerAgents_; diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index efaf27a0..6e9b0773 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -71,6 +71,7 @@ WMError WindowController::AddWindowNode(sptr& property) if (res != WMError::WM_OK) { return res; } + windowRoot_->FocusFaultDetection(); FlushWindowInfo(property->GetWindowId()); if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || @@ -96,6 +97,7 @@ WMError WindowController::RemoveWindowNode(uint32_t windowId) if (res != WMError::WM_OK) { return res; } + windowRoot_->FocusFaultDetection(); FlushWindowInfo(windowId); return res; } @@ -111,6 +113,7 @@ WMError WindowController::DestroyWindow(uint32_t windowId, bool onlySelf) if (res != WMError::WM_OK) { return res; } + windowRoot_->FocusFaultDetection(); FlushWindowInfoWithDisplayId(displayId); return res; } @@ -385,6 +388,7 @@ WMError WindowController::ProcessWindowTouchedEvent(uint32_t windowId) WLOGFI("ProcessWindowTouchedEvent end"); return WMError::WM_OK; } + windowRoot_->FocusFaultDetection(); return WMError::WM_ERROR_INVALID_OPERATION; } diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 6a67ba3b..88f03a48 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -16,6 +16,7 @@ #include "window_root.h" #include +#include #include "display_manager_service_inner.h" #include "window_helper.h" @@ -171,6 +172,7 @@ WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node) } if (res == WMError::WM_OK && node->GetWindowProperty()->GetFocusable()) { container->SetFocusWindow(node->GetWindowId()); + needCheckFocusWindow = true; } return res; } @@ -467,6 +469,60 @@ WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mo return ret; } +std::string WindowRoot::GenAllWindowsLogInfo() const +{ + std::ostringstream os; + WindowNodeOperationFunc func = [&os](sptr node) { + if (node == nullptr) { + WLOGE("WindowNode is nullptr"); + return false; + } + os<<"window_name:"<GetWindowName()<<",id:"<GetWindowId()<< + ",focusable:"<GetWindowProperty()->GetFocusable()<<";"; + return false; + }; + + for (auto& elem : windowNodeContainerMap_) { + if (elem.second == nullptr) { + continue; + } + os<<"Display "<GetDisplayId()<<":"; + elem.second->TraverseWindowTree(func, true); + } + return os.str(); +} + +void WindowRoot::FocusFaultDetection() const +{ + if (!needCheckFocusWindow) { + return; + } + bool needReport = true; + uint32_t focusWinId = INVALID_WINDOW_ID; + for (auto& elem : windowNodeContainerMap_) { + if (elem.second == nullptr) { + continue; + } + focusWinId = elem.second->GetFocusWindow(); + if (focusWinId != INVALID_WINDOW_ID) { + needReport = false; + sptr windowNode = GetWindowNode(focusWinId); + if (windowNode == nullptr || !windowNode->currentVisibility_) { + needReport = true; + WLOGFE("The focus windowNode is nullptr or is invisible, focusWinId: %{public}u", focusWinId); + break; + } + } + } + if (needReport) { + std::string windowLog(GenAllWindowsLogInfo()); + WLOGFE("The focus window is faulty, focusWinId:%{public}u, %{public}s", focusWinId, windowLog.c_str()); + OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, "NO_FOCUS_WINDOW", + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, "PID", getpid(), "UID", getuid(), + "FOCUS_WINDOW", focusWinId, "FAULT_INFO", windowLog); + } +} + void WindowRoot::NotifyDisplayDestroy(DisplayId expandDisplayId) { WLOGFD("disconnect expand display, get default and expand display container");