100600bfbSopenharmony_ci/*
200600bfbSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
300600bfbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
400600bfbSopenharmony_ci * you may not use this file except in compliance with the License.
500600bfbSopenharmony_ci * You may obtain a copy of the License at
600600bfbSopenharmony_ci *
700600bfbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
800600bfbSopenharmony_ci *
900600bfbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1000600bfbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1100600bfbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1200600bfbSopenharmony_ci * See the License for the specific language governing permissions and
1300600bfbSopenharmony_ci * limitations under the License.
1400600bfbSopenharmony_ci */
1500600bfbSopenharmony_ci#include "raw_param.h"
1600600bfbSopenharmony_ci#include <cinttypes>
1700600bfbSopenharmony_ci#include <thread>
1800600bfbSopenharmony_ci#include <securec.h>
1900600bfbSopenharmony_ci#include <string_ex.h>
2000600bfbSopenharmony_ci#include <unistd.h>
2100600bfbSopenharmony_ci#include "hilog_wrapper.h"
2200600bfbSopenharmony_ci#include "dump_manager_service.h"
2300600bfbSopenharmony_ci
2400600bfbSopenharmony_cinamespace OHOS {
2500600bfbSopenharmony_cinamespace HiviewDFX {
2600600bfbSopenharmony_cinamespace {
2700600bfbSopenharmony_cistatic const bool SHOW_PROGRESS_BAR = false;
2800600bfbSopenharmony_cistatic const int PROGRESS_LENGTH = 128;
2900600bfbSopenharmony_cistatic const char PROGRESS_STYLE = '=';
3000600bfbSopenharmony_cistatic const char PROGRESS_TICK[] = {'-', '\\', '|', '/'};
3100600bfbSopenharmony_ci} // namespace
3200600bfbSopenharmony_ci
3300600bfbSopenharmony_ciRawParam::RawParam(int calllingUid, int calllingPid, uint32_t reqId, std::vector<std::u16string> &args, int outfd)
3400600bfbSopenharmony_ci    : uid_(calllingUid), pid_(calllingPid), canceled_(false), finished_(false), reqId_(reqId), outfd_(outfd)
3500600bfbSopenharmony_ci{
3600600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "create|pid=%{public}d, reqId=%{public}u", pid_, reqId_);
3700600bfbSopenharmony_ci    Init(args);
3800600bfbSopenharmony_ci}
3900600bfbSopenharmony_ci
4000600bfbSopenharmony_ciRawParam::~RawParam()
4100600bfbSopenharmony_ci{
4200600bfbSopenharmony_ciDUMPER_HILOGD(MODULE_SERVICE, "release|pid=%{public}d, reqId=%{public}u", pid_, reqId_);
4300600bfbSopenharmony_ci    Uninit();
4400600bfbSopenharmony_ci}
4500600bfbSopenharmony_ci
4600600bfbSopenharmony_cibool RawParam::Init(std::vector<std::u16string> &args)
4700600bfbSopenharmony_ci{
4800600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "enter|");
4900600bfbSopenharmony_ci    if (deathRecipient_ == nullptr) {
5000600bfbSopenharmony_ci        deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new ClientDeathRecipient(reqId_, canceled_));
5100600bfbSopenharmony_ci    }
5200600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "debug|argc=%{public}zu", args.size());
5300600bfbSopenharmony_ci    for (size_t i = 0; i < args.size() && i <= ARG_MAX_COUNT; i++) {
5400600bfbSopenharmony_ci        argValues_[i] = std::make_unique<ArgValue>();
5500600bfbSopenharmony_ci        if (sprintf_s(argValues_[i]->value, SINGLE_ARG_MAXLEN, "%s", Str16ToStr8(args[i]).c_str()) < 0) {
5600600bfbSopenharmony_ci            return false;
5700600bfbSopenharmony_ci        }
5800600bfbSopenharmony_ci        argHead_[i] = argValues_[i]->value;
5900600bfbSopenharmony_ci    }
6000600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "leave|true");
6100600bfbSopenharmony_ci    return true;
6200600bfbSopenharmony_ci}
6300600bfbSopenharmony_ci
6400600bfbSopenharmony_civoid RawParam::Uninit()
6500600bfbSopenharmony_ci{
6600600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "enter|");
6700600bfbSopenharmony_ci    CloseOutputFd();
6800600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "leave|");
6900600bfbSopenharmony_ci}
7000600bfbSopenharmony_ci
7100600bfbSopenharmony_ciint &RawParam::GetOutputFd()
7200600bfbSopenharmony_ci{
7300600bfbSopenharmony_ci    return outfd_;
7400600bfbSopenharmony_ci}
7500600bfbSopenharmony_ci
7600600bfbSopenharmony_civoid RawParam::CloseOutputFd()
7700600bfbSopenharmony_ci{
7800600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "enter|outfd=%{public}d", outfd_);
7900600bfbSopenharmony_ci    if (outfd_ > -1) {
8000600bfbSopenharmony_ci        DUMPER_HILOGD(MODULE_SERVICE, "debug|outfd=%{public}d", outfd_);
8100600bfbSopenharmony_ci        close(outfd_);
8200600bfbSopenharmony_ci    }
8300600bfbSopenharmony_ci    outfd_ = -1;
8400600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "leave|outfd=%{public}d", outfd_);
8500600bfbSopenharmony_ci}
8600600bfbSopenharmony_ci
8700600bfbSopenharmony_ciint RawParam::GetArgc()
8800600bfbSopenharmony_ci{
8900600bfbSopenharmony_ci    int count = 0;
9000600bfbSopenharmony_ci    for (int i = 0; i < ARG_MAX_COUNT; i++) {
9100600bfbSopenharmony_ci        if (argHead_[i] == nullptr) {
9200600bfbSopenharmony_ci            break;
9300600bfbSopenharmony_ci        }
9400600bfbSopenharmony_ci        count = i + 1;
9500600bfbSopenharmony_ci    }
9600600bfbSopenharmony_ci    return count;
9700600bfbSopenharmony_ci}
9800600bfbSopenharmony_ci
9900600bfbSopenharmony_cichar **RawParam::GetArgv()
10000600bfbSopenharmony_ci{
10100600bfbSopenharmony_ci    return argHead_;
10200600bfbSopenharmony_ci}
10300600bfbSopenharmony_ci
10400600bfbSopenharmony_ciint RawParam::GetUid()
10500600bfbSopenharmony_ci{
10600600bfbSopenharmony_ci    return uid_;
10700600bfbSopenharmony_ci}
10800600bfbSopenharmony_ci
10900600bfbSopenharmony_ciint RawParam::GetPid()
11000600bfbSopenharmony_ci{
11100600bfbSopenharmony_ci    return pid_;
11200600bfbSopenharmony_ci}
11300600bfbSopenharmony_ci
11400600bfbSopenharmony_ciuint32_t RawParam::GetRequestId()
11500600bfbSopenharmony_ci{
11600600bfbSopenharmony_ci    return reqId_;
11700600bfbSopenharmony_ci}
11800600bfbSopenharmony_ci
11900600bfbSopenharmony_cibool RawParam::IsCanceled()
12000600bfbSopenharmony_ci{
12100600bfbSopenharmony_ci    return canceled_;
12200600bfbSopenharmony_ci}
12300600bfbSopenharmony_ci
12400600bfbSopenharmony_cibool RawParam::IsFinished()
12500600bfbSopenharmony_ci{
12600600bfbSopenharmony_ci    return (canceled_ || finished_ || hasError_);
12700600bfbSopenharmony_ci}
12800600bfbSopenharmony_ci
12900600bfbSopenharmony_cibool RawParam::HasError()
13000600bfbSopenharmony_ci{
13100600bfbSopenharmony_ci    return hasError_;
13200600bfbSopenharmony_ci}
13300600bfbSopenharmony_ci
13400600bfbSopenharmony_civoid RawParam::Cancel()
13500600bfbSopenharmony_ci{
13600600bfbSopenharmony_ci    canceled_ = true;
13700600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "debug|reqId=%{public}u", reqId_);
13800600bfbSopenharmony_ci}
13900600bfbSopenharmony_ci
14000600bfbSopenharmony_civoid RawParam::SetProgressEnabled(bool enable)
14100600bfbSopenharmony_ci{
14200600bfbSopenharmony_ci    progressEnabled_ = enable;
14300600bfbSopenharmony_ci}
14400600bfbSopenharmony_ci
14500600bfbSopenharmony_cibool RawParam::IsProgressEnabled() const
14600600bfbSopenharmony_ci{
14700600bfbSopenharmony_ci    return progressEnabled_;
14800600bfbSopenharmony_ci}
14900600bfbSopenharmony_ci
15000600bfbSopenharmony_civoid RawParam::SetTitle(const std::string &path)
15100600bfbSopenharmony_ci{
15200600bfbSopenharmony_ci    path_ = path;
15300600bfbSopenharmony_ci}
15400600bfbSopenharmony_ci
15500600bfbSopenharmony_civoid RawParam::SetFolder(const std::string &folder)
15600600bfbSopenharmony_ci{
15700600bfbSopenharmony_ci    folder_ = folder;
15800600bfbSopenharmony_ci}
15900600bfbSopenharmony_ci
16000600bfbSopenharmony_cistd::string RawParam::GetFolder()
16100600bfbSopenharmony_ci{
16200600bfbSopenharmony_ci    return folder_;
16300600bfbSopenharmony_ci}
16400600bfbSopenharmony_ci
16500600bfbSopenharmony_civoid RawParam::UpdateProgress(uint32_t total, uint32_t current)
16600600bfbSopenharmony_ci{
16700600bfbSopenharmony_ci    if ((!progressEnabled_) || (outfd_ < 0) || (total < 1) || (total < current)) {
16800600bfbSopenharmony_ci        return;
16900600bfbSopenharmony_ci    }
17000600bfbSopenharmony_ci    UpdateProgress((uint64_t(FINISH) * current) / total);
17100600bfbSopenharmony_ci}
17200600bfbSopenharmony_ci
17300600bfbSopenharmony_civoid RawParam::UpdateProgress(uint64_t progress)
17400600bfbSopenharmony_ci{
17500600bfbSopenharmony_ci    if ((!progressEnabled_) || (outfd_ < 0) || (progress > FINISH)) {
17600600bfbSopenharmony_ci        return;
17700600bfbSopenharmony_ci    }
17800600bfbSopenharmony_ci    progress_ = std::max(progress, progress_);
17900600bfbSopenharmony_ci    progressTick_ = (progressTick_ + 1) % sizeof(PROGRESS_TICK);
18000600bfbSopenharmony_ci    if (SHOW_PROGRESS_BAR) {
18100600bfbSopenharmony_ci        char barbuf[PROGRESS_LENGTH + 1] = {0};
18200600bfbSopenharmony_ci        for (size_t i = 0; ((i < progress_) && (i < PROGRESS_LENGTH)); i++) {
18300600bfbSopenharmony_ci            barbuf[i] = PROGRESS_STYLE;
18400600bfbSopenharmony_ci        }
18500600bfbSopenharmony_ci        dprintf(outfd_, "\033[?25l\r[%-100s],%2" PRIu64 "%%,[%c]\033[?25h",
18600600bfbSopenharmony_ci            barbuf, progress_, PROGRESS_TICK[progressTick_]);
18700600bfbSopenharmony_ci    } else {
18800600bfbSopenharmony_ci        dprintf(outfd_, "\033[?25l\r%2" PRIu64 "%%,[%c]\033[?25h", progress_, PROGRESS_TICK[progressTick_]);
18900600bfbSopenharmony_ci    }
19000600bfbSopenharmony_ci    if (progress_ == FINISH) {
19100600bfbSopenharmony_ci        dprintf(outfd_, "%s\n", path_.c_str());
19200600bfbSopenharmony_ci    }
19300600bfbSopenharmony_ci}
19400600bfbSopenharmony_ci
19500600bfbSopenharmony_ciRawParam::ClientDeathRecipient::ClientDeathRecipient(uint32_t reqId, bool &deathed) : reqId_(reqId), deathed_(deathed)
19600600bfbSopenharmony_ci{}
19700600bfbSopenharmony_ci
19800600bfbSopenharmony_civoid RawParam::ClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
19900600bfbSopenharmony_ci{
20000600bfbSopenharmony_ci    if (remote == nullptr || remote.promote() == nullptr) {
20100600bfbSopenharmony_ci        return;
20200600bfbSopenharmony_ci    }
20300600bfbSopenharmony_ci    auto dumpManagerService = DumpDelayedSpSingleton<DumpManagerService>::GetInstance();
20400600bfbSopenharmony_ci    if (dumpManagerService == nullptr) {
20500600bfbSopenharmony_ci        return;
20600600bfbSopenharmony_ci    }
20700600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "enter|reqId=%{public}d", reqId_);
20800600bfbSopenharmony_ci    deathed_ = true;
20900600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "leave|reqId=%{public}d", reqId_);
21000600bfbSopenharmony_ci}
21100600bfbSopenharmony_ci
21200600bfbSopenharmony_civoid RawParam::Dump() const
21300600bfbSopenharmony_ci{
21400600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "enter|");
21500600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "debug|uid=%{public}d, pid=%{public}d", uid_, pid_);
21600600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "debug|reqId=%{public}u", reqId_);
21700600bfbSopenharmony_ci    DUMPER_HILOGD(MODULE_SERVICE, "leave|");
21800600bfbSopenharmony_ci}
21900600bfbSopenharmony_ci} // namespace HiviewDFX
22000600bfbSopenharmony_ci} // namespace OHOS
221