/* * Copyright (c) 2024 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 "screen_session_dumper.h" #include #include #include "unique_fd.h" #include "screen_session_manager.h" #include "session_permission.h" #include "parameters.h" namespace OHOS { namespace Rosen { namespace { constexpr int LINE_WIDTH = 30; const std::string ARG_DUMP_HELP = "-h"; const std::string ARG_DUMP_ALL = "-a"; const std::string ARG_DUMP_FOLD_STATUS = "-f"; const std::string STATUS_FOLD_HALF = "-z"; const std::string STATUS_EXPAND = "-y"; const std::string STATUS_FOLD = "-p"; const std::string ARG_FOLD_DISPLAY_FULL = "-f"; const std::string ARG_FOLD_DISPLAY_MAIN = "-m"; const std::string ARG_FOLD_DISPLAY_SUB = "-sub"; const std::string ARG_FOLD_DISPLAY_COOR = "-coor"; const std::vector displayModeCommands = {"-f", "-m", "-sub", "-coor"}; const std::string ARG_LOCK_FOLD_DISPLAY_STATUS = "-l"; const std::string ARG_UNLOCK_FOLD_DISPLAY_STATUS = "-u"; } static std::string GetProcessNameByPid(int32_t pid) { std::string filePath = "/proc/" + std::to_string(pid) + "/comm"; char tmpPath[PATH_MAX] = { 0 }; if (!realpath(filePath.c_str(), tmpPath)) { return "UNKNOWN"; } std::ifstream infile(filePath); if (!infile.is_open()) { return "UNKNOWN"; } std::string processName = "UNKNOWN"; std::getline(infile, processName); infile.close(); return processName; } ScreenSessionDumper::ScreenSessionDumper(int fd, const std::vector& args) : fd_(fd) { std::wstring_convert, char16_t> cv; std::string info; for (auto& u16str: args) { std::string arg = cv.to_bytes(u16str); params_.emplace_back(arg); info += arg; } TLOGI(WmsLogTag::DMS, "input args: [%{public}s]", info.c_str()); } void ScreenSessionDumper::OutputDumpInfo() { if (fd_ < 0) { TLOGE(WmsLogTag::DMS, "invalid fd: %{public}d", fd_); return; } static_cast(signal(SIGPIPE, SIG_IGN)); // ignore SIGPIPE crash int ret = dprintf(fd_, "%s\n", dumpInfo_.c_str()); if (ret < 0) { TLOGE(WmsLogTag::DMS, "dprintf error. ret: %{public}d", ret); return; } dumpInfo_.clear(); } void ScreenSessionDumper::ExcuteDumpCmd() { if (params_.empty() || params_[0] == ARG_DUMP_HELP) { //help command ShowHelpInfo(); } if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) { TLOGE(WmsLogTag::DMS, "dump permission denied!"); return; } if (!params_.empty() && params_[0] == ARG_DUMP_ALL) { // dump all info command ShowAllScreenInfo(); } else if (!params_.empty() && params_[0] == ARG_DUMP_FOLD_STATUS) { // dump fold status command DumpFoldStatus(); } ExcuteInjectCmd(); OutputDumpInfo(); } void ScreenSessionDumper::ExcuteInjectCmd() { bool isDebugMode = system::GetBoolParameter("dms.hidumper.supportdebug", false); if (!isDebugMode) { TLOGI(WmsLogTag::DMS, "Can't use DMS hidumper inject methods."); dumpInfo_.append("dms.hidumper.supportdebug false\n"); return; } if (params_[0] == STATUS_FOLD_HALF || params_[0] == STATUS_EXPAND || params_[0] == STATUS_FOLD) { ShowNotifyFoldStatusChangedInfo(); } else if (params_.size() == 1 && IsValidDisplayModeCommand(params_[0])) { int errCode = SetFoldDisplayMode(); if (errCode != 0) { ShowIllegalArgsInfo(); } } else if (params_.size() == 1 && (params_[0] == ARG_LOCK_FOLD_DISPLAY_STATUS || params_[0] == ARG_UNLOCK_FOLD_DISPLAY_STATUS)) { int errCode = SetFoldStatusLocked(); if (errCode != 0) { ShowIllegalArgsInfo(); } } } void ScreenSessionDumper::DumpEventTracker(EventTracker& tracker) { std::ostringstream oss; auto recordInfos = tracker.GetRecordInfos(); oss << "-------------- DMS KEY EVENTS LIST --------------" << std::endl; for (const auto& info : recordInfos) { oss << std::left << "[" << tracker.formatTimestamp(info.timestamp).c_str() << "]: " << info.info.c_str() << std::endl; } dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpMultiUserInfo(std::vector oldScbPids, int32_t userId, int32_t ScbPid) { std::ostringstream oss; oss << "-------------- DMS Multi User Info --------------" << std::endl; oss << std::left << "[oldScbPid:] "; for (auto oldScbPid : oldScbPids) { oss << oldScbPid << " "; } oss << std::endl; oss << std::left << "[userId:] " << userId << std::endl; oss << std::left << "[ScbPid:] " << ScbPid << std::endl; dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpFreezedPidList(std::set pidList) { std::ostringstream oss; oss << "-------------- DMS FREEZED PID LIST --------------" << std::endl; for (auto pid : pidList) { oss << std::left << "[PID: " << pid << "]: " << " [" << GetProcessNameByPid(pid) << "]"<< std::endl; } dumpInfo_.append(oss.str()); } void ScreenSessionDumper::ShowHelpInfo() { dumpInfo_.append("Usage:\n") .append(" -h ") .append("|help text for the tool\n") .append(" -a ") .append("|dump all screen information in the system\n") .append(" -z ") .append("|switch to fold half status\n") .append(" -y ") .append("|switch to expand status\n") .append(" -p ") .append("|switch to fold status\n") .append(" -f ") .append("|get to fold status\n"); } void ScreenSessionDumper::ShowAllScreenInfo() { std::vector screenIds = ScreenSessionManager::GetInstance().GetAllScreenIds(); for (auto screenId : screenIds) { std::ostringstream oss; oss << "---------------- Screen ID: " << screenId << " ----------------" << std::endl; dumpInfo_.append(oss.str()); DumpFoldStatus(); DumpScreenSessionById(screenId); DumpRsInfoById(screenId); DumpCutoutInfoById(screenId); DumpScreenInfoById(screenId); DumpScreenPropertyById(screenId); } } void ScreenSessionDumper::DumpFoldStatus() { std::ostringstream oss; auto foldStatus = ScreenSessionManager::GetInstance().GetFoldStatus(); std::string status = ""; switch (foldStatus) { case FoldStatus::EXPAND: { status = "EXPAND"; break; } case FoldStatus::FOLDED: { status = "FOLDED"; break; } case FoldStatus::HALF_FOLD: { status = "HALF_FOLD"; break; } default: { status = "UNKNOWN"; break; } } oss << std::left << std::setw(LINE_WIDTH) << "FoldStatus: " << status << std::endl; dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpScreenSessionById(ScreenId id) { std::ostringstream oss; oss << "[SCREEN SESSION]" << std::endl; auto screenSession = ScreenSessionManager::GetInstance().GetScreenSession(id); if (screenSession == nullptr) { TLOGE(WmsLogTag::DMS, "screenSession nullptr. screen id: %{public}" PRIu64"", id); return; } oss << std::left << std::setw(LINE_WIDTH) << "Name: " << screenSession->GetName() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "RSScreenId: " << screenSession->GetRSScreenId() << std::endl; sptr activeModes = screenSession->GetActiveScreenMode(); if (activeModes != nullptr) { oss << std::left << std::setw(LINE_WIDTH) << "activeModes: " << activeModes->id_ << ", " << activeModes->width_ << ", " << activeModes->height_ << ", " << activeModes->refreshRate_ << std::endl; } oss << std::left << std::setw(LINE_WIDTH) << "SourceMode: " << static_cast(screenSession->GetSourceMode()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "ScreenCombination: " << static_cast(screenSession->GetScreenCombination()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Orientation: " << static_cast(screenSession->GetOrientation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Rotation: " << static_cast(screenSession->GetRotation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "ScreenRequestedOrientation: " << static_cast(screenSession->GetScreenRequestedOrientation()) << std::endl; dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpRsInfoById(ScreenId id) { std::ostringstream oss; oss << "[RS INFO]" << std::endl; auto screenSession = ScreenSessionManager::GetInstance().GetScreenSession(id); if (screenSession == nullptr) { TLOGE(WmsLogTag::DMS, "screenSession nullptr. screen id: %{public}" PRIu64"", id); return; } std::vector colorGamuts; DMError ret = screenSession->GetScreenSupportedColorGamuts(colorGamuts); if (ret == DMError::DM_OK && colorGamuts.size() > 0) { oss << std::left << std::setw(LINE_WIDTH) << "SupportedColorGamuts: "; for (uint32_t i = 0; i < colorGamuts.size() - 1; i++) { oss << static_cast(colorGamuts[i]) << ", "; } oss << static_cast(colorGamuts[colorGamuts.size() - 1]) << std::endl; } ScreenColorGamut colorGamut; ret = screenSession->GetScreenColorGamut(colorGamut); if (ret == DMError::DM_OK) { oss << std::left << std::setw(LINE_WIDTH) << "ScreenColorGamut: " << static_cast(colorGamut) << std::endl; } ScreenGamutMap gamutMap; ret = screenSession->GetScreenGamutMap(gamutMap); if (ret == DMError::DM_OK) { oss << std::left << std::setw(LINE_WIDTH) << "ScreenGamutMap: " << static_cast(gamutMap) << std::endl; } GraphicPixelFormat pixelFormat; ret = screenSession->GetPixelFormat(pixelFormat); if (ret == DMError::DM_OK) { oss << std::left << std::setw(LINE_WIDTH) << "GraphicPixelFormat: " << static_cast(pixelFormat) << std::endl; } dumpInfo_.append(oss.str()); DumpRsInfoById01(screenSession); // 拆分函数,避免函数过长 } void ScreenSessionDumper::DumpRsInfoById01(sptr screenSession) { std::ostringstream oss; std::vector hdrFormats; DMError ret = screenSession->GetSupportedHDRFormats(hdrFormats); if (ret == DMError::DM_OK && hdrFormats.size() > 0) { oss << std::left << std::setw(LINE_WIDTH) << "SupportedScreenHDRFormat: "; for (uint32_t i = 0; i < hdrFormats.size() - 1; i++) { oss << static_cast(hdrFormats[i]) << ", "; } oss << static_cast(hdrFormats[hdrFormats.size() - 1]) << std::endl; } ScreenHDRFormat hdrFormat; ret = screenSession->GetScreenHDRFormat(hdrFormat); if (ret == DMError::DM_OK) { oss << std::left << std::setw(LINE_WIDTH) << "ScreenHDRFormat: " << static_cast(hdrFormat) << std::endl; } std::vector colorSpaces; ret = screenSession->GetSupportedColorSpaces(colorSpaces); if (ret == DMError::DM_OK && colorSpaces.size() > 0) { oss << std::left << std::setw(LINE_WIDTH) << "SupportedColorSpaces: "; for (uint32_t i = 0; i < colorSpaces.size() - 1; i++) { oss << static_cast(colorSpaces[i]) << ", "; } oss << static_cast(colorSpaces[colorSpaces.size() - 1]) << std::endl; } GraphicCM_ColorSpaceType colorSpace; ret = screenSession->GetScreenColorSpace(colorSpace); if (ret == DMError::DM_OK) { oss << std::left << std::setw(LINE_WIDTH) << "ScreenColorSpace: " << static_cast(colorSpace) << std::endl; } dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpCutoutInfoById(ScreenId id) { std::ostringstream oss; oss << "[CUTOUT INFO]" << std::endl; sptr cutoutInfo = ScreenSessionManager::GetInstance().GetCutoutInfo(id); if (cutoutInfo == nullptr) { TLOGE(WmsLogTag::DMS, "cutoutInfo nullptr. screen id: %{public}" PRIu64"", id); return; } oss << std::left << std::setw(LINE_WIDTH) << "WaterFall_L: " << cutoutInfo->GetWaterfallDisplayAreaRects().left.posX_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().left.posY_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().left.width_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().left.height_ << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "WaterFall_T: " << cutoutInfo->GetWaterfallDisplayAreaRects().top.posX_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().top.posY_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().top.width_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().top.height_ << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "WaterFall_R: " << cutoutInfo->GetWaterfallDisplayAreaRects().right.posX_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().right.posY_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().right.width_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().right.height_ << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "WaterFall_B: " << cutoutInfo->GetWaterfallDisplayAreaRects().bottom.posX_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().bottom.posY_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().bottom.width_ << ", " << cutoutInfo->GetWaterfallDisplayAreaRects().bottom.height_ << std::endl; std::vector boundingRects = cutoutInfo->GetBoundingRects(); oss << std::left << std::setw(LINE_WIDTH) << "BoundingRects: "; for (auto rect : boundingRects) { oss << "[" << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_ << "] "; } oss << std::endl; dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpScreenInfoById(ScreenId id) { std::ostringstream oss; oss << "[SCREEN INFO]" << std::endl; auto screenInfo = ScreenSessionManager::GetInstance().GetScreenInfoById(id); if (screenInfo == nullptr) { TLOGE(WmsLogTag::DMS, "screenInfo nullptr. screen id: %{public}" PRIu64"", id); return; } oss << std::left << std::setw(LINE_WIDTH) << "VirtualWidth: " << screenInfo->GetVirtualWidth() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "VirtualHeight: " << screenInfo->GetVirtualHeight() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "LastParentId: " << screenInfo->GetLastParentId() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "ParentId: " << screenInfo->GetParentId() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "IsScreenGroup: " << screenInfo->GetIsScreenGroup() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "VirtualPixelRatio: " << screenInfo->GetVirtualPixelRatio() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Rotation: " << static_cast(screenInfo->GetRotation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Orientation: " << static_cast(screenInfo->GetOrientation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "SourceMode: " << static_cast(screenInfo->GetSourceMode()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "ScreenType: " << static_cast(screenInfo->GetType()) << std::endl; dumpInfo_.append(oss.str()); } void ScreenSessionDumper::DumpScreenPropertyById(ScreenId id) { std::ostringstream oss; oss << "[SCREEN PROPERTY]" << std::endl; ScreenProperty screenProperty = ScreenSessionManager::GetInstance().GetScreenProperty(id); oss << std::left << std::setw(LINE_WIDTH) << "Rotation: " << screenProperty.GetRotation() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Density: " << screenProperty.GetDensity() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "DensityInCurResolution: " << screenProperty.GetDensityInCurResolution() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "PhyWidth: " << screenProperty.GetPhyWidth() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "PhyHeight: " << screenProperty.GetPhyHeight() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "RefreshRate: " << screenProperty.GetRefreshRate() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "VirtualPixelRatio: " << screenProperty.GetVirtualPixelRatio() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "ScreenRotation: " << static_cast(screenProperty.GetRotation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Orientation: " << static_cast(screenProperty.GetOrientation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "DisplayOrientation: " << static_cast(screenProperty.GetDisplayOrientation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "GetScreenType: " << static_cast(screenProperty.GetScreenType()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "ReqOrientation: " << static_cast(screenProperty.GetScreenRequestedOrientation()) << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "DPI: " << screenProperty.GetXDpi() << ", " << screenProperty.GetYDpi() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Offset: " << screenProperty.GetOffsetX() << ", " << screenProperty.GetOffsetY() << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "Bounds: " << screenProperty.GetBounds().rect_.GetLeft() << ", " << screenProperty.GetBounds().rect_.GetTop() << ", " << screenProperty.GetBounds().rect_.GetWidth() << ", " << screenProperty.GetBounds().rect_.GetHeight() << ", " << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "PhyBounds: " << screenProperty.GetPhyBounds().rect_.GetLeft() << ", " << screenProperty.GetPhyBounds().rect_.GetTop() << ", " << screenProperty.GetPhyBounds().rect_.GetWidth() << ", " << screenProperty.GetPhyBounds().rect_.GetHeight() << ", " << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "AvailableArea " << screenProperty.GetAvailableArea().posX_ << ", " << screenProperty.GetAvailableArea().posY_ << ", " << screenProperty.GetAvailableArea().width_ << ", " << screenProperty.GetAvailableArea().height_ << ", " << std::endl; oss << std::left << std::setw(LINE_WIDTH) << "DefaultDeviceRotationOffset " << screenProperty.GetDefaultDeviceRotationOffset() << std::endl; dumpInfo_.append(oss.str()); } /* * hidumper inject methods */ void ScreenSessionDumper::ShowNotifyFoldStatusChangedInfo() { TLOGI(WmsLogTag::DMS, "params_: [%{public}s]", params_[0].c_str()); int errCode = ScreenSessionManager::GetInstance().NotifyFoldStatusChanged(params_[0]); if (errCode != 0) { ShowIllegalArgsInfo(); } else { std::ostringstream oss; oss << "currentFoldStatus is: " << static_cast(ScreenSessionManager::GetInstance().GetFoldStatus()) << std::endl; dumpInfo_.append(oss.str()); } } void ScreenSessionDumper::ShowIllegalArgsInfo() { dumpInfo_.append("The arguments are illegal and you can enter '-h' for help."); } bool ScreenSessionDumper::IsValidDisplayModeCommand(std::string command) { if (std::find(displayModeCommands.begin(), displayModeCommands.end(), command) != displayModeCommands.end()) { return true; } return false; } int ScreenSessionDumper::SetFoldDisplayMode() { std::string modeParam = params_[0]; if (modeParam.empty()) { return -1; } FoldDisplayMode displayMode = FoldDisplayMode::UNKNOWN; if (modeParam == ARG_FOLD_DISPLAY_FULL) { displayMode = FoldDisplayMode::FULL; } else if (modeParam == ARG_FOLD_DISPLAY_MAIN) { displayMode = FoldDisplayMode::MAIN; } else if (modeParam == ARG_FOLD_DISPLAY_SUB) { displayMode = FoldDisplayMode::SUB; } else if (modeParam == ARG_FOLD_DISPLAY_COOR) { displayMode = FoldDisplayMode::COORDINATION; } else { TLOGW(WmsLogTag::DMS, "SetFoldDisplayMode mode not support"); return -1; } ScreenSessionManager::GetInstance().SetFoldDisplayMode(displayMode); return 0; } int ScreenSessionDumper::SetFoldStatusLocked() { std::string lockParam = params_[0]; if (lockParam.empty()) { return -1; } bool lockDisplayStatus = false; if (lockParam == ARG_LOCK_FOLD_DISPLAY_STATUS) { lockDisplayStatus = true; } else if (lockParam == ARG_UNLOCK_FOLD_DISPLAY_STATUS) { lockDisplayStatus = false; } else { TLOGW(WmsLogTag::DMS, "SetFoldStatusLocked status not support"); return -1; } ScreenSessionManager::GetInstance().SetFoldStatusLocked(lockDisplayStatus); return 0; } } // Rosen } // OHOS