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 "hisysevent_observer.h"
17
18 #ifdef RESSCHED_COMMUNICATION_BLUETOOTH_ENABLE
19 #include "bluetooth_def.h"
20 #endif
21 #include "res_sched_log.h"
22 #include "res_sched_mgr.h"
23 #include "res_type.h"
24
25 namespace OHOS {
26 namespace ResourceSchedule {
27 namespace {
28 static const std::string WIFI_CONNECTION = "WIFI_CONNECTION";
29 static const std::string WIFI_SCAN = "WIFI_SCAN";
30 static const std::string CAMERA_CONNECT = "CAMERA_CONNECT";
31 constexpr int32_t INDENT = -1;
32 constexpr int32_t WIFISCAN = 2;
33 constexpr int32_t WIFICONNECTED = 3;
34 constexpr int32_t WIFIDISCONNECTED = 5;
35 constexpr int32_t CAMERACONNECT = 0;
36 constexpr int32_t CAMERADISCONNECT = 1;
37 constexpr int32_t RUNNINGLOCK_DISABLE = 0;
38 constexpr int32_t RUNNINGLOCK_ENABLE = 1;
39 constexpr int32_t RUNNINGLOCK_PROXIED = 2;
40 constexpr int32_t MAX_LENGTH = 1024;
41 }
42
HiSysEventObserver()43 HiSysEventObserver::HiSysEventObserver() : HiviewDFX::HiSysEventListener()
44 {
45 handleObserverMap_ = {
46 {"RUNNINGLOCK", [this](const nlohmann::json& root, const std::string& eventName) {
47 this->ProcessRunningLockEvent(root, eventName);
48 }},
49 {"STREAM_CHANGE", [this](const nlohmann::json& root, const std::string& eventName) {
50 this->ProcessAudioEvent(root, eventName);
51 }},
52 {"CAMERA_CONNECT", [this](const nlohmann::json& root, const std::string& eventName) {
53 this->ProcessCameraEvent(root, eventName);
54 }},
55 {"CAMERA_DISCONNECT", [this](const nlohmann::json& root, const std::string& eventName) {
56 this->ProcessCameraEvent(root, eventName);
57 }},
58 {"BR_SWITCH_STATE", [this](const nlohmann::json& root, const std::string& eventName) {
59 this->ProcessBluetoothEvent(root, eventName);
60 }},
61 {"BLE_SWITCH_STATE", [this](const nlohmann::json& root, const std::string& eventName) {
62 this->ProcessBluetoothEvent(root, eventName);
63 }},
64 {"WIFI_CONNECTION", [this](const nlohmann::json& root, const std::string& eventName) {
65 this->ProcessWifiEvent(root, eventName);
66 }},
67 {"WIFI_SCAN", [this](const nlohmann::json& root, const std::string& eventName) {
68 this->ProcessWifiEvent(root, eventName);
69 }},
70 };
71 }
72
~HiSysEventObserver()73 HiSysEventObserver::~HiSysEventObserver()
74 {
75 handleObserverMap_.clear();
76 }
77
CheckJsonValue(const nlohmann::json & value,std::initializer_list<std::string> params)78 bool HiSysEventObserver::CheckJsonValue(const nlohmann::json& value, std::initializer_list<std::string> params)
79 {
80 for (const auto& param : params) {
81 if (value.find(param) == value.end()) {
82 return false;
83 }
84 }
85 return true;
86 }
87
OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)88 void HiSysEventObserver::OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)
89 {
90 if (sysEvent == nullptr) {
91 RESSCHED_LOGE("OnEvent hisysevent info is null");
92 return;
93 }
94 std::string eventDetail = sysEvent->AsJson();
95 if (eventDetail.length() > MAX_LENGTH) {
96 RESSCHED_LOGE("eventDetail length is invalid");
97 return;
98 }
99 RESSCHED_LOGD("Process hisysevent event, detail:%{public}s", eventDetail.c_str());
100 nlohmann::json root = nlohmann::json::parse(eventDetail, nullptr, false);
101 if (root.is_discarded()) {
102 RESSCHED_LOGE("Parse hisysevent data failed");
103 return;
104 }
105 if (!CheckJsonValue(root, { "domain_", "name_" })
106 || !root.at("domain_").is_string() || !root.at("name_").is_string()) {
107 RESSCHED_LOGE("hisysevent data domain info lost");
108 return;
109 }
110 std::string domainName = root.at("domain_").get<std::string>();
111 std::string eventName = root.at("name_").get<std::string>();
112 RESSCHED_LOGD("hisysevent info, domain: %{public}s, name:%{public}s", domainName.c_str(), eventName.c_str());
113 ProcessHiSysEvent(eventName, root);
114 }
115
ProcessHiSysEvent(const std::string & eventName,const nlohmann::json & root)116 void HiSysEventObserver::ProcessHiSysEvent(const std::string& eventName, const nlohmann::json& root)
117 {
118 if (root.at("domain_").get<std::string>() == "AV_CODEC") {
119 ProcessAvCodecEvent(root, eventName);
120 return;
121 }
122
123 auto funcIter = handleObserverMap_.find(eventName.c_str());
124 if (funcIter != handleObserverMap_.end()) {
125 auto function = funcIter->second;
126 if (function) {
127 function(root, eventName);
128 }
129 }
130 }
131
ProcessAvCodecEvent(const nlohmann::json & root,const std::string & eventName)132 void HiSysEventObserver::ProcessAvCodecEvent(const nlohmann::json& root, const std::string& eventName)
133 {
134 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
135 RESSCHED_LOGD("Process av_codec event, event root:%{public}s", str.c_str());
136 nlohmann::json payload;
137 if (root.contains("CLIENT_UID") && root.at("CLIENT_UID").is_number_integer()) {
138 payload["uid"] = std::to_string(root.at("CLIENT_UID").get<std::int32_t>());
139 } else {
140 RESSCHED_LOGE("av_codec event uid format error!");
141 return;
142 }
143 if (root.contains("CLIENT_PID") && root.at("CLIENT_PID").is_number_integer()) {
144 payload["pid"] = std::to_string(root.at("CLIENT_PID").get<std::int32_t>());
145 } else {
146 RESSCHED_LOGE("av_codec event pid format error!");
147 return;
148 }
149 if (root.contains("CODEC_INSTANCE_ID") && root.at("CODEC_INSTANCE_ID").is_number_integer()) {
150 payload["instanceId"] = std::to_string(root.at("CODEC_INSTANCE_ID").get<std::int32_t>());
151 } else {
152 RESSCHED_LOGE("av_codec event instanceId format error!");
153 return;
154 }
155
156 if (eventName == "CODEC_START_INFO") {
157 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AV_CODEC_STATE,
158 ResType::AvCodecState::CODEC_START_INFO, payload);
159 } else if (eventName == "CODEC_STOP_INFO") {
160 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AV_CODEC_STATE,
161 ResType::AvCodecState::CODEC_STOP_INFO, payload);
162 }
163 }
164
ProcessRunningLockEvent(const nlohmann::json & root,const std::string & eventName)165 void HiSysEventObserver::ProcessRunningLockEvent(const nlohmann::json& root, const std::string& eventName)
166 {
167 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
168 RESSCHED_LOGD("Process runninglock event, event root:%{public}s", str.c_str());
169 nlohmann::json payload;
170 if (root.contains("UID") && root.at("UID").is_number_integer()) {
171 payload["uid"] = std::to_string(root.at("UID").get<std::int32_t>());
172 } else {
173 RESSCHED_LOGE("running lock event uid format error!");
174 return;
175 }
176 if (root.contains("PID") && root.at("PID").is_number_integer()) {
177 payload["pid"] = std::to_string(root.at("PID").get<std::int32_t>());
178 } else {
179 RESSCHED_LOGE("running lock event pid format error!");
180 return;
181 }
182 if (root.contains("TYPE") && root.at("TYPE").is_number_integer()) {
183 payload["type"] = std::to_string(root.at("TYPE").get<std::uint32_t>());
184 } else {
185 RESSCHED_LOGE("running lock event lock type format error!");
186 return;
187 }
188
189 if (root.contains("STATE") && root.at("STATE").is_number_integer()) {
190 RunningLockState lockState = RunningLockState(root.at("STATE").get<std::int32_t>());
191 RESSCHED_LOGD("Process runninglock event, event type is:%{public}d", lockState);
192 switch (lockState) {
193 case RunningLockState::RUNNINGLOCK_STATE_DISABLE: {
194 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_RUNNINGLOCK_STATE,
195 RUNNINGLOCK_DISABLE, payload);
196 break;
197 }
198 case RunningLockState::RUNNINGLOCK_STATE_ENABLE: {
199 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_RUNNINGLOCK_STATE,
200 RUNNINGLOCK_ENABLE, payload);
201 break;
202 }
203 case RunningLockState::RUNNINGLOCK_STATE_PROXIED:
204 case RunningLockState::RUNNINGLOCK_STATE_UNPROXIED_RESTORE: {
205 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_RUNNINGLOCK_STATE,
206 RUNNINGLOCK_PROXIED, payload);
207 break;
208 }
209 default:
210 break;
211 }
212 } else {
213 RESSCHED_LOGE("running lock event state format error!");
214 return;
215 }
216 }
217
ProcessAudioEvent(const nlohmann::json & root,const std::string & eventName)218 void HiSysEventObserver::ProcessAudioEvent(const nlohmann::json& root, const std::string& eventName)
219 {
220 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
221 RESSCHED_LOGD("Process audio event, event root :%{public}s", str.c_str());
222 nlohmann::json payload;
223 if (root.contains("UID") && root.at("UID").is_number_integer()) {
224 payload["uid"] = root.at("UID").get<std::int32_t>();
225 } else {
226 RESSCHED_LOGE("audio event uid format error!");
227 return;
228 }
229 if (root.contains("PID") && root.at("PID").is_number_integer()) {
230 payload["pid"] = root.at("PID").get<std::int32_t>();
231 } else {
232 RESSCHED_LOGE("audio event pid format error!");
233 return;
234 }
235
236 if (root.contains("STATE") && root.at("STATE").is_number_integer()) {
237 AudioState audioState = AudioState(root.at("STATE").get<std::int32_t>());
238 RESSCHED_LOGD("Process audio event, event type is:%{public}d", audioState);
239 switch (audioState) {
240 case AudioState::AUDIO_STATE_RUNNING:
241 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AUDIO_RENDER_STATE_CHANGE,
242 ResType::AudioStatus::RENDERER_RUNNING, payload);
243 break;
244 case AudioState::AUDIO_STATE_STOPPED:
245 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AUDIO_RENDER_STATE_CHANGE,
246 ResType::AudioStatus::RENDERER_STOPPED, payload);
247 break;
248 case AudioState::AUDIO_STATE_RELEASED:
249 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AUDIO_RENDER_STATE_CHANGE,
250 ResType::AudioStatus::RENDERER_RELEASED, payload);
251 break;
252 case AudioState::AUDIO_STATE_PAUSED:
253 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_AUDIO_RENDER_STATE_CHANGE,
254 ResType::AudioStatus::RENDERER_PAUSED, payload);
255 break;
256 default:
257 break;
258 }
259 } else {
260 RESSCHED_LOGE("audio event state format error!");
261 return;
262 }
263 }
264
ProcessCameraEvent(const nlohmann::json & root,const std::string & eventName)265 void HiSysEventObserver::ProcessCameraEvent(const nlohmann::json& root, const std::string& eventName)
266 {
267 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
268 RESSCHED_LOGD("Process camera event, event root:%{public}s, eventName:%{public}s", str.c_str(), eventName.c_str());
269 nlohmann::json payload;
270 if (root.contains("UID") && root.at("UID").is_number_integer()) {
271 payload["uid"] = std::to_string(root.at("UID").get<std::int32_t>());
272 } else {
273 RESSCHED_LOGE("camera event uid format error!");
274 return;
275 }
276 if (root.contains("PID") && root.at("PID").is_number_integer()) {
277 payload["pid"] = std::to_string(root.at("PID").get<std::int32_t>());
278 } else {
279 RESSCHED_LOGE("camera event pid format error!");
280 return;
281 }
282
283 if (eventName == CAMERA_CONNECT) {
284 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_REPORT_CAMERA_STATE, CAMERACONNECT, payload);
285 } else {
286 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_REPORT_CAMERA_STATE, CAMERADISCONNECT, payload);
287 }
288 }
289
ProcessBluetoothEvent(const nlohmann::json & root,const std::string & eventName)290 void HiSysEventObserver::ProcessBluetoothEvent(const nlohmann::json& root, const std::string& eventName)
291 {
292 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
293 RESSCHED_LOGD("Process bluetooth event, event root :%{public}s", str.c_str());
294 nlohmann::json payload;
295 if (root.contains("UID") && root.at("UID").is_number_integer()) {
296 payload["uid"] = std::to_string(root.at("UID").get<std::int32_t>());
297 } else {
298 RESSCHED_LOGE("bluetooth event uid format error!");
299 return;
300 }
301 if (root.contains("PID") && root.at("PID").is_number_integer()) {
302 payload["pid"] = std::to_string(root.at("PID").get<std::int32_t>());
303 } else {
304 RESSCHED_LOGE("bluetooth event pid format error!");
305 return;
306 }
307
308 #ifdef RESSCHED_COMMUNICATION_BLUETOOTH_ENABLE
309 if (root.contains("STATE") && root.at("STATE").is_number_integer()) {
310 RESSCHED_LOGD("Process bluetooth event, event type is:%{public}d", root.at("STATE").get<std::int32_t>());
311 if (root.at("STATE").get<std::int32_t>() == Bluetooth::BTStateID::STATE_TURN_ON) {
312 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_BLUETOOTH_A2DP_CONNECT_STATE_CHANGE,
313 Bluetooth::BTStateID::STATE_TURN_ON, payload);
314 } else if (root.at("STATE").get<std::int32_t>() == Bluetooth::BTStateID::STATE_TURN_OFF) {
315 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_BLUETOOTH_A2DP_CONNECT_STATE_CHANGE,
316 Bluetooth::BTStateID::STATE_TURN_OFF, payload);
317 }
318 } else {
319 RESSCHED_LOGE("Bluetooth event type not support!");
320 return;
321 }
322 #endif
323 }
324
ProcessWifiEvent(const nlohmann::json & root,const std::string & eventName)325 void HiSysEventObserver::ProcessWifiEvent(const nlohmann::json& root, const std::string& eventName)
326 {
327 std::string str = root.dump(INDENT, ' ', false, nlohmann::json::error_handler_t::replace);
328 RESSCHED_LOGD("Process wifi event, event root :%{public}s, eventName:%{public}s", str.c_str(), eventName.c_str());
329 nlohmann::json payload;
330 if (root.contains("uid_") && root.at("uid_").is_number_integer()) {
331 payload["uid"] = std::to_string(root.at("uid_").get<std::int32_t>());
332 } else {
333 RESSCHED_LOGE("Wifi event uid format error!");
334 return;
335 }
336 if (root.contains("pid_") && root.at("pid_").is_number_integer()) {
337 payload["pid"] = std::to_string(root.at("pid_").get<std::int32_t>());
338 } else {
339 RESSCHED_LOGE("Wifi event pid format error!");
340 return;
341 }
342
343 WifiState connectionType;
344 if (root.contains("TYPE") && root.at("TYPE").is_number_integer()) {
345 connectionType = WifiState(root.at("TYPE").get<std::int32_t>());
346 } else {
347 RESSCHED_LOGE("Wifi event type format error!");
348 return;
349 }
350 if (eventName == WIFI_CONNECTION) {
351 switch (connectionType) {
352 case WifiState::CONNECTED:
353 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE,
354 WIFICONNECTED, payload);
355 break;
356 case WifiState::DISCONNECTED:
357 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE,
358 WIFIDISCONNECTED, payload);
359 break;
360 default:
361 break;
362 }
363 } else if (eventName == WIFI_SCAN) {
364 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE, WIFISCAN, payload);
365 } else {
366 RESSCHED_LOGE("Wifi event name not support!");
367 return;
368 }
369 }
370
OnServiceDied()371 void HiSysEventObserver::OnServiceDied()
372 {
373 RESSCHED_LOGE("HiSysEventObserver service disconnected");
374 }
375 } // namespace ResourceSchedule
376 } // namespace OHOS
377