1 /*
2 * Copyright (c) 2023-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 "hisysevent_observer.h"
17
18 #include "res_sched_log.h"
19 #include "res_sched_mgr.h"
20 #include "res_type.h"
21 #include "res_value.h"
22
23 namespace OHOS {
24 namespace ResourceSchedule {
25 namespace {
26 static const char* WIFI_CONNECTION = "WIFI_CONNECTION";
27 static const char* WIFI_SCAN = "WIFI_SCAN";
28 static const char* CAMERA_CONNECT = "CAMERA_CONNECT";
29 static constexpr int32_t INDENT = -1;
30 static constexpr int32_t CAMERACONNECT = 0;
31 static constexpr int32_t CAMERADISCONNECT = 1;
32 static constexpr int32_t RUNNINGLOCK_DISABLE = 0;
33 static constexpr int32_t RUNNINGLOCK_ENABLE = 1;
34 static constexpr int32_t RUNNINGLOCK_PROXIED = 2;
35 static constexpr int32_t MAX_LENGTH = 1024;
36 }
37
HiSysEventObserver()38 HiSysEventObserver::HiSysEventObserver() : HiviewDFX::HiSysEventListener()
39 {
40 handleObserverMap_ = {
41 {"RUNNINGLOCK", [this](const nlohmann::json& root, const std::string& eventName) {
42 this->ProcessRunningLockEvent(root, eventName);
43 }},
44 {"CAMERA_CONNECT", [this](const nlohmann::json& root, const std::string& eventName) {
45 this->ProcessCameraEvent(root, eventName);
46 }},
47 {"CAMERA_DISCONNECT", [this](const nlohmann::json& root, const std::string& eventName) {
48 this->ProcessCameraEvent(root, eventName);
49 }},
50 {"WIFI_CONNECTION", [this](const nlohmann::json& root, const std::string& eventName) {
51 this->ProcessWifiEvent(root, eventName);
52 }},
53 {"WIFI_SCAN", [this](const nlohmann::json& root, const std::string& eventName) {
54 this->ProcessWifiEvent(root, eventName);
55 }},
56 };
57 }
58
~HiSysEventObserver()59 HiSysEventObserver::~HiSysEventObserver()
60 {
61 handleObserverMap_.clear();
62 }
63
CheckJsonValue(const nlohmann::json & value,std::initializer_list<std::string> params)64 bool HiSysEventObserver::CheckJsonValue(const nlohmann::json& value, std::initializer_list<std::string> params)
65 {
66 for (const auto& param : params) {
67 if (value.find(param) == value.end()) {
68 return false;
69 }
70 }
71 return true;
72 }
73
OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)74 void HiSysEventObserver::OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)
75 {
76 if (sysEvent == nullptr) {
77 RESSCHED_LOGE("OnEvent hisysevent info is null");
78 return;
79 }
80 std::string eventDetail = sysEvent->AsJson();
81 if (eventDetail.length() > MAX_LENGTH) {
82 RESSCHED_LOGE("eventDetail length is invalid");
83 return;
84 }
85 RESSCHED_LOGD("Process hisysevent event, detail:%{public}s", eventDetail.c_str());
86 nlohmann::json root = nlohmann::json::parse(eventDetail, nullptr, false);
87 if (root.is_discarded()) {
88 RESSCHED_LOGE("Parse hisysevent data failed");
89 return;
90 }
91 if (!CheckJsonValue(root, { "domain_", "name_" })
92 || !root.at("domain_").is_string() || !root.at("name_").is_string()) {
93 RESSCHED_LOGE("hisysevent data domain info lost");
94 return;
95 }
96 std::string domainName = root.at("domain_").get<std::string>();
97 std::string eventName = root.at("name_").get<std::string>();
98 RESSCHED_LOGD("hisysevent info, domain: %{public}s, name:%{public}s", domainName.c_str(), eventName.c_str());
99 ProcessHiSysEvent(eventName, root);
100 }
101
ProcessHiSysEvent(const std::string & eventName,const nlohmann::json & root)102 void HiSysEventObserver::ProcessHiSysEvent(const std::string& eventName, const nlohmann::json& root)
103 {
104 if (root.at("domain_").get<std::string>() == "AV_CODEC") {
105 ProcessAvCodecEvent(root, eventName);
106 return;
107 }
108
109 auto funcIter = handleObserverMap_.find(eventName.c_str());
110 if (funcIter != handleObserverMap_.end()) {
111 auto function = funcIter->second;
112 if (function) {
113 function(root, eventName);
114 }
115 }
116 }
117
ProcessAvCodecEvent(const nlohmann::json & root,const std::string & eventName)118 void HiSysEventObserver::ProcessAvCodecEvent(const nlohmann::json& root, const std::string& eventName)
119 {
120 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
121 RESSCHED_LOGD("Process av_codec event, event root:%{public}s", str.c_str());
122 nlohmann::json payload;
123 if (root.contains("CLIENT_UID") && root.at("CLIENT_UID").is_number_integer()) {
124 payload["uid"] = std::to_string(root.at("CLIENT_UID").get<std::int32_t>());
125 } else {
126 RESSCHED_LOGE("av_codec event uid format error!");
127 return;
128 }
129 if (root.contains("CLIENT_PID") && root.at("CLIENT_PID").is_number_integer()) {
130 payload["pid"] = std::to_string(root.at("CLIENT_PID").get<std::int32_t>());
131 } else {
132 RESSCHED_LOGE("av_codec event pid format error!");
133 return;
134 }
135 if (root.contains("CODEC_INSTANCE_ID") && root.at("CODEC_INSTANCE_ID").is_number_integer()) {
136 payload["instanceId"] = std::to_string(root.at("CODEC_INSTANCE_ID").get<std::int32_t>());
137 } else {
138 RESSCHED_LOGE("av_codec event instanceId format error!");
139 return;
140 }
141
142 if (eventName == "CODEC_START_INFO") {
143 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AV_CODEC_STATE,
144 ResType::AvCodecState::CODEC_START_INFO, payload);
145 } else if (eventName == "CODEC_STOP_INFO") {
146 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AV_CODEC_STATE,
147 ResType::AvCodecState::CODEC_STOP_INFO, payload);
148 }
149 }
150
ProcessRunningLockEvent(const nlohmann::json & root,const std::string & eventName)151 void HiSysEventObserver::ProcessRunningLockEvent(const nlohmann::json& root, const std::string& eventName)
152 {
153 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
154 RESSCHED_LOGD("Process runninglock event, event root:%{public}s", str.c_str());
155 nlohmann::json payload;
156 if (root.contains("UID") && root.at("UID").is_number_integer()) {
157 payload["uid"] = std::to_string(root.at("UID").get<std::int32_t>());
158 } else {
159 RESSCHED_LOGE("running lock event uid format error!");
160 return;
161 }
162 if (root.contains("PID") && root.at("PID").is_number_integer()) {
163 payload["pid"] = std::to_string(root.at("PID").get<std::int32_t>());
164 } else {
165 RESSCHED_LOGE("running lock event pid format error!");
166 return;
167 }
168 if (root.contains("TYPE") && root.at("TYPE").is_number_integer()) {
169 payload["type"] = std::to_string(root.at("TYPE").get<std::uint32_t>());
170 } else {
171 RESSCHED_LOGE("running lock event lock type format error!");
172 return;
173 }
174
175 if (root.contains("STATE") && root.at("STATE").is_number_integer()) {
176 RunningLockState lockState = RunningLockState(root.at("STATE").get<std::int32_t>());
177 RESSCHED_LOGD("Process runninglock event, event type is:%{public}d", lockState);
178 switch (lockState) {
179 case RunningLockState::RUNNINGLOCK_STATE_DISABLE: {
180 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_RUNNINGLOCK_STATE,
181 RUNNINGLOCK_DISABLE, payload);
182 break;
183 }
184 case RunningLockState::RUNNINGLOCK_STATE_ENABLE: {
185 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_RUNNINGLOCK_STATE,
186 RUNNINGLOCK_ENABLE, payload);
187 break;
188 }
189 case RunningLockState::RUNNINGLOCK_STATE_PROXIED:
190 case RunningLockState::RUNNINGLOCK_STATE_UNPROXIED_RESTORE: {
191 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_RUNNINGLOCK_STATE,
192 RUNNINGLOCK_PROXIED, payload);
193 break;
194 }
195 default:
196 break;
197 }
198 } else {
199 RESSCHED_LOGE("running lock event state format error!");
200 return;
201 }
202 }
203
ProcessCameraEvent(const nlohmann::json & root,const std::string & eventName)204 void HiSysEventObserver::ProcessCameraEvent(const nlohmann::json& root, const std::string& eventName)
205 {
206 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
207 RESSCHED_LOGD("Process camera event, event root:%{public}s, eventName:%{public}s", str.c_str(), eventName.c_str());
208 nlohmann::json payload;
209 if (root.contains("UID") && root.at("UID").is_number_integer()) {
210 payload["uid"] = std::to_string(root.at("UID").get<std::int32_t>());
211 } else {
212 RESSCHED_LOGE("camera event uid format error!");
213 return;
214 }
215 if (root.contains("PID") && root.at("PID").is_number_integer()) {
216 payload["pid"] = std::to_string(root.at("PID").get<std::int32_t>());
217 } else {
218 RESSCHED_LOGE("camera event pid format error!");
219 return;
220 }
221
222 if (eventName == CAMERA_CONNECT) {
223 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_REPORT_CAMERA_STATE, CAMERACONNECT, payload);
224 } else {
225 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_REPORT_CAMERA_STATE, CAMERADISCONNECT, payload);
226 }
227 }
228
ProcessWifiEvent(const nlohmann::json & root,const std::string & eventName)229 void HiSysEventObserver::ProcessWifiEvent(const nlohmann::json& root, const std::string& eventName)
230 {
231 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
232 RESSCHED_LOGD("Process wifi event, event root :%{public}s, eventName:%{public}s", str.c_str(), eventName.c_str());
233 nlohmann::json payload;
234 if (root.contains("uid_") && root.at("uid_").is_number_integer()) {
235 payload["uid"] = std::to_string(root.at("uid_").get<std::int32_t>());
236 } else {
237 RESSCHED_LOGE("Wifi event uid format error!");
238 return;
239 }
240 if (root.contains("pid_") && root.at("pid_").is_number_integer()) {
241 payload["pid"] = std::to_string(root.at("pid_").get<std::int32_t>());
242 } else {
243 RESSCHED_LOGE("Wifi event pid format error!");
244 return;
245 }
246
247 WifiState connectionType;
248 if (root.contains("TYPE") && root.at("TYPE").is_number_integer()) {
249 connectionType = WifiState(root.at("TYPE").get<std::int32_t>());
250 } else {
251 RESSCHED_LOGE("Wifi event type format error!");
252 return;
253 }
254 if (eventName == WIFI_CONNECTION) {
255 switch (connectionType) {
256 case WifiState::CONNECTED:
257 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE,
258 ResType::WifiConnectionState::WIFI_STATE_CONNECTED, payload);
259 break;
260 case WifiState::DISCONNECTED:
261 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE,
262 ResType::WifiConnectionState::WIFI_STATE_DISCONNECTED, payload);
263 break;
264 default:
265 break;
266 }
267 } else if (eventName == WIFI_SCAN) {
268 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE,
269 ResType::WifiConnectionState::WIFI_STATE_SCAN, payload);
270 } else {
271 RESSCHED_LOGE("Wifi event name not support!");
272 return;
273 }
274 }
275
OnServiceDied()276 void HiSysEventObserver::OnServiceDied()
277 {
278 RESSCHED_LOGE("HiSysEventObserver service disconnected");
279 }
280 } // namespace ResourceSchedule
281 } // namespace OHOS
282