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