1 /*
2 * Copyright (c) 2023 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
16 #include "event_publish.h"
17
18 #include "bundle_mgr_client.h"
19 #include "file_util.h"
20 #include "json/json.h"
21 #include "logger.h"
22 #include "string_util.h"
23 #include "time_util.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace {
28 DEFINE_LOG_TAG("HiView-EventPublish");
29 constexpr int VALUE_MOD = 200000;
30 constexpr int DELAY_TIME = 30;
31 const std::string PATH_DIR = "/data/log/hiview/system_event_db/events/temp";
32 const std::string FILE_PREFIX = "/hiappevent_";
33 const std::string FILE_SUFFIX = ".evt";
34 const std::string DOMAIN_PROPERTY = "domain";
35 const std::string NAME_PROPERTY = "name";
36 const std::string EVENT_TYPE_PROPERTY = "eventType";
37 const std::string PARAM_PROPERTY = "params";
38 const std::string DOMAIN_OS = "OS";
39
GetTempFilePath(int32_t uid)40 std::string GetTempFilePath(int32_t uid)
41 {
42 std::string srcPath = PATH_DIR;
43 srcPath.append(FILE_PREFIX).append(std::to_string(uid)).append(FILE_SUFFIX);
44 return srcPath;
45 }
46
GetBundleNameById(int32_t uid)47 std::string GetBundleNameById(int32_t uid)
48 {
49 std::string bundleName;
50 AppExecFwk::BundleMgrClient client;
51 if (client.GetNameForUid(uid, bundleName) != 0) {
52 HIVIEW_LOGW("Failed to query bundleName from bms, uid=%{public}d.", uid);
53 } else {
54 HIVIEW_LOGD("bundleName of uid=%{public}d, bundleName=%{public}s", uid, bundleName.c_str());
55 }
56 return bundleName;
57 }
58
GetSandBoxPathByUid(int32_t uid)59 std::string GetSandBoxPathByUid(int32_t uid)
60 {
61 int userId = uid / VALUE_MOD;
62 std::string bundleName = GetBundleNameById(uid);
63 std::string path;
64 path.append("/data/app/el2/")
65 .append(std::to_string(userId))
66 .append("/base/")
67 .append(bundleName)
68 .append("/cache/hiappevent");
69 return path;
70 }
71 }
72
StartSendingThread()73 void EventPublish::StartSendingThread()
74 {
75 if (sendingThread_ == nullptr) {
76 HIVIEW_LOGI("start send thread.");
77 sendingThread_ = std::make_unique<std::thread>(&EventPublish::SendEventToSandBox, this);
78 sendingThread_->detach();
79 }
80 }
81
SendEventToSandBox()82 void EventPublish::SendEventToSandBox()
83 {
84 std::this_thread::sleep_for(std::chrono::seconds(DELAY_TIME));
85 std::lock_guard<std::mutex> lock(mutex_);
86 std::string timeStr = std::to_string(TimeUtil::GetMilliseconds());
87 std::vector<std::string> files;
88 FileUtil::GetDirFiles(PATH_DIR, files, false);
89 for (const auto& srcPath : files) {
90 std::string uidStr = StringUtil::GetMidSubstr(srcPath, FILE_PREFIX, FILE_SUFFIX);
91 if (uidStr.empty()) {
92 continue;
93 }
94 int32_t uid = StringUtil::StrToInt(uidStr);
95 std::string desPath = GetSandBoxPathByUid(uid);
96 if (!FileUtil::FileExists(desPath)) {
97 HIVIEW_LOGE("SendEventToSandBox not exit desPath=%{public}s.", desPath.c_str());
98 (void)FileUtil::RemoveFile(srcPath);
99 continue;
100 }
101 desPath.append(FILE_PREFIX).append(timeStr).append(".txt");
102 if (FileUtil::CopyFile(srcPath, desPath) == -1) {
103 HIVIEW_LOGE("failed to move file=%{public}s to desFile=%{public}s.",
104 srcPath.c_str(), desPath.c_str());
105 continue;
106 }
107 HIVIEW_LOGI("copy srcPath=%{public}s, desPath=%{public}s.", srcPath.c_str(), desPath.c_str());
108 (void)FileUtil::RemoveFile(srcPath);
109 }
110 sendingThread_.reset();
111 }
112
PushEvent(int32_t uid,const std::string & eventName,HiSysEvent::EventType eventType,const std::string & paramJson)113 void EventPublish::PushEvent(int32_t uid, const std::string& eventName, HiSysEvent::EventType eventType,
114 const std::string& paramJson)
115 {
116 if (eventName.empty() || paramJson.empty() || uid < 0) {
117 HIVIEW_LOGW("empty param.");
118 return;
119 }
120 std::lock_guard<std::mutex> lock(mutex_);
121 if (!FileUtil::FileExists(PATH_DIR) && !FileUtil::ForceCreateDirectory(PATH_DIR)) {
122 HIVIEW_LOGE("failed to create resourceDir.");
123 return;
124 }
125 std::string srcPath = GetTempFilePath(uid);
126 std::string desPath = GetSandBoxPathByUid(uid);
127 if (!FileUtil::FileExists(desPath)) {
128 HIVIEW_LOGD("PushEvent not exit desPath=%{public}s.", desPath.c_str());
129 (void)FileUtil::RemoveFile(srcPath);
130 return;
131 }
132
133 Json::Value eventJson;
134 eventJson[DOMAIN_PROPERTY] = DOMAIN_OS;
135 eventJson[NAME_PROPERTY] = eventName;
136 eventJson[EVENT_TYPE_PROPERTY] = eventType;
137 Json::Value params;
138 Json::Reader reader;
139 if (!reader.parse(paramJson, params)) {
140 HIVIEW_LOGE("failed to parse paramJson.");
141 return;
142 }
143 eventJson[PARAM_PROPERTY] = params;
144 std::string eventStr = Json::FastWriter().write(eventJson);
145 if (!FileUtil::SaveStringToFile(srcPath, eventStr, false)) {
146 HIVIEW_LOGE("failed to persist event to file.");
147 }
148 StartSendingThread();
149 }
150 } // namespace HiviewDFX
151 } // namespace OHOS