• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (args.size() >= ARG_MIN_COUNT) {
54         SetCallerPpid(Str16ToStr8(args[args.size() - 1]));
55         args.pop_back();
56     }
57     for (size_t i = 0; i < args.size() && i <= ARG_MAX_COUNT; i++) {
58         argValues_[i] = std::make_unique<ArgValue>();
59         if (sprintf_s(argValues_[i]->value, SINGLE_ARG_MAXLEN, "%s", Str16ToStr8(args[i]).c_str()) < 0) {
60             return false;
61         }
62         argHead_[i] = argValues_[i]->value;
63     }
64     DUMPER_HILOGD(MODULE_SERVICE, "leave|true");
65     return true;
66 }
67 
Uninit()68 void RawParam::Uninit()
69 {
70     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
71     CloseOutputFd();
72     DUMPER_HILOGD(MODULE_SERVICE, "leave|");
73 }
74 
GetOutputFd()75 int &RawParam::GetOutputFd()
76 {
77     return outfd_;
78 }
79 
CloseOutputFd()80 void RawParam::CloseOutputFd()
81 {
82     DUMPER_HILOGD(MODULE_SERVICE, "enter|outfd=%{public}d", outfd_);
83     if (outfd_ > -1) {
84         DUMPER_HILOGD(MODULE_SERVICE, "debug|outfd=%{public}d", outfd_);
85         close(outfd_);
86     }
87     outfd_ = -1;
88     DUMPER_HILOGD(MODULE_SERVICE, "leave|outfd=%{public}d", outfd_);
89 }
90 
GetArgc()91 int RawParam::GetArgc()
92 {
93     int count = 0;
94     for (int i = 0; i < ARG_MAX_COUNT; i++) {
95         if (argHead_[i] == nullptr) {
96             break;
97         }
98         count = i + 1;
99     }
100     return count;
101 }
102 
GetArgv()103 char **RawParam::GetArgv()
104 {
105     return argHead_;
106 }
107 
GetUid()108 int RawParam::GetUid()
109 {
110     return uid_;
111 }
112 
GetPid()113 int RawParam::GetPid()
114 {
115     return pid_;
116 }
117 
GetRequestId()118 uint32_t RawParam::GetRequestId()
119 {
120     return reqId_;
121 }
122 
IsCanceled()123 bool RawParam::IsCanceled()
124 {
125     return canceled_;
126 }
127 
IsFinished()128 bool RawParam::IsFinished()
129 {
130     return (canceled_ || finished_ || hasError_);
131 }
132 
HasError()133 bool RawParam::HasError()
134 {
135     return hasError_;
136 }
137 
Cancel()138 void RawParam::Cancel()
139 {
140     canceled_ = true;
141     DUMPER_HILOGD(MODULE_SERVICE, "debug|reqId=%{public}u", reqId_);
142 }
143 
SetProgressEnabled(bool enable)144 void RawParam::SetProgressEnabled(bool enable)
145 {
146     progressEnabled_ = enable;
147 }
148 
IsProgressEnabled() const149 bool RawParam::IsProgressEnabled() const
150 {
151     return progressEnabled_;
152 }
153 
SetTitle(const std::string & path)154 void RawParam::SetTitle(const std::string &path)
155 {
156     path_ = path;
157 }
158 
SetFolder(const std::string & folder)159 void RawParam::SetFolder(const std::string &folder)
160 {
161     folder_ = folder;
162 }
163 
GetFolder()164 std::string RawParam::GetFolder()
165 {
166     return folder_;
167 }
168 
SetCallerPpid(const std::string & ppid)169 void RawParam::SetCallerPpid(const std::string &ppid)
170 {
171     StrToInt(ppid, callerPpid_);
172 }
173 
GetCallerPpid()174 int RawParam::GetCallerPpid()
175 {
176     return callerPpid_;
177 }
178 
UpdateProgress(uint32_t total,uint32_t current)179 void RawParam::UpdateProgress(uint32_t total, uint32_t current)
180 {
181     if ((!progressEnabled_) || (outfd_ < 0) || (total < 1) || (total < current)) {
182         return;
183     }
184     UpdateProgress((uint64_t(FINISH) * current) / total);
185 }
186 
UpdateProgress(uint64_t progress)187 void RawParam::UpdateProgress(uint64_t progress)
188 {
189     if ((!progressEnabled_) || (outfd_ < 0) || (progress > FINISH)) {
190         return;
191     }
192     progress_ = std::max(progress, progress_);
193     progressTick_ = (progressTick_ + 1) % sizeof(PROGRESS_TICK);
194     if (SHOW_PROGRESS_BAR) {
195         char barbuf[PROGRESS_LENGTH + 1] = {0};
196         for (size_t i = 0; ((i < progress_) && (i < PROGRESS_LENGTH)); i++) {
197             barbuf[i] = PROGRESS_STYLE;
198         }
199         dprintf(outfd_, "\033[?25l\r[%-100s],%2" PRIu64 "%%,[%c]\033[?25h",
200             barbuf, progress_, PROGRESS_TICK[progressTick_]);
201     } else {
202         dprintf(outfd_, "\033[?25l\r%2" PRIu64 "%%,[%c]\033[?25h", progress_, PROGRESS_TICK[progressTick_]);
203     }
204     if (progress_ == FINISH) {
205         dprintf(outfd_, "%s\n", path_.c_str());
206     }
207 }
208 
ClientDeathRecipient(uint32_t reqId,bool & deathed)209 RawParam::ClientDeathRecipient::ClientDeathRecipient(uint32_t reqId, bool &deathed) : reqId_(reqId), deathed_(deathed)
210 {}
211 
OnRemoteDied(const wptr<IRemoteObject> & remote)212 void RawParam::ClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
213 {
214     if (remote == nullptr || remote.promote() == nullptr) {
215         return;
216     }
217     auto dumpManagerService = DumpDelayedSpSingleton<DumpManagerService>::GetInstance();
218     if (dumpManagerService == nullptr) {
219         return;
220     }
221     DUMPER_HILOGD(MODULE_SERVICE, "enter|reqId=%{public}d", reqId_);
222     deathed_ = true;
223     DUMPER_HILOGD(MODULE_SERVICE, "leave|reqId=%{public}d", reqId_);
224 }
225 
Dump() const226 void RawParam::Dump() const
227 {
228     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
229     DUMPER_HILOGD(MODULE_SERVICE, "debug|uid=%{public}d, pid=%{public}d", uid_, pid_);
230     DUMPER_HILOGD(MODULE_SERVICE, "debug|reqId=%{public}u", reqId_);
231     DUMPER_HILOGD(MODULE_SERVICE, "leave|");
232 }
233 } // namespace HiviewDFX
234 } // namespace OHOS
235