• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_export_engine.h"
17 
18 #include <chrono>
19 
20 #include "event_expire_task.h"
21 #include "event_export_task.h"
22 #include "ffrt.h"
23 #include "file_util.h"
24 #include "hiview_global.h"
25 #include "hiview_logger.h"
26 #include "parameter_ex.h"
27 #include "setting_observer_manager.h"
28 #include "sys_event_sequence_mgr.h"
29 
30 namespace OHOS {
31 namespace HiviewDFX {
32 DEFINE_LOG_TAG("HiView-EventExportEngine");
33 namespace {
34 constexpr char SYS_EVENT_EXPORT_DIR_NAME[] = "sys_event_export";
35 constexpr int REGISTER_RETRY_CNT = 100;
36 constexpr int REGISTER_LOOP_DURATION = 6;
GetExportDir(HiviewContext::DirectoryType type)37 std::string GetExportDir(HiviewContext::DirectoryType type)
38 {
39     auto& context = HiviewGlobal::GetInstance();
40     if (context == nullptr) {
41         HIVIEW_LOGW("faield to get export directory");
42         return "";
43     }
44     std::string configDir = context->GetHiViewDirectory(type);
45     return FileUtil::IncludeTrailingPathDelimiter(configDir.append(SYS_EVENT_EXPORT_DIR_NAME));
46 }
47 
GenerateUuid()48 std::string GenerateUuid()
49 {
50     std::string uuid;
51     int8_t retryTimes = 3; // max retry 3 times
52     do {
53         FileUtil::LoadStringFromFile("/proc/sys/kernel/random/uuid", uuid);
54         if (!uuid.empty()) {
55             break;
56         }
57         --retryTimes;
58     } while (retryTimes > 0);
59 
60     if (!uuid.empty() && uuid.back() == '\n') {
61         // remove line breaks at the end
62         uuid.pop_back();
63     }
64     uuid.erase(std::remove(uuid.begin(), uuid.end(), '-'), uuid.end()); // remove character '-'
65     return uuid;
66 }
67 }
68 
GetInstance()69 EventExportEngine& EventExportEngine::GetInstance()
70 {
71     static EventExportEngine instance;
72     return instance;
73 }
74 
EventExportEngine()75 EventExportEngine::EventExportEngine()
76 {
77 }
78 
~EventExportEngine()79 EventExportEngine::~EventExportEngine()
80 {
81     for (auto& config : configs_) {
82         SettingObserverManager::GetInstance()->UnregisterObserver(config->exportSwitchParam.name);
83     }
84 }
85 
Start()86 void EventExportEngine::Start()
87 {
88     std::lock_guard<std::mutex> lock(mgrMutex_);
89     if (isTaskRunning_) {
90         HIVIEW_LOGW("tasks have been started.");
91         return;
92     }
93     isTaskRunning_ = true;
94     auto initTaskHandle = ffrt::submit_h([this] () {
95             Init();
96         }, {}, {}, ffrt::task_attr().name("dft_export_init").qos(ffrt::qos_default));
97     ffrt::submit([this] () {
98             InitAndRunTasks();
99         }, { initTaskHandle }, {}, ffrt::task_attr().name("dft_export_start").qos(ffrt::qos_default));
100 }
101 
Stop()102 void EventExportEngine::Stop()
103 {
104     std::lock_guard<std::mutex> lock(mgrMutex_);
105     if (!isTaskRunning_) {
106         HIVIEW_LOGW("tasks have been stopped");
107         return;
108     }
109     isTaskRunning_ = false;
110     HIVIEW_LOGE("succeed to stop all tasks");
111 }
112 
Init()113 void EventExportEngine::Init()
114 {
115     // init ExportConfigManager
116     std::string configFileStoreDir = GetExportDir(HiviewContext::DirectoryType::CONFIG_DIRECTORY);
117     HIVIEW_LOGI("directory for export config file to store: %{public}s", configFileStoreDir.c_str());
118     ExportConfigManager configMgr(configFileStoreDir);
119 
120     // init ExportDbManager
121     std::string dbStoreDir = GetExportDir(HiviewContext::DirectoryType::WORK_DIRECTORY);
122     HIVIEW_LOGI("directory for export db to store: %{public}s", dbStoreDir.c_str());
123     dbMgr_ = std::make_shared<ExportDbManager>(dbStoreDir);
124 
125     // build tasks for all modules
126     configMgr.GetExportConfigs(configs_);
127     HIVIEW_LOGD("count of configuration: %{public}zu", configs_.size());
128 }
129 
InitAndRunTasks()130 void EventExportEngine::InitAndRunTasks()
131 {
132     HIVIEW_LOGI("total count of module is %{public}zu", configs_.size());
133     for (const auto& config : configs_) {
134         auto task = std::bind(&EventExportEngine::InitAndRunTask, this, config);
135         ffrt::submit(task, {}, {}, ffrt::task_attr().name("dft_event_export").qos(ffrt::qos_default));
136     }
137 }
138 
RegistSettingObserver(std::shared_ptr<ExportConfig> config)139 bool EventExportEngine::RegistSettingObserver(std::shared_ptr<ExportConfig> config)
140 {
141     SettingObserver::ObserverCallback callback =
142         [this, &config] (const std::string& paramKey) {
143             std::string val = SettingObserverManager::GetInstance()->GetStringValue(paramKey);
144             HIVIEW_LOGI("value of param key[%{public}s] is %{public}s", paramKey.c_str(), val.c_str());
145             if (val == config->exportSwitchParam.enabledVal) {
146                 HandleExportSwitchOn(config->moduleName);
147             } else {
148                 HandleExportSwitchOff(config->moduleName);
149             }
150         };
151     bool regRet = false;
152     int retryCount = REGISTER_RETRY_CNT;
153     while (!regRet && retryCount > 0) {
154         regRet = SettingObserverManager::GetInstance()->RegisterObserver(config->exportSwitchParam.name,
155             callback);
156         if (regRet) {
157             break;
158         }
159         retryCount--;
160         ffrt::this_task::sleep_for(std::chrono::seconds(REGISTER_LOOP_DURATION));
161     }
162     if (!regRet) {
163         HIVIEW_LOGW("failed to regist setting db observer for module %{public}s", config->moduleName.c_str());
164         return regRet;
165     }
166     if (dbMgr_->IsUnrecordedModule(config->moduleName)) { // first time to export event for current module
167         auto upgradeParam = config->sysUpgradeParam;
168         if (!upgradeParam.name.empty() &&
169             SettingObserverManager::GetInstance()->GetStringValue(upgradeParam.name) == upgradeParam.enabledVal) {
170             int64_t startSeq = EventStore::SysEventSequenceManager::GetInstance().GetStartSequence();
171             HIVIEW_LOGI("reset enabled sequence to %{public}" PRId64 " for moudle %{public}s",
172                 startSeq, config->moduleName.c_str());
173             dbMgr_->HandleExportSwitchChanged(config->moduleName, startSeq);
174             FileUtil::CreateFile(dbMgr_->GetEventInheritFlagPath()); // create inherit flag file
175         }
176     }
177     HIVIEW_LOGI("succeed to regist setting db observer for module %{public}s", config->moduleName.c_str());
178     return regRet;
179 }
180 
InitAndRunTask(std::shared_ptr<ExportConfig> config)181 void EventExportEngine::InitAndRunTask(std::shared_ptr<ExportConfig> config)
182 {
183     // reg setting db observer
184     auto regRet = RegistSettingObserver(config);
185     if (!regRet) {
186         return;
187     }
188     // init tasks of current config then run them
189     auto expireTask = std::make_shared<EventExpireTask>(config, dbMgr_);
190     auto exportTask = std::make_shared<EventExportTask>(config, dbMgr_);
191     while (isTaskRunning_) {
192         expireTask->Run();
193         exportTask->Run();
194         // sleep for a task cycle
195         ffrt::this_task::sleep_for(exportTask->GetExecutingCycle());
196     }
197 }
198 
HandleExportSwitchOn(const std::string & moduleName)199 void EventExportEngine::HandleExportSwitchOn(const std::string& moduleName)
200 {
201     if (FileUtil::FileExists(dbMgr_->GetEventInheritFlagPath())) {
202         // if inherit flag file exists, no need to update export enabled seq
203         return;
204     }
205     auto curEventSeq = EventStore::SysEventSequenceManager::GetInstance().GetSequence();
206     HIVIEW_LOGI("update enabled seq:%{public}" PRId64 " for moudle %{public}s", curEventSeq, moduleName.c_str());
207     dbMgr_->HandleExportSwitchChanged(moduleName, curEventSeq);
208 }
209 
HandleExportSwitchOff(const std::string & moduleName)210 void EventExportEngine::HandleExportSwitchOff(const std::string& moduleName)
211 {
212     dbMgr_->HandleExportSwitchChanged(moduleName, INVALID_SEQ_VAL);
213     FileUtil::RemoveFile(dbMgr_->GetEventInheritFlagPath()); // remove inherit flag file if switch changes
214 }
215 
InitPackId()216 void EventExportEngine::InitPackId()
217 {
218     if (Parameter::GetUserType() != Parameter::USER_TYPE_OVERSEA_COMMERCIAL) {
219         return;
220     }
221     const std::string packIdProp = "persist.hiviewdfx.priv.packid";
222     if (!Parameter::GetString(packIdProp, "").empty()) {
223         return;
224     }
225     if (std::string packId = GenerateUuid(); packId.empty()) {
226         HIVIEW_LOGW("init packid failed.");
227     } else {
228         HIVIEW_LOGI("init packid success.");
229         Parameter::SetProperty(packIdProp, packId);
230     }
231 }
232 } // HiviewDFX
233 } // OHOS
234