1 /*
2 * Copyright (c) 2025 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 #include "gfx/dump/rs_dump_manager.h"
16
17 #include <vector>
18 #include <string>
19 #include <future>
20
21 #include "platform/common/rs_log.h"
22 #include "rs_trace.h"
23
24 namespace OHOS::Rosen {
25 // Define a static constant to represent the fixed length of HELPINFO_CMD
26 static const size_t HELPINFO_CMD_FIXED_LENGTH = 30;
27
RSDumpManager()28 RSDumpManager::RSDumpManager()
29 {
30 // Register the help information function to the function mapping table
31 RSDumpFunc helpInfoFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
32 std::string &dumpString) -> void {
33 DumpHelpInfo(dumpString);
34 };
35 Register({ RSDumpID::HELP_INFO, helpInfoFunc });
36 }
37
38 // Get the instance of RSDumpManager
GetInstance()39 RSDumpManager& RSDumpManager::GetInstance()
40 {
41 // Define a static RSDumpManager object to ensure only one instance is created
42 static RSDumpManager instance;
43 return instance;
44 }
45
46 // Register a module to RSDumpManager
Register(RSDumpHander rsDumpHander)47 void RSDumpManager::Register(RSDumpHander rsDumpHander)
48 {
49 RSDumpID rsDumpId = rsDumpHander.rsDumpId;
50 if (rsDumpHanderMap_.find(rsDumpId) != rsDumpHanderMap_.end()) {
51 // If the module ID already exists, output a warning message
52 RS_LOGW("RSDumpManager::Register, rsDumpId %{public}d is already exist.", static_cast<int>(rsDumpId));
53 } else {
54 rsDumpHanderMap_[rsDumpId] = rsDumpHander;
55 }
56 }
57
58 // Register multiple Dump points to RSDumpManager
Register(const std::vector<RSDumpHander> & rsDumpHanders)59 void RSDumpManager::Register(const std::vector<RSDumpHander> &rsDumpHanders)
60 {
61 if (rsDumpHanders.empty()) {
62 return;
63 }
64 for (const auto &rsDumpHander : rsDumpHanders) {
65 Register(rsDumpHander);
66 }
67 }
68
69 // Unregister a Dump point
UnRegister(RSDumpID rsDumpId)70 void RSDumpManager::UnRegister(RSDumpID rsDumpId)
71 {
72 auto it = rsDumpHanderMap_.find(rsDumpId);
73 if (it != rsDumpHanderMap_.end()) {
74 rsDumpHanderMap_.erase(it);
75 } else {
76 // If the Dump point does not exist, output a warning message
77 RS_LOGW("RSDumpManager::UnRegister, rsDumpId %{public}d is not exist.", static_cast<int>(rsDumpId));
78 }
79 }
80
81 // Execute a command
CmdExec(std::unordered_set<std::u16string> & argSets,std::string & out)82 void RSDumpManager::CmdExec(std::unordered_set<std::u16string>& argSets, std::string &out)
83 {
84 if (!argSets.empty()) {
85 MatchAndExecuteCommand(argSets, out);
86 } else {
87 // If the parameters are empty, output an error message
88 RS_LOGW("RSDumpManager::CmdExec, args is empty.");
89 DumpHelpInfo(out);
90 }
91 }
92
93 // Match and execute a command
MatchAndExecuteCommand(std::unordered_set<std::u16string> & argSets,std::string & out)94 void RSDumpManager::MatchAndExecuteCommand(std::unordered_set<std::u16string> &argSets, std::string &out)
95 {
96 for (const std::u16string &cmd : argSets) {
97 auto it = cmdMap_.find(cmd);
98 if (it != cmdMap_.end()) {
99 std::string cmd_str = std::string(cmd.begin(), cmd.end());
100 RS_LOGI("RSDumpManager::cmdExec, cmd is '%{public}s'.", cmd_str.c_str());
101
102 RSDumpCmd entry = it->second;
103 for (RSDumpID rsDumpId : entry.rsDumpIds) {
104 DoDump(rsDumpId, cmd, argSets, out);
105 }
106 break;
107 }
108 }
109 if (out.empty()) {
110 // If the command is not found, output help information
111 DumpHelpInfo(out);
112 }
113 }
114
115 // Execute a specific dump operation
DoDump(RSDumpID rsDumpId,const std::u16string & cmd,std::unordered_set<std::u16string> & argSets,std::string & out)116 void RSDumpManager::DoDump(RSDumpID rsDumpId, const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
117 std::string &out)
118 {
119 RS_TRACE_NAME_FMT("RSDumpManager::DoDump rsDumpId [%d]", rsDumpId);
120 RS_LOGI("RSDumpManager::DoDump, rsDumpId is '%{public}d'.", static_cast<uint8_t>(rsDumpId));
121 auto it = rsDumpHanderMap_.find(rsDumpId);
122 if (it != rsDumpHanderMap_.end()) {
123 RSDumpHander hander = it->second;
124 if (!hander.tag.empty() && hander.tag.size() > 0) {
125 out.append("\n\n-- ").append(hander.tag).append("\n");
126 }
127 hander.func(cmd, argSets, out);
128 } else {
129 // If the hander is not registered, output an error message
130 RS_LOGE("RSDumpManager::DoDump, rsDumpId %{public}d not registered.", static_cast<int>(rsDumpId));
131 }
132 }
133
134 // Generate help information
DumpHelpInfo(std::string & out)135 void RSDumpManager::DumpHelpInfo(std::string &out)
136 {
137 out.append("------ Graphic2D--RenderSerice ------\n")
138 .append("Usage:\n");
139 for (const auto &entry : cmdMap_) {
140 std::u16string cmd = entry.first;
141 if (excludeCmds_.find(cmd) != excludeCmds_.end()) {
142 continue;
143 }
144 std::string cmd_str = std::string(cmd.begin(), cmd.end());
145 out.append(cmd_str)
146 .append(HELPINFO_CMD_FIXED_LENGTH - cmd_str.length(), ' ')
147 .append("|")
148 .append(entry.second.helpInfo)
149 .append("\n");
150 }
151 }
152 } // namespace OHOS::Rosen