* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <sstream>
#include <csignal>
#include <sys/wait.h>
#include <unistd.h>
#include "data_collection.h"
namespace OHOS::perftest {
using namespace std;
const string BUNDLE_NAME_PARAM = "BUNDLE_NAME";
void DataCollection::SetPid(int32_t pid)
{
pid_ = pid;
}
void DataCollection::SetBundleName(string bundleName)
{
bundleName_ = bundleName;
}
int32_t DataCollection::GetPidByBundleName()
{
int32_t pid = -1;
int32_t pipefd[2];
if (pipe(pipefd) == -1) {
return pid;
}
pid_t executePid = fork();
if (executePid == 0) {
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
string pifofCommand = "pidof";
char *executeParam[] = {pifofCommand.data(), bundleName_.data(), NULL};
int32_t res = execv("/bin/pidof", executeParam);
if (res == -1) {
return pid;
}
} else {
close(pipefd[1]);
char buffer[128] = {0};
string executeRes;
ssize_t count;
while ((count = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
executeRes.append(buffer, count);
}
LOG_I("Pid of process %{public}s is %{public}s", bundleName_.c_str(), executeRes.c_str());
stringstream pidStream(executeRes);
pidStream >> pid;
close(pipefd[0]);
waitpid(executePid, nullptr, 0);
}
return pid;
}
bool DataCollection::IsProcessExist(int32_t pid)
{
std::string cmd = "ps -ef | grep -v grep | grep " + to_string(pid);
FILE *fd = popen(cmd.c_str(), "r");
if (fd == nullptr) {
LOG_E("Execute popen to get process failed");
return false;
}
char buf[4096] = {'\0'};
while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
std::string line(buf);
LOG_D("Get process info by pid, line = %{public}s, pid = %{public}d", line.c_str(), pid);
std::istringstream iss(line);
std::string field;
int count = 0;
while (iss >> field) {
LOG_D("Get process info by pid, count = %{public}d , field = '%{public}s'", count, field.c_str());
if (count == 1 && field == to_string(pid)) {
pclose(fd);
return true;
}
count++;
}
}
pclose(fd);
return false;
}
bool DataCollection::ExecuteCommand(const string command, string& result)
{
LOG_I("Execute command: %{public}s", command.c_str());
result = "";
FILE *fp = popen(command.c_str(), "r");
if (fp == nullptr) {
LOG_E("Execute popen to execute command: %{public}s failed", command.c_str());
return false;
}
char bufferInfo[1024] = { '\0' };
while (fgets(bufferInfo, sizeof(bufferInfo), fp) != nullptr) {
result += bufferInfo;
}
pclose(fp);
LOG_I("Execute command res: %{public}s", result.c_str());
return true;
}
void TimeListener::OnEvent(shared_ptr<HiSysEventRecord> record)
{
LOG_I("TimeListener::OnEvent called");
if (record == nullptr) {
return;
}
string bundleName = "";
if (record->GetParamValue(BUNDLE_NAME_PARAM, bundleName) != 0) {
LOG_E("Get the bundlename of HiSysEventRecord failed");
return;
}
if (bundleName != bundleName_) {
LOG_I("Not the specific bundlename");
return;
}
lastEvent_ = record;
}
void TimeListener::OnServiceDied()
{
LOG_E("Service disconnect");
}
shared_ptr<HiviewDFX::HiSysEventRecord> TimeListener::GetEvent()
{
return lastEvent_;
}
}