1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci
16020a203aSopenharmony_ci#include "hiview_service.h"
17020a203aSopenharmony_ci
18020a203aSopenharmony_ci#include <cinttypes>
19020a203aSopenharmony_ci#include <cstdio>
20020a203aSopenharmony_ci#include <fcntl.h>
21020a203aSopenharmony_ci#include <sys/sendfile.h>
22020a203aSopenharmony_ci#include <sys/stat.h>
23020a203aSopenharmony_ci
24020a203aSopenharmony_ci#include "app_caller_event.h"
25020a203aSopenharmony_ci#include "bundle_mgr_client.h"
26020a203aSopenharmony_ci#include "collect_event.h"
27020a203aSopenharmony_ci#include "file_util.h"
28020a203aSopenharmony_ci#include "hiview_logger.h"
29020a203aSopenharmony_ci#include "hiview_platform.h"
30020a203aSopenharmony_ci#include "hiview_service_adapter.h"
31020a203aSopenharmony_ci#include "sys_event.h"
32020a203aSopenharmony_ci#include "string_util.h"
33020a203aSopenharmony_ci#include "time_util.h"
34020a203aSopenharmony_ci#include "trace_manager.h"
35020a203aSopenharmony_ci
36020a203aSopenharmony_cinamespace OHOS {
37020a203aSopenharmony_cinamespace HiviewDFX {
38020a203aSopenharmony_ciDEFINE_LOG_TAG("HiView-Service");
39020a203aSopenharmony_cinamespace {
40020a203aSopenharmony_ciconstexpr int MIN_SUPPORT_CMD_SIZE = 1;
41020a203aSopenharmony_ciconstexpr int32_t ERR_DEFAULT = -1;
42020a203aSopenharmony_ci}
43020a203aSopenharmony_ci
44020a203aSopenharmony_ciHiviewService::HiviewService()
45020a203aSopenharmony_ci{
46020a203aSopenharmony_ci    traceCollector_ = UCollectUtil::TraceCollector::Create();
47020a203aSopenharmony_ci    cpuCollector_ = UCollectUtil::CpuCollector::Create();
48020a203aSopenharmony_ci    graphicMemoryCollector_ = UCollectUtil::GraphicMemoryCollector::Create();
49020a203aSopenharmony_ci}
50020a203aSopenharmony_ci
51020a203aSopenharmony_civoid HiviewService::StartService()
52020a203aSopenharmony_ci{
53020a203aSopenharmony_ci    std::unique_ptr<HiviewServiceAdapter> adapter = std::make_unique<HiviewServiceAdapter>();
54020a203aSopenharmony_ci    adapter->StartService(this);
55020a203aSopenharmony_ci}
56020a203aSopenharmony_ci
57020a203aSopenharmony_civoid HiviewService::DumpRequestDispatcher(int fd, const std::vector<std::string> &cmds)
58020a203aSopenharmony_ci{
59020a203aSopenharmony_ci    if (fd < 0) {
60020a203aSopenharmony_ci        HIVIEW_LOGW("invalid fd.");
61020a203aSopenharmony_ci        return;
62020a203aSopenharmony_ci    }
63020a203aSopenharmony_ci
64020a203aSopenharmony_ci    if (cmds.size() == 0) {
65020a203aSopenharmony_ci        DumpLoadedPluginInfo(fd);
66020a203aSopenharmony_ci        return;
67020a203aSopenharmony_ci    }
68020a203aSopenharmony_ci
69020a203aSopenharmony_ci    // hidumper hiviewdfx -d
70020a203aSopenharmony_ci    if ((cmds.size() == MIN_SUPPORT_CMD_SIZE) && (cmds[0] == "-d")) {
71020a203aSopenharmony_ci        DumpDetailedInfo(fd);
72020a203aSopenharmony_ci        return;
73020a203aSopenharmony_ci    }
74020a203aSopenharmony_ci
75020a203aSopenharmony_ci    // hidumper hiviewdfx -p
76020a203aSopenharmony_ci    if ((cmds.size() >= MIN_SUPPORT_CMD_SIZE) && (cmds[0] == "-p")) {
77020a203aSopenharmony_ci        DumpPluginInfo(fd, cmds);
78020a203aSopenharmony_ci        return;
79020a203aSopenharmony_ci    }
80020a203aSopenharmony_ci
81020a203aSopenharmony_ci    PrintUsage(fd);
82020a203aSopenharmony_ci    return;
83020a203aSopenharmony_ci}
84020a203aSopenharmony_ci
85020a203aSopenharmony_civoid HiviewService::DumpPluginInfo(int fd, const std::vector<std::string> &cmds) const
86020a203aSopenharmony_ci{
87020a203aSopenharmony_ci    std::string pluginName = "";
88020a203aSopenharmony_ci    const int pluginNameSize = 2;
89020a203aSopenharmony_ci    const int pluginNamePos = 1;
90020a203aSopenharmony_ci    std::vector<std::string> newCmd;
91020a203aSopenharmony_ci    if (cmds.size() >= pluginNameSize) {
92020a203aSopenharmony_ci        pluginName = cmds[pluginNamePos];
93020a203aSopenharmony_ci        newCmd.insert(newCmd.begin(), cmds.begin() + pluginNamePos, cmds.end());
94020a203aSopenharmony_ci    }
95020a203aSopenharmony_ci
96020a203aSopenharmony_ci    auto &platform = HiviewPlatform::GetInstance();
97020a203aSopenharmony_ci    auto const &curPluginMap = platform.GetPluginMap();
98020a203aSopenharmony_ci    for (auto const &entry : curPluginMap) {
99020a203aSopenharmony_ci        auto const &pluginPtr = entry.second;
100020a203aSopenharmony_ci        if (pluginPtr == nullptr) {
101020a203aSopenharmony_ci            continue;
102020a203aSopenharmony_ci        }
103020a203aSopenharmony_ci
104020a203aSopenharmony_ci        if (pluginName.empty()) {
105020a203aSopenharmony_ci            pluginPtr->Dump(fd, newCmd);
106020a203aSopenharmony_ci            continue;
107020a203aSopenharmony_ci        }
108020a203aSopenharmony_ci
109020a203aSopenharmony_ci        if (pluginPtr->GetName() == pluginName) {
110020a203aSopenharmony_ci            pluginPtr->Dump(fd, newCmd);
111020a203aSopenharmony_ci            break;
112020a203aSopenharmony_ci        }
113020a203aSopenharmony_ci    }
114020a203aSopenharmony_ci}
115020a203aSopenharmony_ci
116020a203aSopenharmony_civoid HiviewService::DumpDetailedInfo(int fd)
117020a203aSopenharmony_ci{
118020a203aSopenharmony_ci    if (parser_ != nullptr) {
119020a203aSopenharmony_ci        parser_.reset();
120020a203aSopenharmony_ci    }
121020a203aSopenharmony_ci    DumpLoadedPluginInfo(fd);
122020a203aSopenharmony_ci    parser_ = std::make_unique<AuditLogParser>();
123020a203aSopenharmony_ci    parser_->StartParse();
124020a203aSopenharmony_ci    std::string timeScope = parser_->GetAuditLogTimeScope();
125020a203aSopenharmony_ci    dprintf(fd, "%s\n", timeScope.c_str());
126020a203aSopenharmony_ci    DumpPluginUsageInfo(fd);
127020a203aSopenharmony_ci    DumpThreadUsageInfo(fd);
128020a203aSopenharmony_ci    DumpPipelineUsageInfo(fd);
129020a203aSopenharmony_ci    parser_.reset();
130020a203aSopenharmony_ci}
131020a203aSopenharmony_ci
132020a203aSopenharmony_civoid HiviewService::DumpLoadedPluginInfo(int fd) const
133020a203aSopenharmony_ci{
134020a203aSopenharmony_ci    auto &platform = HiviewPlatform::GetInstance();
135020a203aSopenharmony_ci    auto const &curPluginMap = platform.GetPluginMap();
136020a203aSopenharmony_ci    dprintf(fd, "Current Loaded Plugins:\n");
137020a203aSopenharmony_ci    for (auto const &entry : curPluginMap) {
138020a203aSopenharmony_ci        auto const &pluginName = entry.first;
139020a203aSopenharmony_ci        if (entry.second != nullptr) {
140020a203aSopenharmony_ci            dprintf(fd, "PluginName:%s ", pluginName.c_str());
141020a203aSopenharmony_ci            dprintf(fd, "IsDynamic:%s ",
142020a203aSopenharmony_ci                (entry.second->GetType() == Plugin::PluginType::DYNAMIC) ? "True" : "False");
143020a203aSopenharmony_ci            dprintf(fd, "Version:%s ", (entry.second->GetVersion().c_str()));
144020a203aSopenharmony_ci            dprintf(fd,
145020a203aSopenharmony_ci                "ThreadName:%s\n",
146020a203aSopenharmony_ci                ((entry.second->GetWorkLoop() == nullptr) ? "Null" : entry.second->GetWorkLoop()->GetName().c_str()));
147020a203aSopenharmony_ci        }
148020a203aSopenharmony_ci    }
149020a203aSopenharmony_ci    dprintf(fd, "Dump Plugin Loaded Info Done.\n\n");
150020a203aSopenharmony_ci}
151020a203aSopenharmony_ci
152020a203aSopenharmony_civoid HiviewService::DumpPluginUsageInfo(int fd)
153020a203aSopenharmony_ci{
154020a203aSopenharmony_ci    auto &platform = HiviewPlatform::GetInstance();
155020a203aSopenharmony_ci    auto const &curPluginMap = platform.GetPluginMap();
156020a203aSopenharmony_ci    for (auto const &entry : curPluginMap) {
157020a203aSopenharmony_ci        auto pluginName = entry.first;
158020a203aSopenharmony_ci        if (entry.second != nullptr) {
159020a203aSopenharmony_ci            DumpPluginUsageInfo(fd, pluginName);
160020a203aSopenharmony_ci        }
161020a203aSopenharmony_ci    }
162020a203aSopenharmony_ci}
163020a203aSopenharmony_ci
164020a203aSopenharmony_civoid HiviewService::DumpPluginUsageInfo(int fd, const std::string &pluginName) const
165020a203aSopenharmony_ci{
166020a203aSopenharmony_ci    if (parser_ == nullptr) {
167020a203aSopenharmony_ci        return;
168020a203aSopenharmony_ci    }
169020a203aSopenharmony_ci    auto logList = parser_->GetPluginSummary(pluginName);
170020a203aSopenharmony_ci    dprintf(fd, "Following events processed By Plugin %s:\n", pluginName.c_str());
171020a203aSopenharmony_ci    for (auto &log : logList) {
172020a203aSopenharmony_ci        dprintf(fd, " %s.\n", log.c_str());
173020a203aSopenharmony_ci    }
174020a203aSopenharmony_ci    dprintf(fd, "Dump Plugin Usage Done.\n\n");
175020a203aSopenharmony_ci}
176020a203aSopenharmony_ci
177020a203aSopenharmony_civoid HiviewService::DumpThreadUsageInfo(int fd) const
178020a203aSopenharmony_ci{
179020a203aSopenharmony_ci    auto &platform = HiviewPlatform::GetInstance();
180020a203aSopenharmony_ci    auto const &curThreadMap = platform.GetWorkLoopMap();
181020a203aSopenharmony_ci    dprintf(fd, "Start Dump ThreadInfo:\n");
182020a203aSopenharmony_ci    for (auto const &entry : curThreadMap) {
183020a203aSopenharmony_ci        if (entry.second != nullptr) {
184020a203aSopenharmony_ci            std::string name = entry.second->GetName();
185020a203aSopenharmony_ci            DumpThreadUsageInfo(fd, name);
186020a203aSopenharmony_ci        }
187020a203aSopenharmony_ci    }
188020a203aSopenharmony_ci    dprintf(fd, "Dump ThreadInfo Done.\n\n");
189020a203aSopenharmony_ci}
190020a203aSopenharmony_ci
191020a203aSopenharmony_civoid HiviewService::DumpThreadUsageInfo(int fd, const std::string &threadName) const
192020a203aSopenharmony_ci{
193020a203aSopenharmony_ci    if (parser_ == nullptr) {
194020a203aSopenharmony_ci        return;
195020a203aSopenharmony_ci    }
196020a203aSopenharmony_ci    auto logList = parser_->GetThreadSummary(threadName);
197020a203aSopenharmony_ci    dprintf(fd, "Following events processed on Thread %s:\n", threadName.c_str());
198020a203aSopenharmony_ci    for (auto &log : logList) {
199020a203aSopenharmony_ci        dprintf(fd, " %s.\n", log.c_str());
200020a203aSopenharmony_ci    }
201020a203aSopenharmony_ci}
202020a203aSopenharmony_ci
203020a203aSopenharmony_civoid HiviewService::DumpPipelineUsageInfo(int fd) const
204020a203aSopenharmony_ci{
205020a203aSopenharmony_ci    auto &platform = HiviewPlatform::GetInstance();
206020a203aSopenharmony_ci    auto const &curPipelineMap = platform.GetPipelineMap();
207020a203aSopenharmony_ci    dprintf(fd, "Start Dump Pipeline Info:\n");
208020a203aSopenharmony_ci    for (auto const &entry : curPipelineMap) {
209020a203aSopenharmony_ci        auto pipeline = entry.first;
210020a203aSopenharmony_ci        DumpPipelineUsageInfo(fd, pipeline);
211020a203aSopenharmony_ci    }
212020a203aSopenharmony_ci}
213020a203aSopenharmony_ci
214020a203aSopenharmony_civoid HiviewService::DumpPipelineUsageInfo(int fd, const std::string &pipelineName) const
215020a203aSopenharmony_ci{
216020a203aSopenharmony_ci    if (parser_ == nullptr) {
217020a203aSopenharmony_ci        return;
218020a203aSopenharmony_ci    }
219020a203aSopenharmony_ci    auto logList = parser_->GetPipelineSummary(pipelineName);
220020a203aSopenharmony_ci    dprintf(fd, "Following events processed on Pipeline %s:\n", pipelineName.c_str());
221020a203aSopenharmony_ci    for (auto &log : logList) {
222020a203aSopenharmony_ci        dprintf(fd, " %s.\n", log.c_str());
223020a203aSopenharmony_ci    }
224020a203aSopenharmony_ci    dprintf(fd, "Dump Pipeline Usage Info Done.\n\n");
225020a203aSopenharmony_ci}
226020a203aSopenharmony_ci
227020a203aSopenharmony_civoid HiviewService::PrintUsage(int fd) const
228020a203aSopenharmony_ci{
229020a203aSopenharmony_ci    dprintf(fd, "Hiview Plugin Platform dump options:\n");
230020a203aSopenharmony_ci    dprintf(fd, "hidumper hiviewdfx [-d(etail)]\n");
231020a203aSopenharmony_ci    dprintf(fd, "    [-p(lugin) pluginName]\n");
232020a203aSopenharmony_ci}
233020a203aSopenharmony_ci
234020a203aSopenharmony_ciint32_t HiviewService::CopyFile(const std::string& srcFilePath, const std::string& destFilePath)
235020a203aSopenharmony_ci{
236020a203aSopenharmony_ci    int srcFd = open(srcFilePath.c_str(), O_RDONLY);
237020a203aSopenharmony_ci    if (srcFd == -1) {
238020a203aSopenharmony_ci        HIVIEW_LOGE("failed to open source file, src=%{public}s", StringUtil::HideSnInfo(srcFilePath).c_str());
239020a203aSopenharmony_ci        return ERR_DEFAULT;
240020a203aSopenharmony_ci    }
241020a203aSopenharmony_ci    struct stat st{};
242020a203aSopenharmony_ci    if (fstat(srcFd, &st) == -1) {
243020a203aSopenharmony_ci        HIVIEW_LOGE("failed to stat file.");
244020a203aSopenharmony_ci        close(srcFd);
245020a203aSopenharmony_ci        return ERR_DEFAULT;
246020a203aSopenharmony_ci    }
247020a203aSopenharmony_ci    int destFd = open(destFilePath.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH);
248020a203aSopenharmony_ci    if (destFd == -1) {
249020a203aSopenharmony_ci        HIVIEW_LOGE("failed to open destination file, des=%{public}s", StringUtil::HideSnInfo(destFilePath).c_str());
250020a203aSopenharmony_ci        close(srcFd);
251020a203aSopenharmony_ci        return ERR_DEFAULT;
252020a203aSopenharmony_ci    }
253020a203aSopenharmony_ci    off_t offset = 0;
254020a203aSopenharmony_ci    int cycleNum = 0;
255020a203aSopenharmony_ci    while (offset < st.st_size) {
256020a203aSopenharmony_ci        size_t count = static_cast<size_t>((st.st_size - offset) > SSIZE_MAX ? SSIZE_MAX : st.st_size - offset);
257020a203aSopenharmony_ci        ssize_t ret = sendfile(destFd, srcFd, &offset, count);
258020a203aSopenharmony_ci        if (cycleNum > 0) {
259020a203aSopenharmony_ci            HIVIEW_LOGI("sendfile cycle num:%{public}d, ret:%{public}zd, offset:%{public}lld, size:%{public}lld",
260020a203aSopenharmony_ci                cycleNum, ret, static_cast<long long>(offset), static_cast<long long>(st.st_size));
261020a203aSopenharmony_ci        }
262020a203aSopenharmony_ci        cycleNum++;
263020a203aSopenharmony_ci        if (ret < 0 || offset > st.st_size) {
264020a203aSopenharmony_ci            HIVIEW_LOGE("sendfile fail, ret:%{public}zd, offset:%{public}lld, size:%{public}lld",
265020a203aSopenharmony_ci                ret, static_cast<long long>(offset), static_cast<long long>(st.st_size));
266020a203aSopenharmony_ci            close(srcFd);
267020a203aSopenharmony_ci            close(destFd);
268020a203aSopenharmony_ci            return ERR_DEFAULT;
269020a203aSopenharmony_ci        }
270020a203aSopenharmony_ci    }
271020a203aSopenharmony_ci    close(srcFd);
272020a203aSopenharmony_ci    close(destFd);
273020a203aSopenharmony_ci    return 0;
274020a203aSopenharmony_ci}
275020a203aSopenharmony_ci
276020a203aSopenharmony_ciint32_t HiviewService::Copy(const std::string& srcFilePath, const std::string& destFilePath)
277020a203aSopenharmony_ci{
278020a203aSopenharmony_ci    return CopyFile(srcFilePath, destFilePath);
279020a203aSopenharmony_ci}
280020a203aSopenharmony_ci
281020a203aSopenharmony_ciint32_t HiviewService::Move(const std::string& srcFilePath, const std::string& destFilePath)
282020a203aSopenharmony_ci{
283020a203aSopenharmony_ci    int copyResult = CopyFile(srcFilePath, destFilePath);
284020a203aSopenharmony_ci    if (copyResult != 0) {
285020a203aSopenharmony_ci        HIVIEW_LOGW("copy file failed, result: %{public}d", copyResult);
286020a203aSopenharmony_ci        return copyResult;
287020a203aSopenharmony_ci    }
288020a203aSopenharmony_ci    bool result = FileUtil::RemoveFile(srcFilePath);
289020a203aSopenharmony_ci    HIVIEW_LOGI("move file, delete src result: %{public}d", result);
290020a203aSopenharmony_ci    if (!result) {
291020a203aSopenharmony_ci        bool destResult = FileUtil::RemoveFile(destFilePath);
292020a203aSopenharmony_ci        HIVIEW_LOGI("move file, delete dest result: %{public}d", destResult);
293020a203aSopenharmony_ci        return ERR_DEFAULT;
294020a203aSopenharmony_ci    }
295020a203aSopenharmony_ci    return 0;
296020a203aSopenharmony_ci}
297020a203aSopenharmony_ci
298020a203aSopenharmony_ciint32_t HiviewService::Remove(const std::string& filePath)
299020a203aSopenharmony_ci{
300020a203aSopenharmony_ci    bool result = FileUtil::RemoveFile(filePath);
301020a203aSopenharmony_ci    HIVIEW_LOGI("remove file, result:%{public}d", result);
302020a203aSopenharmony_ci    return 0;
303020a203aSopenharmony_ci}
304020a203aSopenharmony_ci
305020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::OpenSnapshotTrace(const std::vector<std::string>& tagGroups)
306020a203aSopenharmony_ci{
307020a203aSopenharmony_ci    TraceManager manager;
308020a203aSopenharmony_ci    int32_t openRet = manager.OpenSnapshotTrace(tagGroups);
309020a203aSopenharmony_ci    if (openRet != UCollect::UcError::SUCCESS) {
310020a203aSopenharmony_ci        HIVIEW_LOGW("failed to open trace in snapshort mode.");
311020a203aSopenharmony_ci    }
312020a203aSopenharmony_ci    CollectResult<int32_t> ret;
313020a203aSopenharmony_ci    ret.retCode = UCollect::UcError(openRet);
314020a203aSopenharmony_ci    return ret;
315020a203aSopenharmony_ci}
316020a203aSopenharmony_ci
317020a203aSopenharmony_ciCollectResult<std::vector<std::string>> HiviewService::DumpSnapshotTrace(UCollect::TraceCaller caller)
318020a203aSopenharmony_ci{
319020a203aSopenharmony_ci    HIVIEW_LOGI("caller[%{public}d] dump trace in snapshot mode.", static_cast<int32_t>(caller));
320020a203aSopenharmony_ci    CollectResult<std::vector<std::string>> dumpRet = traceCollector_->DumpTrace(caller);
321020a203aSopenharmony_ci    if (dumpRet.retCode != UCollect::UcError::SUCCESS) {
322020a203aSopenharmony_ci        HIVIEW_LOGE("failed to dump the trace in snapshort mode.");
323020a203aSopenharmony_ci    }
324020a203aSopenharmony_ci    return dumpRet;
325020a203aSopenharmony_ci}
326020a203aSopenharmony_ci
327020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::OpenRecordingTrace(const std::string& tags)
328020a203aSopenharmony_ci{
329020a203aSopenharmony_ci    TraceManager manager;
330020a203aSopenharmony_ci    int32_t openRet = manager.OpenRecordingTrace(tags);
331020a203aSopenharmony_ci    if (openRet != UCollect::UcError::SUCCESS) {
332020a203aSopenharmony_ci        HIVIEW_LOGW("failed to open trace in recording mode.");
333020a203aSopenharmony_ci    }
334020a203aSopenharmony_ci    CollectResult<int32_t> ret;
335020a203aSopenharmony_ci    ret.retCode = UCollect::UcError(openRet);
336020a203aSopenharmony_ci    return ret;
337020a203aSopenharmony_ci}
338020a203aSopenharmony_ci
339020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::RecordingTraceOn()
340020a203aSopenharmony_ci{
341020a203aSopenharmony_ci    CollectResult<int32_t> traceOnRet = traceCollector_->TraceOn();
342020a203aSopenharmony_ci    if (traceOnRet.retCode != UCollect::UcError::SUCCESS) {
343020a203aSopenharmony_ci        HIVIEW_LOGE("failed to turn on the trace in recording mode.");
344020a203aSopenharmony_ci    }
345020a203aSopenharmony_ci    return traceOnRet;
346020a203aSopenharmony_ci}
347020a203aSopenharmony_ci
348020a203aSopenharmony_ciCollectResult<std::vector<std::string>> HiviewService::RecordingTraceOff()
349020a203aSopenharmony_ci{
350020a203aSopenharmony_ci    CollectResult<std::vector<std::string>> traceOffRet = traceCollector_->TraceOff();
351020a203aSopenharmony_ci    if (traceOffRet.retCode != UCollect::UcError::SUCCESS) {
352020a203aSopenharmony_ci        HIVIEW_LOGE("failed to turn off the trace in recording mode.");
353020a203aSopenharmony_ci        return traceOffRet;
354020a203aSopenharmony_ci    }
355020a203aSopenharmony_ci    TraceManager manager;
356020a203aSopenharmony_ci    auto recoverRet = manager.RecoverTrace();
357020a203aSopenharmony_ci    if (recoverRet != UCollect::UcError::SUCCESS) {
358020a203aSopenharmony_ci        HIVIEW_LOGE("failed to recover the trace after trace off in recording mode.");
359020a203aSopenharmony_ci        traceOffRet.retCode = UCollect::UcError::UNSUPPORT;
360020a203aSopenharmony_ci    }
361020a203aSopenharmony_ci    return traceOffRet;
362020a203aSopenharmony_ci}
363020a203aSopenharmony_ci
364020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::CloseTrace()
365020a203aSopenharmony_ci{
366020a203aSopenharmony_ci    TraceManager manager;
367020a203aSopenharmony_ci    int32_t closeRet = manager.CloseTrace();
368020a203aSopenharmony_ci    if (closeRet != UCollect::UcError::SUCCESS) {
369020a203aSopenharmony_ci        HIVIEW_LOGW("failed to close the trace. errorCode=%{public}d", closeRet);
370020a203aSopenharmony_ci    }
371020a203aSopenharmony_ci    CollectResult<int32_t> ret;
372020a203aSopenharmony_ci    ret.retCode = UCollect::UcError(closeRet);
373020a203aSopenharmony_ci    return ret;
374020a203aSopenharmony_ci}
375020a203aSopenharmony_ci
376020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::RecoverTrace()
377020a203aSopenharmony_ci{
378020a203aSopenharmony_ci    TraceManager manager;
379020a203aSopenharmony_ci    int32_t recoverRet = manager.RecoverTrace();
380020a203aSopenharmony_ci    if (recoverRet != UCollect::UcError::SUCCESS) {
381020a203aSopenharmony_ci        HIVIEW_LOGW("failed to recover the trace.");
382020a203aSopenharmony_ci    }
383020a203aSopenharmony_ci    CollectResult<int32_t> ret;
384020a203aSopenharmony_ci    ret.retCode = UCollect::UcError(recoverRet);
385020a203aSopenharmony_ci    return ret;
386020a203aSopenharmony_ci}
387020a203aSopenharmony_ci
388020a203aSopenharmony_cistatic std::shared_ptr<AppCallerEvent> InnerCreateAppCallerEvent(UCollectClient::AppCaller &appCaller,
389020a203aSopenharmony_ci    const std::string &eventName)
390020a203aSopenharmony_ci{
391020a203aSopenharmony_ci    std::shared_ptr<AppCallerEvent> appCallerEvent = std::make_shared<AppCallerEvent>("HiViewService");
392020a203aSopenharmony_ci    appCallerEvent->messageType_ = Event::MessageType::PLUGIN_MAINTENANCE;
393020a203aSopenharmony_ci    appCallerEvent->eventName_ = eventName;
394020a203aSopenharmony_ci    appCallerEvent->isBusinessJank_ = appCaller.isBusinessJank;
395020a203aSopenharmony_ci    appCallerEvent->bundleName_ = appCaller.bundleName;
396020a203aSopenharmony_ci    appCallerEvent->bundleVersion_ = appCaller.bundleVersion;
397020a203aSopenharmony_ci    appCallerEvent->uid_ = appCaller.uid;
398020a203aSopenharmony_ci    appCallerEvent->pid_ = appCaller.pid;
399020a203aSopenharmony_ci    appCallerEvent->happenTime_ = static_cast<uint64_t>(appCaller.happenTime);
400020a203aSopenharmony_ci    appCallerEvent->beginTime_ = appCaller.beginTime;
401020a203aSopenharmony_ci    appCallerEvent->endTime_ = appCaller.endTime;
402020a203aSopenharmony_ci    appCallerEvent->taskBeginTime_ = static_cast<int64_t>(TimeUtil::GetMilliseconds());
403020a203aSopenharmony_ci    appCallerEvent->taskEndTime_ = appCallerEvent->taskBeginTime_;
404020a203aSopenharmony_ci    appCallerEvent->resultCode_ = UCollect::UcError::SUCCESS;
405020a203aSopenharmony_ci    appCallerEvent->foreground_ = appCaller.foreground;
406020a203aSopenharmony_ci    appCallerEvent->threadName_ = appCaller.threadName;
407020a203aSopenharmony_ci    return appCallerEvent;
408020a203aSopenharmony_ci}
409020a203aSopenharmony_ci
410020a203aSopenharmony_cistatic CollectResult<int32_t> InnerResponseAppTrace(UCollectClient::AppCaller &appCaller, const std::string &eventName)
411020a203aSopenharmony_ci{
412020a203aSopenharmony_ci    CollectResult<int32_t> result;
413020a203aSopenharmony_ci    result.data = 0;
414020a203aSopenharmony_ci    result.retCode = UCollect::UcError::SUCCESS;
415020a203aSopenharmony_ci
416020a203aSopenharmony_ci    std::shared_ptr<Plugin> plugin = HiviewPlatform::GetInstance().GetPluginByName(UCollectUtil::UCOLLECTOR_PLUGIN);
417020a203aSopenharmony_ci    if (plugin == nullptr) {
418020a203aSopenharmony_ci        HIVIEW_LOGE("UnifiedCollector plugin does not exists, uid=%{public}d, pid=%{public}d",
419020a203aSopenharmony_ci            appCaller.uid, appCaller.pid);
420020a203aSopenharmony_ci        result.retCode = UCollect::UcError::SYSTEM_ERROR;
421020a203aSopenharmony_ci        return result;
422020a203aSopenharmony_ci    }
423020a203aSopenharmony_ci
424020a203aSopenharmony_ci    std::shared_ptr<AppCallerEvent> appCallerEvent = InnerCreateAppCallerEvent(appCaller, eventName);
425020a203aSopenharmony_ci    std::shared_ptr<Event> event = std::dynamic_pointer_cast<Event>(appCallerEvent);
426020a203aSopenharmony_ci    if (!plugin->OnEvent(event)) {
427020a203aSopenharmony_ci        HIVIEW_LOGE("%{public}s failed for uid=%{public}d pid=%{public}d error code=%{public}d",
428020a203aSopenharmony_ci            eventName.c_str(), appCaller.uid, appCaller.pid, appCallerEvent->resultCode_);
429020a203aSopenharmony_ci        result.retCode = UCollect::UcError(appCallerEvent->resultCode_);
430020a203aSopenharmony_ci        return result;
431020a203aSopenharmony_ci    }
432020a203aSopenharmony_ci    return result;
433020a203aSopenharmony_ci}
434020a203aSopenharmony_ci
435020a203aSopenharmony_cistatic CollectResult<int32_t> InnerResponseStartAppTrace(UCollectClient::AppCaller &appCaller)
436020a203aSopenharmony_ci{
437020a203aSopenharmony_ci    return InnerResponseAppTrace(appCaller, UCollectUtil::START_APP_TRACE);
438020a203aSopenharmony_ci}
439020a203aSopenharmony_ci
440020a203aSopenharmony_cistatic CollectResult<int32_t> InnerResponseDumpAppTrace(UCollectClient::AppCaller &appCaller)
441020a203aSopenharmony_ci{
442020a203aSopenharmony_ci    return InnerResponseAppTrace(appCaller, UCollectUtil::DUMP_APP_TRACE);
443020a203aSopenharmony_ci}
444020a203aSopenharmony_ci
445020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::CaptureDurationTrace(UCollectClient::AppCaller &appCaller)
446020a203aSopenharmony_ci{
447020a203aSopenharmony_ci    CollectResult<int32_t> result;
448020a203aSopenharmony_ci    result.data = 0;
449020a203aSopenharmony_ci    if (!AppCallerEvent::enableDynamicTrace_) {
450020a203aSopenharmony_ci        HIVIEW_LOGE("disable dynamic trace, can not capture trace for uid=%{public}d, pid=%{public}d",
451020a203aSopenharmony_ci            appCaller.uid, appCaller.pid);
452020a203aSopenharmony_ci        result.retCode = UCollect::UcError::UNSUPPORT;
453020a203aSopenharmony_ci        return result;
454020a203aSopenharmony_ci    }
455020a203aSopenharmony_ci
456020a203aSopenharmony_ci    if (appCaller.actionId == UCollectClient::ACTION_ID_START_TRACE) {
457020a203aSopenharmony_ci        return InnerResponseStartAppTrace(appCaller);
458020a203aSopenharmony_ci    } else if (appCaller.actionId == UCollectClient::ACTION_ID_DUMP_TRACE) {
459020a203aSopenharmony_ci        return InnerResponseDumpAppTrace(appCaller);
460020a203aSopenharmony_ci    } else {
461020a203aSopenharmony_ci        HIVIEW_LOGE("invalid param %{public}d, can not capture trace for uid=%{public}d, pid=%{public}d",
462020a203aSopenharmony_ci            appCaller.actionId, appCaller.uid, appCaller.pid);
463020a203aSopenharmony_ci        result.retCode = UCollect::UcError::INVALID_ACTION_ID;
464020a203aSopenharmony_ci        return result;
465020a203aSopenharmony_ci    }
466020a203aSopenharmony_ci
467020a203aSopenharmony_ci    result.retCode = UCollect::UcError::SUCCESS;
468020a203aSopenharmony_ci    return result;
469020a203aSopenharmony_ci}
470020a203aSopenharmony_ci
471020a203aSopenharmony_ciCollectResult<double> HiviewService::GetSysCpuUsage()
472020a203aSopenharmony_ci{
473020a203aSopenharmony_ci    CollectResult<double> cpuUsageRet = cpuCollector_->GetSysCpuUsage();
474020a203aSopenharmony_ci    if (cpuUsageRet.retCode != UCollect::UcError::SUCCESS) {
475020a203aSopenharmony_ci        HIVIEW_LOGE("failed to collect system cpu usage");
476020a203aSopenharmony_ci    }
477020a203aSopenharmony_ci    return cpuUsageRet;
478020a203aSopenharmony_ci}
479020a203aSopenharmony_ci
480020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::SetAppResourceLimit(UCollectClient::MemoryCaller& memoryCaller)
481020a203aSopenharmony_ci{
482020a203aSopenharmony_ci    CollectResult<int32_t> result;
483020a203aSopenharmony_ci    result.data = 0;
484020a203aSopenharmony_ci    result.retCode = UCollect::UcError::SUCCESS;
485020a203aSopenharmony_ci
486020a203aSopenharmony_ci    std::shared_ptr<Plugin> plugin = HiviewPlatform::GetInstance().GetPluginByName("XPower");
487020a203aSopenharmony_ci    if (plugin == nullptr) {
488020a203aSopenharmony_ci        HIVIEW_LOGE("XPower plugin does not exists. pid=%{public}d", memoryCaller.pid);
489020a203aSopenharmony_ci        result.retCode = UCollect::UcError::SYSTEM_ERROR;
490020a203aSopenharmony_ci        return result;
491020a203aSopenharmony_ci    }
492020a203aSopenharmony_ci
493020a203aSopenharmony_ci    std::string eventName = "APP_RESOURCE_LIMIT";
494020a203aSopenharmony_ci    SysEventCreator sysEventCreator("HIVIEWDFX", eventName, SysEventCreator::FAULT);
495020a203aSopenharmony_ci    sysEventCreator.SetKeyValue("PID", memoryCaller.pid);
496020a203aSopenharmony_ci    sysEventCreator.SetKeyValue("RESOURCE_TYPE", memoryCaller.resourceType);
497020a203aSopenharmony_ci    sysEventCreator.SetKeyValue("RESOURCE_LIMIT", memoryCaller.limitValue);
498020a203aSopenharmony_ci    sysEventCreator.SetKeyValue("RESOURCE_DEBUG_ENABLE", memoryCaller.enabledDebugLog ? "true" : "false");
499020a203aSopenharmony_ci    std::shared_ptr<SysEvent> sysEvent = std::make_shared<SysEvent>(eventName, nullptr, sysEventCreator);
500020a203aSopenharmony_ci    std::shared_ptr<Event> event = std::dynamic_pointer_cast<Event>(sysEvent);
501020a203aSopenharmony_ci    if (!plugin->OnEvent(event)) {
502020a203aSopenharmony_ci        HIVIEW_LOGE("%{public}s failed for pid=%{public}d error", eventName.c_str(), memoryCaller.pid);
503020a203aSopenharmony_ci        result.retCode = UCollect::UcError::SYSTEM_ERROR;
504020a203aSopenharmony_ci        return result;
505020a203aSopenharmony_ci    }
506020a203aSopenharmony_ci    return result;
507020a203aSopenharmony_ci}
508020a203aSopenharmony_ci
509020a203aSopenharmony_ciCollectResult<int32_t> HiviewService::GetGraphicUsage(int32_t pid)
510020a203aSopenharmony_ci{
511020a203aSopenharmony_ci    return graphicMemoryCollector_->GetGraphicUsage(pid);
512020a203aSopenharmony_ci}
513020a203aSopenharmony_ci}  // namespace HiviewDFX
514020a203aSopenharmony_ci}  // namespace OHOS
515