• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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