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