• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "display_dumper.h"
17 
18 #include <cinttypes>
19 #include <csignal>
20 #include <iomanip>
21 #include <map>
22 #include <sstream>
23 #include <string_ex.h>
24 #include <unique_fd.h>
25 
26 #include "window_manager_hilog.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 namespace {
31     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DisplayDumper"};
32 
33     constexpr int SCREEN_NAME_MAX_LENGTH = 20;
34     const std::string ARG_DUMP_HELP = "-h";
35     const std::string ARG_DUMP_ALL = "-a";
36     const std::string ARG_DUMP_SCREEN = "-s";
37     const std::string ARG_DUMP_DISPLAY = "-d";
38 }
39 
DisplayDumper(const sptr<AbstractDisplayController> & abstractDisplayController,const sptr<AbstractScreenController> & abstractScreenController,std::recursive_mutex & mutex)40 DisplayDumper::DisplayDumper(const sptr<AbstractDisplayController>& abstractDisplayController,
41     const sptr<AbstractScreenController>& abstractScreenController, std::recursive_mutex& mutex)
42     : abstractDisplayController_(abstractDisplayController), abstractScreenController_(abstractScreenController),
43     mutex_(mutex)
44 {
45 }
46 
Dump(int fd,const std::vector<std::u16string> & args) const47 DMError DisplayDumper::Dump(int fd, const std::vector<std::u16string>& args) const
48 {
49     WLOGFI("Dump begin fd: %{public}d", fd);
50     if (fd < 0) {
51         return DMError::DM_ERROR_INVALID_PARAM;
52     }
53     (void) signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE crash
54     UniqueFd ufd = UniqueFd(fd); // auto close
55     fd = ufd.Get();
56     std::vector<std::string> params;
57     for (auto& arg : args) {
58         params.emplace_back(Str16ToStr8(arg));
59     }
60 
61     std::string dumpInfo;
62     if (params.empty()) {
63         ShowHelpInfo(dumpInfo);
64     } else if (params.size() == 1 && params[0] == ARG_DUMP_HELP) { // 1: params num
65         ShowHelpInfo(dumpInfo);
66     } else {
67         DMError errCode = DumpInfo(params, dumpInfo);
68         if (errCode != DMError::DM_OK) {
69             ShowIllegalArgsInfo(dumpInfo, errCode);
70         }
71     }
72     int ret = dprintf(fd, "%s\n", dumpInfo.c_str());
73     if (ret < 0) {
74         WLOGFE("dprintf error");
75         return DMError::DM_ERROR_UNKNOWN;
76     }
77     WLOGFI("Dump end");
78     return DMError::DM_OK;
79 }
80 
ShowHelpInfo(std::string & dumpInfo) const81 void DisplayDumper::ShowHelpInfo(std::string& dumpInfo) const
82 {
83     dumpInfo.append("Usage:\n")
84         .append(" -h                          ")
85         .append("|help text for the tool\n")
86         .append(" -s -a                       ")
87         .append("|dump all screen information in the system\n")
88         .append(" -d -a                       ")
89         .append("|dump all display information in the system\n")
90         .append(" -s {screen id}              ")
91         .append("|dump specified screen information\n")
92         .append(" -d {display id}             ")
93         .append("|dump specified display information\n");
94 }
95 
ShowIllegalArgsInfo(std::string & dumpInfo,DMError errCode) const96 void DisplayDumper::ShowIllegalArgsInfo(std::string& dumpInfo, DMError errCode) const
97 {
98     switch (errCode) {
99         case DMError::DM_ERROR_INVALID_PARAM:
100             dumpInfo.append("The arguments are illegal and you can enter '-h' for help.");
101             break;
102         case DMError::DM_ERROR_NULLPTR:
103             dumpInfo.append("The screen or display is invalid, ")
104                 .append("you can enter '-s -a' or '-d -a' to get valid screen or display id.");
105             break;
106         default:
107             break;
108     }
109 }
110 
DumpInfo(const std::vector<std::string> & args,std::string & dumpInfo) const111 DMError DisplayDumper::DumpInfo(const std::vector<std::string>& args, std::string& dumpInfo) const
112 {
113     if (args.size() != 2) { // 2: params num
114         return DMError::DM_ERROR_INVALID_PARAM;
115     }
116 
117     if (args[0] == ARG_DUMP_SCREEN && args[1] == ARG_DUMP_ALL) {
118         return DumpAllScreenInfo(dumpInfo);
119     } else if (args[0] == ARG_DUMP_DISPLAY && args[1] == ARG_DUMP_ALL) {
120         return DumpAllDisplayInfo(dumpInfo);
121     } else if (args[0] == ARG_DUMP_SCREEN && IsValidDigitString(args[1])) {
122         ScreenId screenId = std::stoull(args[1]);
123         return DumpSpecifiedScreenInfo(screenId, dumpInfo);
124     } else if (args[0] == ARG_DUMP_DISPLAY && IsValidDigitString(args[1])) {
125         DisplayId displayId = std::stoull(args[1]);
126         return DumpSpecifiedDisplayInfo(displayId, dumpInfo);
127     } else {
128         return DMError::DM_ERROR_INVALID_PARAM;
129     }
130 }
131 
DumpAllScreenInfo(std::string & dumpInfo) const132 DMError DisplayDumper::DumpAllScreenInfo(std::string& dumpInfo) const
133 {
134     std::map<ScreenId, sptr<AbstractScreenGroup>> screenGroups;
135     std::vector<ScreenId> screenIds = abstractScreenController_->GetAllScreenIds();
136     std::ostringstream oss;
137     oss << "--------------------------------------Free Screen"
138         << "--------------------------------------"
139         << std::endl;
140     oss << "ScreenName           Type     IsGroup DmsId RsId                 ActiveIdx VPR Rotation Orientation "
141         << "RequestOrientation NodeId               IsMirrored MirrorNodeId"
142         << std::endl;
143     std::lock_guard<std::recursive_mutex> lock(mutex_);
144     for (ScreenId screenId : screenIds) {
145         auto screen = abstractScreenController_->GetAbstractScreen(screenId);
146         if (screen == nullptr) {
147             WLOGFE("screen is null");
148             return DMError::DM_ERROR_NULLPTR;
149         }
150         if (SCREEN_ID_INVALID == screen->groupDmsId_ || screen->isScreenGroup_) {
151             GetScreenInfo(screen, oss);
152         }
153         if (screen->isScreenGroup_) {
154             auto screenGroup = abstractScreenController_->GetAbstractScreenGroup(screenId);
155             screenGroups.insert(std::make_pair(screenId, screenGroup));
156         }
157     }
158     oss << "total screen num: " << screenIds.size() << std::endl;
159     dumpInfo.append(oss.str());
160     for (auto it = screenGroups.begin(); it != screenGroups.end(); it++) {
161         DMError ret = DumpScreenInfo(it->second, dumpInfo);
162         if (ret != DMError::DM_OK) {
163             return ret;
164         }
165     }
166     return DMError::DM_OK;
167 }
168 
DumpScreenInfo(const sptr<AbstractScreenGroup> & screenGroup,std::string & dumpInfo) const169 DMError DisplayDumper::DumpScreenInfo(const sptr<AbstractScreenGroup>& screenGroup, std::string& dumpInfo) const
170 {
171     if (screenGroup == nullptr) {
172         WLOGFE("screenGroup is null");
173         return DMError::DM_ERROR_NULLPTR;
174     }
175     std::ostringstream oss;
176     oss << "-------------------------------------ScreenGroup " << screenGroup->dmsId_
177         << "-------------------------------------"
178         << std::endl;
179     oss << "ScreenName           Type     IsGroup DmsId RsId                 "
180         << "ActiveIdx VPR Rotation Orientation "
181         << "RequestOrientation NodeId               IsMirrored MirrorNodeId"
182         << std::endl;
183     auto childrenScreen = screenGroup->GetChildren();
184     for (auto screen : childrenScreen) {
185         GetScreenInfo(screen, oss);
186     }
187     dumpInfo.append(oss.str());
188     return DMError::DM_OK;
189 }
190 
DumpSpecifiedScreenInfo(ScreenId screenId,std::string & dumpInfo) const191 DMError DisplayDumper::DumpSpecifiedScreenInfo(ScreenId screenId, std::string& dumpInfo) const
192 {
193     auto screen = abstractScreenController_->GetAbstractScreen(screenId);
194     if (screen == nullptr) {
195         WLOGFE("screen is null");
196         return DMError::DM_ERROR_NULLPTR;
197     }
198 
199     const std::string& name = screen->GetScreenName();
200     const std::string& screenName = name.size() <= SCREEN_NAME_MAX_LENGTH ?
201         name : name.substr(0, SCREEN_NAME_MAX_LENGTH);
202     std::string isGroup = screen->isScreenGroup_ ? "true" : "false";
203     std::string screenType = TransferTypeToString(screen->type_);
204     std::string isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false";
205     NodeId nodeId = (screen->rsDisplayNode_ == nullptr) ? SCREEN_ID_INVALID : screen->rsDisplayNode_->GetId();
206     std::ostringstream oss;
207     oss << "ScreenName: " << screenName << std::endl;
208     oss << "Type: " << screenType << std::endl;
209     oss << "IsGroup: " << isGroup << std::endl;
210     oss << "DmsId: " << screen->dmsId_ << std::endl;
211     oss << "RsId: " << screen->rsId_ << std::endl;
212     oss << "GroupDmsId: " << screen->groupDmsId_ << std::endl;
213     oss << "ActiveIdx: " << screen->activeIdx_ << std::endl;
214     oss << "VPR: " << screen->virtualPixelRatio_ << std::endl;
215     oss << "Rotation: " << static_cast<uint32_t>(screen->rotation_) << std::endl;
216     oss << "Orientation: " << static_cast<uint32_t>(screen->orientation_) << std::endl;
217     oss << "RequestOrientation: " << static_cast<uint32_t>(screen->screenRequestedOrientation_) << std::endl;
218     oss << "NodeId: " << nodeId << std::endl;
219     oss << "IsMirrored: " << isMirrored << std::endl;
220     oss << "MirrorNodeId: " << screen->rSDisplayNodeConfig_.mirrorNodeId << std::endl;
221     dumpInfo.append(oss.str());
222     return DMError::DM_OK;
223 }
224 
DumpAllDisplayInfo(std::string & dumpInfo) const225 DMError DisplayDumper::DumpAllDisplayInfo(std::string& dumpInfo) const
226 {
227     std::vector<DisplayId> displayIds = abstractDisplayController_->GetAllDisplayIds();
228     std::ostringstream oss;
229     oss << "--------------------------------------Display Info"
230         << "--------------------------------------"
231         << std::endl;
232     oss << "DisplayId ScreenId RefreshRate VPR Rotation Orientation DisplayOrientation FreezeFlag [ x   y   w   h   ]"
233         << std::endl;
234     std::lock_guard<std::recursive_mutex> lock(mutex_);
235     for (DisplayId displayId : displayIds) {
236         auto display = abstractDisplayController_->GetAbstractDisplay(displayId);
237         if (display == nullptr) {
238             WLOGFE("display is null");
239             return DMError::DM_ERROR_NULLPTR;
240         }
241         GetDisplayInfo(display, oss);
242     }
243     dumpInfo.append(oss.str());
244     return DMError::DM_OK;
245 }
246 
DumpSpecifiedDisplayInfo(DisplayId displayId,std::string & dumpInfo) const247 DMError DisplayDumper::DumpSpecifiedDisplayInfo(DisplayId displayId, std::string& dumpInfo) const
248 {
249     auto display = abstractDisplayController_->GetAbstractDisplay(displayId);
250     if (display == nullptr) {
251         WLOGFE("display is null");
252         return DMError::DM_ERROR_NULLPTR;
253     }
254     std::ostringstream oss;
255     oss << "DisplayId: " << display->GetId() << std::endl;
256     oss << "ScreenId: " << display->GetAbstractScreenId() << std::endl;
257     oss << "RefreshRate: " << display->GetRefreshRate() << std::endl;
258     oss << "VPR: " << display->GetVirtualPixelRatio() << std::endl;
259     oss << "Rotation: " << static_cast<uint32_t>(display->GetRotation()) << std::endl;
260     oss << "Orientation: " << static_cast<uint32_t>(display->GetOrientation()) << std::endl;
261     oss << "DisplayOrientation: " << static_cast<uint32_t>(display->GetDisplayOrientation()) << std::endl;
262     oss << "FreezeFlag: " << static_cast<uint32_t>(display->GetFreezeFlag()) << std::endl;
263     oss << "DisplayRect: " << "[ "
264         << display->GetOffsetX() << ", " << display->GetOffsetY() << ", "
265         << display->GetWidth() << ", " << display->GetHeight() << " ]" << std::endl;
266     dumpInfo.append(oss.str());
267     return DMError::DM_OK;
268 }
269 
IsValidDigitString(const std::string & idStr) const270 bool DisplayDumper::IsValidDigitString(const std::string& idStr) const
271 {
272     if (idStr.empty()) {
273         return false;
274     }
275     for (char ch : idStr) {
276         if ((ch >= '0' && ch <= '9')) {
277             continue;
278         }
279         WLOGFE("invalid id");
280         return false;
281     }
282     return true;
283 }
284 
TransferTypeToString(ScreenType type) const285 std::string DisplayDumper::TransferTypeToString(ScreenType type) const
286 {
287     std::string screenType;
288     switch (type) {
289         case ScreenType::REAL:
290             screenType = "REAL";
291             break;
292         case ScreenType::VIRTUAL:
293             screenType = "VIRTUAL";
294             break;
295         default:
296             screenType = "UNDEFINED";
297             break;
298     }
299     return screenType;
300 }
301 
GetScreenInfo(const sptr<AbstractScreen> & screen,std::ostringstream & oss) const302 void DisplayDumper::GetScreenInfo(const sptr<AbstractScreen>& screen, std::ostringstream& oss) const
303 {
304     if (screen == nullptr) {
305         WLOGFE("screen is null");
306         return;
307     }
308 
309     const std::string& name = screen->GetScreenName();
310     const std::string& screenName = name.size() <= SCREEN_NAME_MAX_LENGTH ?
311         name : name.substr(0, SCREEN_NAME_MAX_LENGTH);
312     std::string isGroup = screen->isScreenGroup_ ? "true" : "false";
313     std::string screenType = TransferTypeToString(screen->type_);
314     std::string isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false";
315     NodeId nodeId = (screen->rsDisplayNode_ == nullptr) ? SCREEN_ID_INVALID : screen->rsDisplayNode_->GetId();
316     // std::setw is used to set the output width and different width values are set to keep the format aligned.
317     oss << std::left << std::setw(21) << screenName
318         << std::left << std::setw(9) << screenType
319         << std::left << std::setw(8) << isGroup
320         << std::left << std::setw(6) << screen->dmsId_
321         << std::left << std::setw(21) << screen->rsId_
322         << std::left << std::setw(10) << screen->activeIdx_
323         << std::left << std::setw(4) << screen->virtualPixelRatio_
324         << std::left << std::setw(9) << static_cast<uint32_t>(screen->rotation_)
325         << std::left << std::setw(12) << static_cast<uint32_t>(screen->orientation_)
326         << std::left << std::setw(19) << static_cast<uint32_t>(screen->screenRequestedOrientation_)
327         << std::left << std::setw(21) << nodeId
328         << std::left << std::setw(11) << isMirrored
329         << std::left << std::setw(13) << screen->rSDisplayNodeConfig_.mirrorNodeId
330         << std::endl;
331 }
332 
GetDisplayInfo(const sptr<AbstractDisplay> & display,std::ostringstream & oss) const333 void DisplayDumper::GetDisplayInfo(const sptr<AbstractDisplay>& display, std::ostringstream& oss) const
334 {
335     if (display == nullptr) {
336         WLOGFE("display is null");
337         return;
338     }
339     // std::setw is used to set the output width and different width values are set to keep the format aligned.
340     oss << std::left << std::setw(10) << display->GetId()
341         << std::left << std::setw(9) << display->GetAbstractScreenId()
342         << std::left << std::setw(12) << display->GetRefreshRate()
343         << std::left << std::setw(4) << display->GetVirtualPixelRatio()
344         << std::left << std::setw(9) << static_cast<uint32_t>(display->GetRotation())
345         << std::left << std::setw(12) << static_cast<uint32_t>(display->GetOrientation())
346         << std::left << std::setw(18) << static_cast<uint32_t>(display->GetDisplayOrientation())
347         << std::left << std::setw(11) << static_cast<uint32_t>(display->GetFreezeFlag())
348         << "[ "
349         << std::left << std::setw(5) << display->GetOffsetX()
350         << std::left << std::setw(5) << display->GetOffsetY()
351         << std::left << std::setw(5) << display->GetWidth()
352         << std::left << std::setw(5) << display->GetHeight()
353         << "]"
354         << std::endl;
355 }
356 }
357 }