diff --git a/wm/include/window_agent.h b/wm/include/window_agent.h index a7461a7c..2ba25439 100644 --- a/wm/include/window_agent.h +++ b/wm/include/window_agent.h @@ -38,6 +38,7 @@ public: void UpdateActiveStatus(bool isActive) override; sptr GetWindowProperty() override; void NotifyOutsidePressed() override; + void DumpInfo(const std::vector& params, std::vector& info) override; private: sptr window_; }; diff --git a/wm/include/zidl/window_interface.h b/wm/include/zidl/window_interface.h index d57a8585..e45a5534 100644 --- a/wm/include/zidl/window_interface.h +++ b/wm/include/zidl/window_interface.h @@ -40,6 +40,7 @@ public: TRANS_ID_UPDATE_ACTIVE_STATUS, TRANS_ID_GET_WINDOW_PROPERTY, TRANS_ID_NOTIFY_OUTSIDE_PRESSED, + TRANS_ID_DUMP_INFO, }; virtual void UpdateWindowRect(const struct Rect& rect, bool decoStatus, WindowSizeChangeReason reason) = 0; @@ -53,6 +54,7 @@ public: virtual void UpdateActiveStatus(bool isActive) = 0; virtual sptr GetWindowProperty() = 0; virtual void NotifyOutsidePressed() = 0; + virtual void DumpInfo(const std::vector& params, std::vector& info) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/zidl/window_proxy.h b/wm/include/zidl/window_proxy.h index 5b495c67..ac0c1d3f 100644 --- a/wm/include/zidl/window_proxy.h +++ b/wm/include/zidl/window_proxy.h @@ -39,6 +39,7 @@ public: void UpdateActiveStatus(bool isActive) override; sptr GetWindowProperty() override; void NotifyOutsidePressed() override; + void DumpInfo(const std::vector& params, std::vector& info) override; private: static inline BrokerDelegator delegator_; }; diff --git a/wm/src/window_agent.cpp b/wm/src/window_agent.cpp index b19377d8..b524fa39 100644 --- a/wm/src/window_agent.cpp +++ b/wm/src/window_agent.cpp @@ -127,5 +127,14 @@ void WindowAgent::NotifyOutsidePressed() WLOGFI("called"); window_->NotifyOutsidePressed(); } + +void WindowAgent::DumpInfo(const std::vector& params, std::vector& info) +{ + if (window_ == nullptr) { + WLOGFE("window_ is nullptr"); + return; + } + window_->DumpInfo(params, info); +} } // namespace Rosen } // namespace OHOS diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index e315a131..e60ffa4c 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -33,6 +33,7 @@ namespace OHOS { namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowImpl"}; + const std::string PARAM_DUMP_HELP = "-h"; } const WindowImpl::ColorSpaceConvertMap WindowImpl::colorSpaceConvertMap[] = { @@ -490,7 +491,12 @@ ColorSpace WindowImpl::GetColorSpace() void WindowImpl::DumpInfo(const std::vector& params, std::vector& info) { - WLOGFI("Ace:DumpInfo"); + if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num + WLOGFI("Dump ArkUI help Info"); + Ace::UIContent::ShowDumpHelp(info); + return; + } + WLOGFI("ArkUI:DumpInfo"); if (uiContent_ != nullptr) { uiContent_->DumpInfo(params, info); } diff --git a/wm/src/zidl/window_proxy.cpp b/wm/src/zidl/window_proxy.cpp index 071d36f7..c05ea8f6 100644 --- a/wm/src/zidl/window_proxy.cpp +++ b/wm/src/zidl/window_proxy.cpp @@ -262,6 +262,28 @@ void WindowProxy::NotifyOutsidePressed() WLOGFE("SendRequest failed"); } } + +void WindowProxy::DumpInfo(const std::vector& params, std::vector& info) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + if (!data.WriteStringVector(params)) { + WLOGFE("Write params failed"); + return; + } + if (Remote()->SendRequest(static_cast(WindowMessage::TRANS_ID_DUMP_INFO), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } + if (!reply.ReadStringVector(&info)) { + WLOGFE("Read info failed"); + } +} } // namespace Rosen } // namespace OHOS diff --git a/wm/src/zidl/window_stub.cpp b/wm/src/zidl/window_stub.cpp index a35aa93c..53f7c34e 100644 --- a/wm/src/zidl/window_stub.cpp +++ b/wm/src/zidl/window_stub.cpp @@ -111,6 +111,18 @@ int WindowStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParce NotifyOutsidePressed(); break; } + case WindowMessage::TRANS_ID_DUMP_INFO: { + std::vector params; + if (!data.ReadStringVector(¶ms)) { + WLOGFE("Fail to read params"); + } + std::vector info; + DumpInfo(params, info); + if (!reply.WriteStringVector(info)) { + WLOGFE("Fail to write info"); + } + break; + } default: break; } diff --git a/wmserver/include/window_dumper.h b/wmserver/include/window_dumper.h index 4f4458e5..4c3e1315 100644 --- a/wmserver/include/window_dumper.h +++ b/wmserver/include/window_dumper.h @@ -23,6 +23,7 @@ namespace OHOS { namespace Rosen { enum DumpType : uint32_t { DUMP_ALL = 0, + DUMP_WINDOW, DUMP_NONE = 100, }; class WindowDumper : public RefBase { @@ -33,9 +34,14 @@ public: private: WMError DumpWindowInfo(const std::vector& args, std::string& dumpInfo) const; WMError DumpAllWindowInfo(std::string& dumpInfo) const; - WMError DumpDisplayWindowInfo(DisplayId displayId, std::string& dumpInfo) const; + WMError DumpScreenGroupWindowInfo(ScreenId screenGroupId, const sptr& windowNodeContainer, + std::string& dumpInfo) const; + bool IsValidDigitString(const std::string& windowIdStr) const; + WMError DumpSpecifiedWindowInfo(uint32_t windowId, const std::vector& params, + std::string& dumpInfo) const; void ShowHelpInfo(std::string& dumpInfo) const; - void ShowIllegalArgsInfo(std::string& dumpInfo) const; + void ShowAceDumpHelp(std::string& dumpInfo) const; + void ShowIllegalArgsInfo(std::string& dumpInfo, WMError errCode) const; const sptr windowRoot_; }; } diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index d6716a11..a0f532d8 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -81,8 +81,9 @@ public: WMError GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config); std::vector GetAllDisplayIds() const; - uint32_t GetTotalWindowNum(); + uint32_t GetTotalWindowNum() const; uint32_t GetWindowIdByObject(const sptr& remoteObject); + sptr GetWindowForDumpAceHelpInfo() const; private: void OnRemoteDied(const sptr& remoteObject); WMError DestroyWindowInner(sptr& node); diff --git a/wmserver/src/window_dumper.cpp b/wmserver/src/window_dumper.cpp index 6a15c2d9..d582ce7f 100644 --- a/wmserver/src/window_dumper.cpp +++ b/wmserver/src/window_dumper.cpp @@ -31,11 +31,12 @@ namespace OHOS { namespace Rosen { namespace { - constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WindowDumper"}; + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowDumper"}; constexpr int WINDOW_NAME_MAX_LENGTH = 20; const std::string ARG_DUMP_HELP = "-h"; const std::string ARG_DUMP_ALL = "-a"; + const std::string ARG_DUMP_WINDOW = "-w"; } WMError WindowDumper::Dump(int fd, const std::vector& args) const @@ -54,13 +55,13 @@ WMError WindowDumper::Dump(int fd, const std::vector& args) cons std::string dumpInfo; if (params.empty()) { - ShowIllegalArgsInfo(dumpInfo); - } else if (params[0] == ARG_DUMP_HELP) { + ShowIllegalArgsInfo(dumpInfo, WMError::WM_ERROR_INVALID_PARAM); + } else if (params.size() == 1 && params[0] == ARG_DUMP_HELP) { // 1: params num ShowHelpInfo(dumpInfo); } else { WMError errCode = DumpWindowInfo(params, dumpInfo); - if (errCode == WMError::WM_ERROR_INVALID_PARAM) { - ShowIllegalArgsInfo(dumpInfo); + if (errCode != WMError::WM_OK) { + ShowIllegalArgsInfo(dumpInfo, errCode); } } int ret = dprintf(fd, "%s\n", dumpInfo.c_str()); @@ -72,16 +73,16 @@ WMError WindowDumper::Dump(int fd, const std::vector& args) cons return WMError::WM_OK; } -WMError WindowDumper::DumpDisplayWindowInfo(DisplayId displayId, std::string& dumpInfo) const +WMError WindowDumper::DumpScreenGroupWindowInfo(ScreenId screenGroupId, + const sptr& windowNodeContainer, std::string& dumpInfo) const { - auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); if (windowNodeContainer == nullptr) { WLOGFE("windowNodeContainer is null"); return WMError::WM_ERROR_NULLPTR; } std::ostringstream oss; - oss << "---------------------------------------Display " << displayId - << "---------------------------------------" + oss << "-------------------------------------ScreenGroup " << screenGroupId + << "-------------------------------------" << std::endl; oss << "WindowName DisplayId WinId Type Mode Flag ZOrd Orientation [ x y w h ]" << std::endl; @@ -121,16 +122,17 @@ WMError WindowDumper::DumpDisplayWindowInfo(DisplayId displayId, std::string& du WMError WindowDumper::DumpAllWindowInfo(std::string& dumpInfo) const { - std::map windowNodeContainers; + std::map> windowNodeContainers; std::vector displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds(); for (DisplayId displayId : displayIds) { + ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); - if (windowNodeContainer != nullptr) { - windowNodeContainers.emplace(windowNodeContainer.GetRefPtr(), displayId); + if (windowNodeContainers.count(screenGroupId) == 0 && windowNodeContainer != nullptr) { + windowNodeContainers.insert(std::make_pair(screenGroupId, windowNodeContainer)); } } for (auto it = windowNodeContainers.begin(); it != windowNodeContainers.end(); it++) { - WMError ret = DumpDisplayWindowInfo(it->second, dumpInfo); + WMError ret = DumpScreenGroupWindowInfo(it->first, it->second, dumpInfo); if (ret != WMError::WM_OK) { return ret; } @@ -138,20 +140,90 @@ WMError WindowDumper::DumpAllWindowInfo(std::string& dumpInfo) const return WMError::WM_OK; } +bool WindowDumper::IsValidDigitString(const std::string& windowIdStr) const +{ + if (windowIdStr.empty()) { + return false; + } + for (char ch : windowIdStr) { + if ((ch >= '0' && ch <= '9')) { + continue; + } + WLOGFE("invalid window id"); + return false; + } + return true; +} + +WMError WindowDumper::DumpSpecifiedWindowInfo(uint32_t windowId, const std::vector& params, + std::string& dumpInfo) const +{ + auto node = windowRoot_->GetWindowNode(windowId); + if (node == nullptr) { + WLOGFE("invalid window"); + return WMError::WM_ERROR_NULLPTR; + } + std::ostringstream oss; + oss << "WindowName DisplayId WinId Type Mode Flag Orientation [ x y w h ]" + << std::endl; + Rect rect = node->GetWindowRect(); + const std::string& windowName = node->GetWindowName().size() <= WINDOW_NAME_MAX_LENGTH ? + node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH); + // std::setw is used to set the output width and different width values are set to keep the format aligned. + oss << std::left << std::setw(21) << windowName + << std::left << std::setw(10) << node->GetDisplayId() + << std::left << std::setw(6) << node->GetWindowId() + << std::left << std::setw(5) << static_cast(node->GetWindowType()) + << std::left << std::setw(5) << static_cast(node->GetWindowMode()) + << std::left << std::setw(5) << node->GetWindowFlags() + << std::left << std::setw(12) << static_cast(node->GetRequestedOrientation()) + << "[ " + << std::left << std::setw(5) << rect.posX_ + << std::left << std::setw(5) << rect.posY_ + << std::left << std::setw(5) << rect.width_ + << std::left << std::setw(5) << rect.height_ + << "]" + << std::endl; + dumpInfo.append(oss.str()); + if (node->GetWindowToken() != nullptr) { + std::vector resetParams; + resetParams.assign(params.begin() + 2, params.end()); // 2: params num + if (resetParams.empty()) { + WLOGFI("do not dump ui info"); + return WMError::WM_OK; + } + std::vector infos; + node->GetWindowToken()->DumpInfo(resetParams, infos); + for (auto& info: infos) { + dumpInfo.append(info).append("\n"); + } + } + return WMError::WM_OK; +} + WMError WindowDumper::DumpWindowInfo(const std::vector& args, std::string& dumpInfo) const { if (args.empty()) { return WMError::WM_ERROR_INVALID_PARAM; } DumpType dumpType = DumpType::DUMP_NONE; - if (args[0] == ARG_DUMP_ALL) { + uint32_t windowId = INVALID_WINDOW_ID; + if (args.size() == 1 && args[0] == ARG_DUMP_ALL) { // 1: params num dumpType = DumpType::DUMP_ALL; + } else if (args.size() >= 2 && args[0] == ARG_DUMP_WINDOW && IsValidDigitString(args[1])) { // 2: params num + windowId = std::stoul(args[1]); + dumpType = DumpType::DUMP_WINDOW; + } else { + // do nothing } WMError ret = WMError::WM_OK; switch (dumpType) { case DumpType::DUMP_ALL: ret = DumpAllWindowInfo(dumpInfo); break; + case DumpType::DUMP_WINDOW: + ret = DumpSpecifiedWindowInfo(windowId, args, dumpInfo); + break; default: ret = WMError::WM_ERROR_INVALID_PARAM; break; @@ -159,22 +231,50 @@ WMError WindowDumper::DumpWindowInfo(const std::vector& args, std:: return ret; } -void WindowDumper::ShowIllegalArgsInfo(std::string& dumpInfo) const +void WindowDumper::ShowIllegalArgsInfo(std::string& dumpInfo, WMError errCode) const { - dumpInfo.append("The arguments are illegal and you can enter '-h' for help."); + switch (errCode) { + case WMError::WM_ERROR_INVALID_PARAM: + dumpInfo.append("The arguments are illegal and you can enter '-h' for help."); + break; + case WMError::WM_ERROR_NULLPTR: + dumpInfo.append("The window is invalid, you can enter '-a' to get valid window id."); + break; + default: + break; + } } void WindowDumper::ShowHelpInfo(std::string& dumpInfo) const { dumpInfo.append("Usage:\n") - .append(" -h ") + .append(" -h ") .append("|help text for the tool\n") - .append(" -a ") + .append(" -a ") .append("|dump all window infomation in the system\n") - .append(" -o ") - .append("|open starting window\n") - .append(" -c ") - .append("|close starting window\n"); + .append(" -w {window id} [ArkUI Option] ") + .append("|dump specified window information\n") + .append(" ------------------------------------[ArkUI Option]------------------------------------ \n"); + ShowAceDumpHelp(dumpInfo); +} + +void WindowDumper::ShowAceDumpHelp(std::string& dumpInfo) const +{ + std::vector infos; + auto node = windowRoot_->GetWindowForDumpAceHelpInfo(); + if (node == nullptr) { + WLOGFE("invalid window"); + return; + } + if (node->GetWindowToken() != nullptr) { + std::vector params; + params.emplace_back(ARG_DUMP_HELP); + std::vector infos; + node->GetWindowToken()->DumpInfo(params, infos); + for (auto& info: infos) { + dumpInfo.append(info).append("\n"); + } + } } } } \ No newline at end of file diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index dfd1c114..bbf3324d 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -31,11 +31,24 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowRoot"}; } -uint32_t WindowRoot::GetTotalWindowNum() +uint32_t WindowRoot::GetTotalWindowNum() const { return static_cast(windowNodeMap_.size()); } +sptr WindowRoot::GetWindowForDumpAceHelpInfo() const +{ + for (auto& iter : windowNodeMap_) { + if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP || + iter.second->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR || + iter.second->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || + iter.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) { + return iter.second; + } + } + return nullptr; +} + ScreenId WindowRoot::GetScreenGroupId(DisplayId displayId, bool& isRecordedDisplay) { for (auto iter : displayIdMap_) {