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