1 /*
2 * Copyright (c) 2021 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 "raw_param.h"
16 #include <cinttypes>
17 #include <thread>
18 #include <securec.h>
19 #include <string_ex.h>
20 #include <unistd.h>
21 #include "hilog_wrapper.h"
22 #include "dump_manager_service.h"
23
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace {
27 static const bool SHOW_PROGRESS_BAR = false;
28 static const int PROGRESS_LENGTH = 128;
29 static const char PROGRESS_STYLE = '=';
30 static const char PROGRESS_TICK[] = {'-', '\\', '|', '/'};
31 } // namespace
32
RawParam(int calllingUid,int calllingPid,uint32_t reqId,std::vector<std::u16string> & args,int outfd)33 RawParam::RawParam(int calllingUid, int calllingPid, uint32_t reqId, std::vector<std::u16string> &args, int outfd)
34 : uid_(calllingUid), pid_(calllingPid), canceled_(false), finished_(false), reqId_(reqId), outfd_(outfd)
35 {
36 DUMPER_HILOGD(MODULE_SERVICE, "create|pid=%{public}d, reqId=%{public}u", pid_, reqId_);
37 Init(args);
38 }
39
~RawParam()40 RawParam::~RawParam()
41 {
42 DUMPER_HILOGD(MODULE_SERVICE, "release|pid=%{public}d, reqId=%{public}u", pid_, reqId_);
43 Uninit();
44 }
45
Init(std::vector<std::u16string> & args)46 bool RawParam::Init(std::vector<std::u16string> &args)
47 {
48 DUMPER_HILOGD(MODULE_SERVICE, "enter|");
49 if (deathRecipient_ == nullptr) {
50 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new ClientDeathRecipient(reqId_, canceled_));
51 }
52 DUMPER_HILOGD(MODULE_SERVICE, "debug|argc=%{public}zu", args.size());
53 for (size_t i = 0; i < args.size(); i++) {
54 argValues_[i] = std::make_unique<ArgValue>();
55 if (sprintf_s(argValues_[i]->value, SINGLE_ARG_MAXLEN, "%s", Str16ToStr8(args[i]).c_str()) < 0) {
56 return false;
57 }
58 argHead_[i] = argValues_[i]->value;
59 }
60 DUMPER_HILOGD(MODULE_SERVICE, "leave|true");
61 return true;
62 }
63
Uninit()64 void RawParam::Uninit()
65 {
66 DUMPER_HILOGD(MODULE_SERVICE, "enter|");
67 CloseOutputFd();
68 DUMPER_HILOGD(MODULE_SERVICE, "leave|");
69 }
70
GetOutputFd()71 int &RawParam::GetOutputFd()
72 {
73 return outfd_;
74 }
75
CloseOutputFd()76 void RawParam::CloseOutputFd()
77 {
78 DUMPER_HILOGD(MODULE_SERVICE, "enter|outfd=%{public}d", outfd_);
79 if (outfd_ > -1) {
80 DUMPER_HILOGD(MODULE_SERVICE, "debug|outfd=%{public}d", outfd_);
81 close(outfd_);
82 }
83 outfd_ = -1;
84 DUMPER_HILOGD(MODULE_SERVICE, "leave|outfd=%{public}d", outfd_);
85 }
86
GetArgc()87 int RawParam::GetArgc()
88 {
89 int count = 0;
90 for (int i = 0; i < ARG_MAX_COUNT; i++) {
91 if (argHead_[i] == nullptr) {
92 break;
93 }
94 count = i + 1;
95 }
96 return count;
97 }
98
GetArgv()99 char **RawParam::GetArgv()
100 {
101 return argHead_;
102 }
103
GetUid()104 int RawParam::GetUid()
105 {
106 return uid_;
107 }
108
GetPid()109 int RawParam::GetPid()
110 {
111 return pid_;
112 }
113
GetRequestId()114 uint32_t RawParam::GetRequestId()
115 {
116 return reqId_;
117 }
118
IsCanceled()119 bool RawParam::IsCanceled()
120 {
121 return canceled_;
122 }
123
IsFinished()124 bool RawParam::IsFinished()
125 {
126 return (canceled_ || finished_ || hasError_);
127 }
128
HasError()129 bool RawParam::HasError()
130 {
131 return hasError_;
132 }
133
Cancel()134 void RawParam::Cancel()
135 {
136 canceled_ = true;
137 DUMPER_HILOGD(MODULE_SERVICE, "debug|reqId=%{public}u", reqId_);
138 }
139
SetProgressEnabled(bool enable)140 void RawParam::SetProgressEnabled(bool enable)
141 {
142 progressEnabled_ = enable;
143 }
144
IsProgressEnabled() const145 bool RawParam::IsProgressEnabled() const
146 {
147 return progressEnabled_;
148 }
149
SetTitle(const std::string & path)150 void RawParam::SetTitle(const std::string &path)
151 {
152 path_ = path;
153 }
154
SetFolder(const std::string & folder)155 void RawParam::SetFolder(const std::string &folder)
156 {
157 folder_ = folder;
158 }
159
GetFolder()160 std::string RawParam::GetFolder()
161 {
162 return folder_;
163 }
164
UpdateProgress(uint32_t total,uint32_t current)165 void RawParam::UpdateProgress(uint32_t total, uint32_t current)
166 {
167 if ((!progressEnabled_) || (outfd_ < 0) || (total < 1) || (total < current)) {
168 return;
169 }
170 UpdateProgress((uint64_t(FINISH) * current) / total);
171 }
172
UpdateProgress(uint64_t progress)173 void RawParam::UpdateProgress(uint64_t progress)
174 {
175 if ((!progressEnabled_) || (outfd_ < 0) || (progress > FINISH)) {
176 return;
177 }
178 progress_ = std::max(progress, progress_);
179 progressTick_ = (progressTick_ + 1) % sizeof(PROGRESS_TICK);
180 if (SHOW_PROGRESS_BAR) {
181 char barbuf[PROGRESS_LENGTH + 1] = {0};
182 for (size_t i = 0; ((i < progress_) && (i < PROGRESS_LENGTH)); i++) {
183 barbuf[i] = PROGRESS_STYLE;
184 }
185 dprintf(outfd_, "\033[?25l\r[%-100s],%2" PRIu64 "%%,[%c]\033[?25h",
186 barbuf, progress_, PROGRESS_TICK[progressTick_]);
187 } else {
188 dprintf(outfd_, "\033[?25l\r%2" PRIu64 "%%,[%c]\033[?25h", progress_, PROGRESS_TICK[progressTick_]);
189 }
190 if (progress_ == FINISH) {
191 dprintf(outfd_, "%s\n", path_.c_str());
192 }
193 }
194
ClientDeathRecipient(uint32_t reqId,bool & deathed)195 RawParam::ClientDeathRecipient::ClientDeathRecipient(uint32_t reqId, bool &deathed) : reqId_(reqId), deathed_(deathed)
196 {}
197
OnRemoteDied(const wptr<IRemoteObject> & remote)198 void RawParam::ClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
199 {
200 if (remote == nullptr || remote.promote() == nullptr) {
201 return;
202 }
203 auto dumpManagerService = DelayedSpSingleton<DumpManagerService>::GetInstance();
204 if (dumpManagerService == nullptr) {
205 return;
206 }
207 DUMPER_HILOGD(MODULE_SERVICE, "enter|reqId=%{public}d", reqId_);
208 deathed_ = true;
209 DUMPER_HILOGD(MODULE_SERVICE, "leave|reqId=%{public}d", reqId_);
210 }
211
Dump() const212 void RawParam::Dump() const
213 {
214 DUMPER_HILOGD(MODULE_SERVICE, "enter|");
215 DUMPER_HILOGD(MODULE_SERVICE, "debug|uid=%{public}d, pid=%{public}d", uid_, pid_);
216 DUMPER_HILOGD(MODULE_SERVICE, "debug|reqId=%{public}u", reqId_);
217 DUMPER_HILOGD(MODULE_SERVICE, "leave|");
218 }
219 } // namespace HiviewDFX
220 } // namespace OHOS
221