• 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     const std::string& screenName = screen->name_.size() <= SCREEN_NAME_MAX_LENGTH ?
199         screen->name_ : screen->name_.substr(0, SCREEN_NAME_MAX_LENGTH);
200     std::string isGroup = screen->isScreenGroup_ ? "true" : "false";
201     std::string screenType = TransferTypeToString(screen->type_);
202     std::string isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false";
203     NodeId nodeId = (screen->rsDisplayNode_ == nullptr) ? SCREEN_ID_INVALID : screen->rsDisplayNode_->GetId();
204     std::ostringstream oss;
205     oss << "ScreenName: " << screenName << std::endl;
206     oss << "Type: " << screenType << std::endl;
207     oss << "IsGroup: " << isGroup << std::endl;
208     oss << "DmsId: " << screen->dmsId_ << std::endl;
209     oss << "RsId: " << screen->rsId_ << std::endl;
210     oss << "GroupDmsId: " << screen->groupDmsId_ << std::endl;
211     oss << "ActiveIdx: " << screen->activeIdx_ << std::endl;
212     oss << "VPR: " << screen->virtualPixelRatio_ << std::endl;
213     oss << "Rotation: " << static_cast<uint32_t>(screen->rotation_) << std::endl;
214     oss << "Orientation: " << static_cast<uint32_t>(screen->orientation_) << std::endl;
215     oss << "RequestOrientation: " << static_cast<uint32_t>(screen->screenRequestedOrientation_) << std::endl;
216     oss << "NodeId: " << nodeId << std::endl;
217     oss << "IsMirrored: " << isMirrored << std::endl;
218     oss << "MirrorNodeId: " << screen->rSDisplayNodeConfig_.mirrorNodeId << std::endl;
219     dumpInfo.append(oss.str());
220     return DMError::DM_OK;
221 }
222 
DumpAllDisplayInfo(std::string & dumpInfo) const223 DMError DisplayDumper::DumpAllDisplayInfo(std::string& dumpInfo) const
224 {
225     std::vector<DisplayId> displayIds = abstractDisplayController_->GetAllDisplayIds();
226     std::ostringstream oss;
227     oss << "--------------------------------------Display Info"
228         << "--------------------------------------"
229         << std::endl;
230     oss << "DisplayId ScreenId RefreshRate VPR Rotation Orientation FreezeFlag [ x    y    w    h    ]"
231         << std::endl;
232     std::lock_guard<std::recursive_mutex> lock(mutex_);
233     for (DisplayId displayId : displayIds) {
234         auto display = abstractDisplayController_->GetAbstractDisplay(displayId);
235         if (display == nullptr) {
236             WLOGFE("display is null");
237             return DMError::DM_ERROR_NULLPTR;
238         }
239         GetDisplayInfo(display, oss);
240     }
241     dumpInfo.append(oss.str());
242     return DMError::DM_OK;
243 }
244 
DumpSpecifiedDisplayInfo(DisplayId displayId,std::string & dumpInfo) const245 DMError DisplayDumper::DumpSpecifiedDisplayInfo(DisplayId displayId, std::string& dumpInfo) const
246 {
247     auto display = abstractDisplayController_->GetAbstractDisplay(displayId);
248     if (display == nullptr) {
249         WLOGFE("display is null");
250         return DMError::DM_ERROR_NULLPTR;
251     }
252     std::ostringstream oss;
253     oss << "DisplayId: " << display->GetId() << std::endl;
254     oss << "ScreenId: " << display->GetAbstractScreenId() << std::endl;
255     oss << "RefreshRate: " << display->GetRefreshRate() << std::endl;
256     oss << "VPR: " << display->GetVirtualPixelRatio() << std::endl;
257     oss << "Rotation: " << static_cast<uint32_t>(display->GetRotation()) << std::endl;
258     oss << "Orientation: " << static_cast<uint32_t>(display->GetOrientation()) << std::endl;
259     oss << "FreezeFlag: " << static_cast<uint32_t>(display->GetFreezeFlag()) << std::endl;
260     oss << "DisplayRect: " << "[ "
261         << display->GetOffsetX() << ", " << display->GetOffsetY() << ", "
262         << display->GetWidth() << ", " << display->GetHeight() << " ]" << std::endl;
263     dumpInfo.append(oss.str());
264     return DMError::DM_OK;
265 }
266 
IsValidDigitString(const std::string & idStr) const267 bool DisplayDumper::IsValidDigitString(const std::string& idStr) const
268 {
269     if (idStr.empty()) {
270         return false;
271     }
272     for (char ch : idStr) {
273         if ((ch >= '0' && ch <= '9')) {
274             continue;
275         }
276         WLOGFE("invalid id");
277         return false;
278     }
279     return true;
280 }
281 
TransferTypeToString(ScreenType type) const282 std::string DisplayDumper::TransferTypeToString(ScreenType type) const
283 {
284     std::string screenType;
285     switch (type) {
286         case ScreenType::REAL:
287             screenType = "REAL";
288             break;
289         case ScreenType::VIRTUAL:
290             screenType = "VIRTUAL";
291             break;
292         default:
293             screenType = "UNDEFINED";
294             break;
295     }
296     return screenType;
297 }
298 
GetScreenInfo(const sptr<AbstractScreen> & screen,std::ostringstream & oss) const299 void DisplayDumper::GetScreenInfo(const sptr<AbstractScreen>& screen, std::ostringstream& oss) const
300 {
301     if (screen == nullptr) {
302         WLOGFE("screen is null");
303         return;
304     }
305     const std::string& screenName = screen->name_.size() <= SCREEN_NAME_MAX_LENGTH ?
306         screen->name_ : screen->name_.substr(0, SCREEN_NAME_MAX_LENGTH);
307     std::string isGroup = screen->isScreenGroup_ ? "true" : "false";
308     std::string screenType = TransferTypeToString(screen->type_);
309     std::string isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false";
310     NodeId nodeId = (screen->rsDisplayNode_ == nullptr) ? SCREEN_ID_INVALID : screen->rsDisplayNode_->GetId();
311     // std::setw is used to set the output width and different width values are set to keep the format aligned.
312     oss << std::left << std::setw(21) << screenName
313         << std::left << std::setw(9) << screenType
314         << std::left << std::setw(8) << isGroup
315         << std::left << std::setw(6) << screen->dmsId_
316         << std::left << std::setw(21) << screen->rsId_
317         << std::left << std::setw(10) << screen->activeIdx_
318         << std::left << std::setw(4) << screen->virtualPixelRatio_
319         << std::left << std::setw(9) << static_cast<uint32_t>(screen->rotation_)
320         << std::left << std::setw(12) << static_cast<uint32_t>(screen->orientation_)
321         << std::left << std::setw(19) << static_cast<uint32_t>(screen->screenRequestedOrientation_)
322         << std::left << std::setw(21) << nodeId
323         << std::left << std::setw(11) << isMirrored
324         << std::left << std::setw(13) << screen->rSDisplayNodeConfig_.mirrorNodeId
325         << std::endl;
326 }
327 
GetDisplayInfo(const sptr<AbstractDisplay> & display,std::ostringstream & oss) const328 void DisplayDumper::GetDisplayInfo(const sptr<AbstractDisplay>& display, std::ostringstream& oss) const
329 {
330     if (display == nullptr) {
331         WLOGFE("display is null");
332         return;
333     }
334     // std::setw is used to set the output width and different width values are set to keep the format aligned.
335     oss << std::left << std::setw(10) << display->GetId()
336         << std::left << std::setw(9) << display->GetAbstractScreenId()
337         << std::left << std::setw(12) << display->GetRefreshRate()
338         << std::left << std::setw(4) << display->GetVirtualPixelRatio()
339         << std::left << std::setw(9) << static_cast<uint32_t>(display->GetRotation())
340         << std::left << std::setw(12) << static_cast<uint32_t>(display->GetOrientation())
341         << std::left << std::setw(11) << static_cast<uint32_t>(display->GetFreezeFlag())
342         << "[ "
343         << std::left << std::setw(5) << display->GetOffsetX()
344         << std::left << std::setw(5) << display->GetOffsetY()
345         << std::left << std::setw(5) << display->GetWidth()
346         << std::left << std::setw(5) << display->GetHeight()
347         << "]"
348         << std::endl;
349 }
350 }
351 }