1 /*
2 * Copyright (c) 2023 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 "dscreen_hidumper.h"
17
18 #include "dscreen_errcode.h"
19 #include "dscreen_log.h"
20 #include "dscreen_util.h"
21
22 namespace OHOS {
23 namespace DistributedHardware {
24 IMPLEMENT_SINGLE_INSTANCE(DscreenHidumper);
25
26 namespace {
27 const std::string ARGS_HELP = "-h";
28 const std::string ARGS_DUMP_SCREEN_DATA = "--dump";
29 const std::string ARGS_DUMP_SCREEN_DATA_RESTART = "--redump";
30 const std::string ARGS_DUMP_SCREEN_DATA_STOP = "--stopdump";
31
32 const std::map<std::string, HidumpFlag> ARGS_MAP = {
33 { ARGS_HELP, HidumpFlag::GET_HELP },
34 { ARGS_DUMP_SCREEN_DATA, HidumpFlag::DUMP_SCREEN_DATA },
35 { ARGS_DUMP_SCREEN_DATA_RESTART, HidumpFlag::DUMP_SCREEN_DATA_RESTART },
36 { ARGS_DUMP_SCREEN_DATA_STOP, HidumpFlag::DUMP_SCREEN_DATA_STOP },
37 };
38 }
39
DscreenHidumper()40 DscreenHidumper::DscreenHidumper()
41 {
42 DHLOGI("Distributed screen hidumper constructed.");
43 }
44
~DscreenHidumper()45 DscreenHidumper::~DscreenHidumper()
46 {
47 DHLOGI("Distributed screen hidumper deconstructed.");
48 }
49
Dump(const std::vector<std::string> & args,std::string & result)50 bool DscreenHidumper::Dump(const std::vector<std::string> &args, std::string &result)
51 {
52 DHLOGI("Distributed screen hidumper dump args.size():%{public}zu.", args.size());
53 result.clear();
54 int32_t argsSize = static_cast<int32_t>(args.size());
55 for (int32_t i = 0; i < argsSize; i++) {
56 DHLOGI("Distributed screen hidumper dump args[%{public}d]: %{public}s.", i, args.at(i).c_str());
57 }
58
59 if (args.empty()) {
60 ShowHelp(result);
61 return true;
62 }
63
64 if (args.size() > 1) {
65 ShowIllegalInfomation(result);
66 return true;
67 }
68
69 return ProcessDump(args[0], result) == DH_SUCCESS;
70 }
71
ProcessDump(const std::string & args,std::string & result)72 int32_t DscreenHidumper::ProcessDump(const std::string &args, std::string &result)
73 {
74 DHLOGI("Process dump.");
75 HidumpFlag hidumpFlag = HidumpFlag::UNKNOWN;
76 auto operatorIter = ARGS_MAP.find(args);
77 if (operatorIter != ARGS_MAP.end()) {
78 hidumpFlag = operatorIter->second;
79 }
80
81 if (hidumpFlag == HidumpFlag::GET_HELP) {
82 ShowHelp(result);
83 return DH_SUCCESS;
84 }
85 result.clear();
86 switch (hidumpFlag) {
87 case HidumpFlag::DUMP_SCREEN_DATA: {
88 return DumpScreenData(result);
89 }
90 case HidumpFlag::DUMP_SCREEN_DATA_RESTART: {
91 return ReDumpScreenData(result);
92 }
93 case HidumpFlag::DUMP_SCREEN_DATA_STOP: {
94 SetFlagFalse();
95 return DH_SUCCESS;
96 }
97 default: {
98 return ShowIllegalInfomation(result);
99 }
100 }
101 }
102
DumpScreenData(std::string & result)103 int32_t DscreenHidumper::DumpScreenData(std::string &result)
104 {
105 DHLOGI("Dump screen data.");
106
107 if (access(DUMP_FILE_PATH.c_str(), 0) < 0) {
108 if (mkdir(DUMP_FILE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
109 DHLOGI("Create dir err.");
110 DHLOGI("dir path : %{public}s", DUMP_FILE_PATH.c_str());
111 return DSCREEN_BAD_VALUE;
112 }
113 }
114
115 if (fileFullFlag_ == false) {
116 result.append("Dump...");
117 hidumperFlag_ = true;
118 } else {
119 result.append("File oversize 300M : stop dump, use parameter \"--redump\" to clear dumpfile and redump");
120 }
121 return DH_SUCCESS;
122 }
123
ReDumpScreenData(std::string & result)124 int32_t DscreenHidumper::ReDumpScreenData(std::string &result)
125 {
126 DHLOGI("Redump screen data.");
127
128 if (access(DUMP_FILE_PATH.c_str(), 0) < 0) {
129 if (mkdir(DUMP_FILE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
130 DHLOGI("Create dir err.");
131 DHLOGI("dir path : %{public}s", DUMP_FILE_PATH.c_str());
132 return DSCREEN_BAD_VALUE;
133 }
134 }
135 SetFileFlagFalse();
136 SetReDumpFlagTrue();
137 result.append("ReDumpStart...");
138 hidumperFlag_ = true;
139 SetTransReDumpFlagTrue();
140 return DH_SUCCESS;
141 }
142
GetFlagStatus()143 bool DscreenHidumper::GetFlagStatus()
144 {
145 return hidumperFlag_;
146 }
147
SetFlagFalse()148 void DscreenHidumper::SetFlagFalse()
149 {
150 hidumperFlag_ = false;
151 }
152
GetFileFlag()153 bool DscreenHidumper::GetFileFlag()
154 {
155 return fileFullFlag_;
156 }
157
SetFileFlagFalse()158 void DscreenHidumper::SetFileFlagFalse()
159 {
160 fileFullFlag_ = false;
161 }
162
SetFileFlagTrue()163 void DscreenHidumper::SetFileFlagTrue()
164 {
165 fileFullFlag_ = true;
166 }
167
GetReDumpFlag()168 bool DscreenHidumper::GetReDumpFlag()
169 {
170 return reDumpFlag_;
171 }
172
SetReDumpFlagFalse()173 void DscreenHidumper::SetReDumpFlagFalse()
174 {
175 reDumpFlag_ = false;
176 }
177
SetReDumpFlagTrue()178 void DscreenHidumper::SetReDumpFlagTrue()
179 {
180 reDumpFlag_ = true;
181 }
182
GetTransReDumpFlag()183 bool DscreenHidumper::GetTransReDumpFlag()
184 {
185 return transReDumpFlag_;
186 }
187
SetTransReDumpFlagFalse()188 void DscreenHidumper::SetTransReDumpFlagFalse()
189 {
190 transReDumpFlag_ = false;
191 }
192
SetTransReDumpFlagTrue()193 void DscreenHidumper::SetTransReDumpFlagTrue()
194 {
195 transReDumpFlag_ = true;
196 }
197
ShowHelp(std::string & result)198 void DscreenHidumper::ShowHelp(std::string &result)
199 {
200 DHLOGI("Show help.");
201 result.append("Usage:dump <command> [options]\n")
202 .append("Description:\n")
203 .append("-h ")
204 .append(": show help\n")
205 .append("--dump ")
206 .append(": dump screen data in /data/data/dscreen\n")
207 .append("--redump ")
208 .append(": clear file and restart dump screen data\n")
209 .append("--stopdump ")
210 .append(": stop dump screen data\n");
211 }
212
ShowIllegalInfomation(std::string & result)213 int32_t DscreenHidumper::ShowIllegalInfomation(std::string &result)
214 {
215 DHLOGI("Show illegal information.");
216 result.append("unknown command, -h for help.");
217 return DH_SUCCESS;
218 }
219
SaveFile(std::string file,const VideoData & video)220 void DscreenHidumper::SaveFile(std::string file, const VideoData &video)
221 {
222 DHLOGE("Saving File.");
223 std::string fileName = DUMP_FILE_PATH + "/" + file + std::to_string(video.width) + ")_height(" +
224 std::to_string(video.height) + ")_" + video.format + ".jpg";
225 DHLOGE("fileName = %{public}s", fileName.c_str());
226 if (GetReDumpFlag() == true) {
227 std::remove(fileName.c_str());
228 SetReDumpFlagFalse();
229 }
230 std::ofstream ofs(fileName, std::ios::binary | std::ios::out | std::ios::app);
231
232 if (!ofs.is_open()) {
233 DHLOGE("open file failed.");
234 return;
235 }
236 DHLOGE("open Hidumper SaveFile file success.");
237 ofs.seekp(0, std::ios::end);
238 std::ofstream::pos_type fileSize = ofs.tellp();
239 if (fileSize < 0) {
240 DHLOGE("filesize get err");
241 fileSize = 0;
242 }
243 if ((static_cast<size_t>(fileSize) + video.size) < DUMP_FILE_MAX_SIZE) {
244 SetFileFlagFalse();
245 ofs.write(reinterpret_cast<const char *>(video.data), video.size);
246 } else {
247 SetFileFlagTrue();
248 }
249 ofs.close();
250 }
251 } // namespace DistributedHardware
252 } // namespace OHOS