• 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     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