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 <cinttypes>
17 #include <fstream>
18 #include <sys/sysinfo.h>
19 #include "securec.h"
20
21 #include "common_event_collect.h"
22
23 #include "datetime_ex.h"
24 #include "ability_death_recipient.h"
25 #include "system_ability_manager_util.h"
26 #include "common_event_manager.h"
27 #include "common_event_support.h"
28 #include "ipc_skeleton.h"
29 #include "matching_skills.h"
30 #include "parse_util.h"
31 #include "want.h"
32 #include "sam_log.h"
33 #include "sa_profiles.h"
34 #include "system_ability_manager.h"
35 #include "samgr_xcollie.h"
36
37 namespace OHOS {
38 namespace {
39 constexpr uint32_t INIT_EVENT = 10;
40 constexpr uint32_t SUB_COMMON_EVENT = 11;
41 constexpr uint32_t REMOVE_EXTRA_DATA_EVENT = 12;
42 constexpr uint32_t REMOVE_EXTRA_DATA_DELAY_TIME = 300000;
43 constexpr uint32_t UNSUB_DELAY_TIME = 10 * 1000;
44 constexpr int64_t MAX_EXTRA_DATA_ID = 1000000000;
45 constexpr int32_t COMMON_EVENT_SERVICE_ID = 3299;
46 constexpr int32_t TRIGGER_THREAD_RECLAIM_DELAY_TIME = 130;
47 constexpr int32_t TRIGGER_THREAD_RECLAIM_DURATION_TIME = 2;
48 constexpr int32_t CPU_STAT_MIN_FIELDS = 7;
49 constexpr int32_t CPU_STAT_CHECK_INTERVAL = 5;
50 constexpr int32_t CPU_LOAD_SHIFT = 16;
51 constexpr int32_t CPU_LOAD_CHECK_INTERVAL = 300;
52 constexpr float CPU_LOAD_INVALID = 0.0f;
53 constexpr float CPU_LOAD_IDLE_THRESHOLD = 10.0f;
54 constexpr float CPU_LOAD_PERCENT = 100.0f;
55 constexpr const char* CPU_STAT_INFO = "/proc/stat";
56 constexpr const char* UID = "uid";
57 constexpr const char* NET_TYPE = "NetType";
58 constexpr const char* BUNDLE_NAME = "bundleName";
59 constexpr const char* COMMON_EVENT_ACTION_NAME = "common_event_action_name";
60 constexpr const char* COMMON_RECENT_EVENT = "RECENT_EVENT";
61 constexpr const char* COMMON_RECENT_CLEAR_ALL = "RECENT_CLEAR_ALL";
62 }
63
CommonEventCollect(const sptr<IReport> & report)64 CommonEventCollect::CommonEventCollect(const sptr<IReport>& report)
65 : ICollectPlugin(report)
66 {
67 }
68
RemoveWhiteCommonEvent()69 void CommonEventCollect::RemoveWhiteCommonEvent()
70 {
71 std::lock_guard<samgr::mutex> autoLock(commonEventStateLock_);
72 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
73 HILOGI("rm USER_UNLOCKED,size=%{public}zu", commonEventWhitelist.size());
74 }
75
CleanFfrt()76 void CommonEventCollect::CleanFfrt()
77 {
78 if (workHandler_ != nullptr) {
79 workHandler_->CleanFfrt();
80 }
81 if (unsubHandler_ != nullptr) {
82 unsubHandler_->CleanFfrt();
83 }
84 }
85
SetFfrt()86 void CommonEventCollect::SetFfrt()
87 {
88 if (workHandler_ != nullptr) {
89 workHandler_->SetFfrt();
90 }
91 if (unsubHandler_ != nullptr) {
92 unsubHandler_->SetFfrt();
93 }
94 }
95
OnStart()96 int32_t CommonEventCollect::OnStart()
97 {
98 HILOGI("CommonEventCollect OnStart called");
99 if (commonEventNames_.empty()) {
100 HILOGW("CommonEventCollect commonEventNames_ is empty");
101 return ERR_OK;
102 }
103
104 workHandler_ = std::make_shared<CommonHandler>(this);
105 unsubHandler_ = std::make_shared<CommonHandler>(this);
106 workHandler_->SendEvent(INIT_EVENT);
107 StartMonitorThread();
108 return ERR_OK;
109 }
110
OnStop()111 int32_t CommonEventCollect::OnStop()
112 {
113 if (workHandler_ != nullptr) {
114 workHandler_ = nullptr;
115 }
116 if (unsubHandler_ != nullptr) {
117 unsubHandler_ = nullptr;
118 }
119 StopMonitorThread();
120 return ERR_OK;
121 }
122
InitCommonEventState(const OnDemandEvent & event)123 void CommonEventCollect::InitCommonEventState(const OnDemandEvent& event)
124 {
125 if (event.eventId == COMMON_EVENT) {
126 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
127 commonEventNames_.insert(event.name);
128 }
129 for (auto& condition : event.conditions) {
130 if (condition.eventId != COMMON_EVENT) {
131 continue;
132 }
133 {
134 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
135 commonEventNames_.insert(condition.name);
136 }
137 if (condition.extraMessages.size() > 0) {
138 std::lock_guard<samgr::mutex> autoLock(commonEventStateLock_);
139 for (auto [key, value] : condition.extraMessages) {
140 commonEventConditionExtraData_[condition.name][key] = "";
141 }
142 }
143 }
144 }
145
Init(const std::list<SaProfile> & onDemandSaProfiles)146 void CommonEventCollect::Init(const std::list<SaProfile>& onDemandSaProfiles)
147 {
148 {
149 std::lock_guard<samgr::mutex> autoLock(commonEventStateLock_);
150 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
151 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING);
152 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
153 }
154 {
155 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
156 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
157 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
158 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING);
159 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING);
160 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_CONNECTED);
161 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
162 commonEventNames_.insert(EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
163 commonEventNames_.insert(COMMON_RECENT_EVENT);
164 }
165
166 for (auto& profile : onDemandSaProfiles) {
167 for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
168 iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
169 InitCommonEventState(*iterStart);
170 }
171 for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
172 iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
173 InitCommonEventState(*iterStop);
174 }
175 }
176 }
177
AddSkillsEvent(EventFwk::MatchingSkills & skill)178 void CommonEventCollect::AddSkillsEvent(EventFwk::MatchingSkills& skill)
179 {
180 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
181 for (auto& commonEventName : commonEventNames_) {
182 HILOGD("CommonEventCollect add event: %{public}s", commonEventName.c_str());
183 skill.AddEvent(commonEventName);
184 }
185 }
186
CleanFailedEventLocked(const std::vector<std::string> & eventNames)187 void CommonEventCollect::CleanFailedEventLocked(const std::vector<std::string>& eventNames)
188 {
189 if (commonEventSubscriber_ == nullptr) {
190 HILOGE("commonEventSubscriber_ is nullptr!");
191 return;
192 }
193 EventFwk::MatchingSkills skill = commonEventSubscriber_->GetSubscribeInfo().GetMatchingSkills();
194 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
195 for (auto& eventName : eventNames) {
196 skill.RemoveEvent(eventName);
197 commonEventNames_.erase(eventName);
198 }
199 }
200
CreateCommonEventSubscriber()201 bool CommonEventCollect::CreateCommonEventSubscriber()
202 {
203 std::lock_guard<samgr::mutex> autoLock(commonEventSubscriberLock_);
204 return CreateCommonEventSubscriberLocked();
205 }
206
CreateCommonEventSubscriberLocked()207 bool CommonEventCollect::CreateCommonEventSubscriberLocked()
208 {
209 int64_t begin = GetTickCount();
210 EventFwk::MatchingSkills skill = EventFwk::MatchingSkills();
211 AddSkillsEvent(skill);
212 EventFwk::CommonEventSubscribeInfo info(skill);
213 std::shared_ptr<EventFwk::CommonEventSubscriber> comEvtScrb = commonEventSubscriber_;
214 commonEventSubscriber_ = std::make_shared<CommonEventSubscriber>(info, this);
215 bool ret = EventFwk::CommonEventManager::SubscribeCommonEvent(commonEventSubscriber_);
216 HILOGI("SubsComEvt %{public}" PRId64 "ms %{public}s", (GetTickCount() - begin), ret ? "suc" : "fail");
217 if (comEvtScrb != nullptr) {
218 auto unsubTask = [comEvtScrb]() {
219 HILOGI("UnSubsComEvt start");
220 {
221 SamgrXCollie samgrXCollie("samgr--UnSubscribeCommonEvent");
222 bool isUnsubscribe = EventFwk::CommonEventManager::UnSubscribeCommonEvent(comEvtScrb);
223 if (!isUnsubscribe) {
224 HILOGE("CreateCommonEventSubscriberLocked isUnsubscribe failed!");
225 }
226 }
227 };
228 if (unsubHandler_ != nullptr) {
229 unsubHandler_->PostTask(unsubTask, UNSUB_DELAY_TIME);
230 } else {
231 HILOGE("CreateCommonEventSubscriberLocked unsubHandler is null!");
232 }
233 }
234 return ret;
235 }
236
SendEvent(uint32_t eventId)237 bool CommonEventCollect::SendEvent(uint32_t eventId)
238 {
239 if (workHandler_ == nullptr) {
240 HILOGI("CommonEventCollect workHandler is nullptr");
241 return false;
242 }
243 return workHandler_->SendEvent(eventId);
244 }
245
CommonEventListener(const sptr<CommonEventCollect> & commonEventCollect)246 CommonEventListener::CommonEventListener(const sptr<CommonEventCollect>& commonEventCollect)
247 : commonEventCollect_(commonEventCollect) {}
248
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)249 void CommonEventListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
250 {
251 if (commonEventCollect_ == nullptr) {
252 HILOGE("commonEventCollect_ is nullptr!");
253 return;
254 }
255 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
256 HILOGI("CommonEventCollect ces is ready");
257 commonEventCollect_->SendEvent(SUB_COMMON_EVENT);
258 }
259 }
260
OnRemoveSystemAbility(int32_t systemAblityId,const std::string & deviceId)261 void CommonEventListener::OnRemoveSystemAbility(int32_t systemAblityId, const std::string& deviceId)
262 {
263 HILOGI("CommonEventListener OnRemoveSystemAblity systemAblityId:%{public}d", systemAblityId);
264 }
265
SaveAction(const std::string & action)266 void CommonEventCollect::SaveAction(const std::string& action)
267 {
268 std::lock_guard<samgr::mutex> autoLock(commonEventStateLock_);
269 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
270 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
271 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
272 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
273 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
274 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
275 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING) {
276 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING);
277 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING);
278 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING) {
279 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING);
280 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING);
281 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_POWER_CONNECTED) {
282 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_CONNECTED);
283 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
284 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED) {
285 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
286 commonEventWhitelist.erase(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_CONNECTED);
287 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED) {
288 commonEventWhitelist.insert(EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
289 }
290 }
291
CheckCondition(const OnDemandCondition & condition)292 bool CommonEventCollect::CheckCondition(const OnDemandCondition& condition)
293 {
294 std::lock_guard<samgr::mutex> autoLock(commonEventStateLock_);
295 std::map<std::string, std::string> stateMap = commonEventConditionExtraData_[condition.name];
296 for (auto [key, profileValue] : condition.extraMessages) {
297 if (!ParseUtil::CheckLogicRelationship(stateMap[key], profileValue)) {
298 return false;
299 }
300 }
301 if (commonEventConditionValue_[condition.name] != condition.value && condition.value != "") {
302 return false;
303 }
304 if (condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON ||
305 condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF ||
306 condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING ||
307 condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING ||
308 condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_POWER_CONNECTED ||
309 condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED ||
310 condition.name == EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED) {
311 return commonEventWhitelist.count(condition.name) > 0;
312 }
313 return true;
314 }
315
CheckExtraMessage(int64_t extraDataId,const OnDemandEvent & profileEvent)316 bool CommonEventCollect::CheckExtraMessage(int64_t extraDataId, const OnDemandEvent& profileEvent)
317 {
318 OnDemandReasonExtraData extraData;
319 if (!GetOnDemandReasonExtraData(extraDataId, extraData)) {
320 return false;
321 }
322 std::map<std::string, std::string> eventExtraMessages = extraData.GetWant();
323 for (auto [key, profileValue] : profileEvent.extraMessages) {
324 if (!ParseUtil::CheckLogicRelationship(eventExtraMessages[key], profileValue)) {
325 return false;
326 }
327 }
328 return true;
329 }
330
GenerateExtraDataIdLocked()331 int64_t CommonEventCollect::GenerateExtraDataIdLocked()
332 {
333 extraDataId_++;
334 if (extraDataId_ > MAX_EXTRA_DATA_ID) {
335 extraDataId_ = 1;
336 }
337 return extraDataId_;
338 }
339
GetParamFromWant(const std::string & key,const AAFwk::Want & want)340 std::string CommonEventCollect::GetParamFromWant(const std::string& key, const AAFwk::Want& want)
341 {
342 std::string valueString;
343 int32_t valueInt = want.GetIntParam(key, -1);
344 if (valueInt == -1) {
345 valueString = want.GetStringParam(key);
346 } else {
347 valueString = std::to_string(valueInt);
348 }
349 if (want.GetBoolParam(key, false)) {
350 valueString = "true";
351 } else if (!want.GetBoolParam(key, true)) {
352 valueString = "false";
353 }
354 HILOGD("key:%{public}s || value:%{public}s", key.c_str(), valueString.c_str());
355 return valueString;
356 }
357
SaveOnDemandReasonExtraData(const EventFwk::CommonEventData & data)358 int64_t CommonEventCollect::SaveOnDemandReasonExtraData(const EventFwk::CommonEventData& data)
359 {
360 HILOGD("CommonEventCollect extraData code: %{public}d, data: %{public}s", data.GetCode(),
361 data.GetData().c_str());
362 AAFwk::Want want = data.GetWant();
363 auto keySet = want.GetParams().KeySet();
364 std::map<std::string, std::string> wantMap;
365 for (const auto& key : keySet) {
366 wantMap[key] = GetParamFromWant(key, want);
367 HILOGD("CommonEventCollect want key:%{public}s, val:%{public}s", key.c_str(), wantMap[key].c_str());
368 }
369 int32_t uid = want.GetIntParam(UID, -1);
370 int32_t netType = want.GetIntParam(NET_TYPE, -1);
371 wantMap[UID] = std::to_string(uid);
372 wantMap[NET_TYPE] = std::to_string(netType);
373 wantMap[BUNDLE_NAME] = want.GetBundle();
374 int64_t extraDataId = 0;
375 {
376 std::lock_guard<samgr::mutex> autoLock(extraDataLock_);
377 wantMap[COMMON_EVENT_ACTION_NAME] = want.GetAction();
378 OnDemandReasonExtraData extraData(data.GetCode(), data.GetData(), wantMap);
379
380 extraDataId = GenerateExtraDataIdLocked();
381 extraDatas_[extraDataId] = extraData;
382 HILOGD("CommonEventCollect save extraData %{public}d,n:%{public}zu",
383 static_cast<int32_t>(extraDataId), extraDatas_.size());
384 }
385 if (workHandler_ == nullptr) {
386 HILOGI("CommonEventCollect workHandler is nullptr");
387 return -1;
388 }
389 workHandler_->SendEvent(REMOVE_EXTRA_DATA_EVENT, extraDataId, REMOVE_EXTRA_DATA_DELAY_TIME);
390 return extraDataId;
391 }
392
SaveOnDemandConditionExtraData(const EventFwk::CommonEventData & data)393 void CommonEventCollect::SaveOnDemandConditionExtraData(const EventFwk::CommonEventData& data)
394 {
395 std::lock_guard<samgr::mutex> autoLock(commonEventStateLock_);
396 AAFwk::Want want = data.GetWant();
397 commonEventConditionValue_[want.GetAction()] = std::to_string(data.GetCode());
398 for (auto& [key, value] : commonEventConditionExtraData_[want.GetAction()]) {
399 value = GetParamFromWant(key, want);
400 }
401 }
402
RemoveOnDemandReasonExtraData(int64_t extraDataId)403 void CommonEventCollect::RemoveOnDemandReasonExtraData(int64_t extraDataId)
404 {
405 {
406 std::lock_guard<samgr::mutex> autoLock(extraDataLock_);
407 extraDatas_.erase(extraDataId);
408 }
409 HILOGD("CommonEventCollect remove extraData %{public}d", static_cast<int32_t>(extraDataId));
410 RemoveSaExtraDataId(extraDataId);
411 }
412
GetOnDemandReasonExtraData(int64_t extraDataId,OnDemandReasonExtraData & extraData)413 bool CommonEventCollect::GetOnDemandReasonExtraData(int64_t extraDataId, OnDemandReasonExtraData& extraData)
414 {
415 std::lock_guard<samgr::mutex> autoLock(extraDataLock_);
416 HILOGD("CommonEventCollect get extraData %{public}d", static_cast<int32_t>(extraDataId));
417 if (extraDatas_.count(extraDataId) == 0) {
418 return false;
419 }
420 extraData = extraDatas_[extraDataId];
421 return true;
422 }
423
SaveCacheCommonEventSaExtraId(const OnDemandEvent & event,const std::list<SaControlInfo> & saControlList)424 void CommonEventCollect::SaveCacheCommonEventSaExtraId(const OnDemandEvent& event,
425 const std::list<SaControlInfo>& saControlList)
426 {
427 std::list<int32_t> saList = SamgrUtil::GetCacheCommonEventSa(event, saControlList);
428 if (saList.empty()) {
429 return;
430 }
431 for (auto& item : saList) {
432 SaveSaExtraDataId(item, event.extraDataId);
433 }
434 }
435
SaveSaExtraDataId(int32_t saId,int64_t extraDataId)436 void CommonEventCollect::SaveSaExtraDataId(int32_t saId, int64_t extraDataId)
437 {
438 std::lock_guard<samgr::mutex> autoLock(saExtraDataIdLock_);
439 auto& extraIdList = saExtraDataIdMap_[saId];
440 extraIdList.emplace_back(extraDataId);
441 HILOGI("save SA:%{public}d,exId:%{public}d,n:%{public}zu", saId, static_cast<int32_t>(extraDataId),
442 extraIdList.size());
443 }
444
RemoveSaExtraDataId(int64_t extraDataId)445 void CommonEventCollect::RemoveSaExtraDataId(int64_t extraDataId)
446 {
447 std::lock_guard<samgr::mutex> autoLock(saExtraDataIdLock_);
448 HILOGD("rm saExtraId:%{public}d", static_cast<int32_t>(extraDataId));
449 auto iter = saExtraDataIdMap_.begin();
450 while (iter != saExtraDataIdMap_.end()) {
451 auto& tmpList = iter->second;
452 auto listIter = std::find(tmpList.begin(), tmpList.end(), extraDataId);
453 if (listIter != tmpList.end()) {
454 HILOGI("rm SA:%{public}d,exId:%{public}d,n:%{public}zu", iter->first,
455 static_cast<int32_t>(extraDataId), tmpList.size());
456 tmpList.erase(listIter);
457 }
458 if (tmpList.size() == 0) {
459 HILOGI("rm exId SA:%{public}d", iter->first);
460 iter = saExtraDataIdMap_.erase(iter);
461 } else {
462 ++iter;
463 }
464 }
465 }
466
ClearSaExtraDataId(int32_t saId)467 void CommonEventCollect::ClearSaExtraDataId(int32_t saId)
468 {
469 std::lock_guard<samgr::mutex> autoLock(saExtraDataIdLock_);
470 if (saExtraDataIdMap_.count(saId) == 0) {
471 return;
472 }
473 HILOGI("clear SA:%{public}d,map n:%{public}zu", saId, saExtraDataIdMap_.size());
474 saExtraDataIdMap_[saId].clear();
475 saExtraDataIdMap_.erase(saId);
476 }
477
GetSaExtraDataIdList(int32_t saId,std::vector<int64_t> & extraDataidList,const std::string & eventName)478 int32_t CommonEventCollect::GetSaExtraDataIdList(int32_t saId, std::vector<int64_t>& extraDataidList,
479 const std::string& eventName)
480 {
481 std::list<int64_t> temp;
482 {
483 std::lock_guard<samgr::mutex> autoLock(saExtraDataIdLock_);
484 if (saExtraDataIdMap_.count(saId) == 0) {
485 HILOGD("NF exId SA:%{public}d", saId);
486 return ERR_OK;
487 }
488 HILOGD("get exId SA:%{public}d event:%{public}s", saId, eventName.c_str());
489 temp = saExtraDataIdMap_[saId];
490 }
491 if (eventName == "") {
492 std::copy(temp.begin(), temp.end(), std::back_inserter(extraDataidList));
493 return ERR_OK;
494 }
495 for (auto& item : temp) {
496 OnDemandReasonExtraData extraData;
497 if (!GetOnDemandReasonExtraData(item, extraData)) {
498 HILOGD("NF exId:%{public}d", static_cast<int32_t>(item));
499 continue;
500 }
501 std::map<std::string, std::string> want = extraData.GetWant();
502 std::string extraEventName = want[COMMON_EVENT_ACTION_NAME];
503 if (extraEventName != eventName) {
504 HILOGD("exId:%{public}d event:%{public}s not match extra:%{public}s", static_cast<int32_t>(item),
505 eventName.c_str(), extraEventName.c_str());
506 continue;
507 }
508 HILOGD("get exId:%{public}d", static_cast<int32_t>(item));
509 extraDataidList.push_back(item);
510 }
511 return ERR_OK;
512 }
AddCommonEventName(const std::vector<OnDemandEvent> & events)513 std::vector<std::string> CommonEventCollect::AddCommonEventName(const std::vector<OnDemandEvent>& events)
514 {
515 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
516 std::vector<std::string> insertNames;
517 for (auto& event : events) {
518 auto iter = commonEventNames_.find(event.name);
519 if (iter != commonEventNames_.end()) {
520 continue;
521 }
522 HILOGI("CommonEventCollect add collect events: %{public}s", event.name.c_str());
523 commonEventNames_.insert(event.name);
524 insertNames.emplace_back(event.name);
525 }
526 return insertNames;
527 }
528
AddCollectEvent(const std::vector<OnDemandEvent> & events)529 int32_t CommonEventCollect::AddCollectEvent(const std::vector<OnDemandEvent>& events)
530 {
531 std::lock_guard<samgr::mutex> autoLock(commonEventSubscriberLock_);
532 auto insertNames = AddCommonEventName(events);
533 if (insertNames.empty()) {
534 return ERR_OK;
535 }
536 if (!CreateCommonEventSubscriberLocked()) {
537 HILOGE("AddCollectEvent CreateCommonEventSubscriber failed");
538 CleanFailedEventLocked(insertNames);
539 CreateCommonEventSubscriberLocked();
540 return ERR_INVALID_VALUE;
541 }
542 return ERR_OK;
543 }
544
RemoveUnusedEvent(const OnDemandEvent & event)545 int32_t CommonEventCollect::RemoveUnusedEvent(const OnDemandEvent& event)
546 {
547 std::lock_guard<samgr::mutex> autoLock(commomEventLock_);
548 auto iter = commonEventNames_.find(event.name);
549 if (iter != commonEventNames_.end()) {
550 HILOGI("CommonEventCollect remove event name: %{public}s", event.name.c_str());
551 commonEventNames_.erase(iter);
552 }
553 return ERR_OK;
554 }
555
StartReclaimIpcThreadWork(const EventFwk::CommonEventData & data)556 void CommonEventCollect::StartReclaimIpcThreadWork(const EventFwk::CommonEventData& data)
557 {
558 bool isTrigger = false;
559 std::string eventName = data.GetWant().GetAction();
560 std::string eventType = data.GetData();
561
562 if (eventName == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
563 isTrigger = true;
564 isCancel_ = false;
565 } else if (eventName == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
566 isCancel_ = true;
567 } else if (eventName == COMMON_RECENT_EVENT && eventType == COMMON_RECENT_CLEAR_ALL) {
568 isTrigger = true;
569 isCancel_ = false;
570 HILOGI("TriggerSystemIPCThreadReclaim");
571 IPCSkeleton::TriggerSystemIPCThreadReclaim();
572 }
573
574 if (isTrigger && !isTriggerTaskStart_.exchange(true)) {
575 SendKernalReclaimIpcThread();
576 }
577 }
578
SendKernalReclaimIpcThread()579 void CommonEventCollect::SendKernalReclaimIpcThread()
580 {
581 auto task = [this]() {
582 for (int i = 0; i < TRIGGER_THREAD_RECLAIM_DELAY_TIME; i+= TRIGGER_THREAD_RECLAIM_DURATION_TIME) {
583 if (isCancel_) {
584 isTriggerTaskStart_ = false;
585 return;
586 }
587 std::this_thread::sleep_for(std::chrono::seconds(TRIGGER_THREAD_RECLAIM_DURATION_TIME));
588 }
589 HILOGI("TriggerSystemIPCThreadReclaim");
590 IPCSkeleton::TriggerSystemIPCThreadReclaim();
591 isTriggerTaskStart_ = false;
592 };
593 std::thread reclaimThread(task);
594 reclaimThread.detach();
595 }
596
PostTask(std::function<void ()> func,uint64_t delayTime)597 bool CommonHandler::PostTask(std::function<void()> func, uint64_t delayTime)
598 {
599 if (handler_ == nullptr) {
600 HILOGE("CommonEventCollect PostTask handler is null!");
601 return false;
602 }
603 return handler_->PostTask(func, delayTime);
604 }
605
PostTask(std::function<void ()> func,const std::string & name,uint64_t delayTime)606 bool CommonHandler::PostTask(std::function<void()> func, const std::string& name, uint64_t delayTime)
607 {
608 if (handler_ == nullptr) {
609 HILOGE("CommonEventCollect PostTask handler is null!");
610 return false;
611 }
612 return handler_->PostTask(func, name, delayTime);
613 }
614
RemoveTask(const std::string & name)615 void CommonHandler::RemoveTask(const std::string& name)
616 {
617 if (handler_ == nullptr) {
618 HILOGE("CommonEventCollect RemoveTask handler is null!");
619 return;
620 }
621 handler_->RemoveTask(name);
622 }
623
DelTask(const std::string & name)624 void CommonHandler::DelTask(const std::string& name)
625 {
626 if (handler_ == nullptr) {
627 HILOGE("CommonEventCollect DelTask handler is null!");
628 return;
629 }
630 handler_->DelTask(name);
631 }
632
CleanFfrt()633 void CommonHandler::CleanFfrt()
634 {
635 if (handler_ != nullptr) {
636 handler_->CleanFfrt();
637 }
638 }
639
SetFfrt()640 void CommonHandler::SetFfrt()
641 {
642 if (handler_ != nullptr) {
643 handler_->SetFfrt("CommonHandler");
644 }
645 }
646
ProcessEvent(uint32_t eventId,int64_t extraDataId)647 void CommonHandler::ProcessEvent(uint32_t eventId, int64_t extraDataId)
648 {
649 if (commonCollect_ == nullptr) {
650 HILOGE("CommonEventCollect ProcessEvent collect or event is null!");
651 return;
652 }
653 if (eventId != INIT_EVENT && eventId != REMOVE_EXTRA_DATA_EVENT && eventId != SUB_COMMON_EVENT) {
654 HILOGE("CommonEventCollect ProcessEvent error event code!");
655 return;
656 }
657 auto commonCollect = commonCollect_.promote();
658 if (commonCollect == nullptr) {
659 HILOGE("CommonEventCollect collect is nullptr");
660 return;
661 }
662 if (eventId == REMOVE_EXTRA_DATA_EVENT) {
663 commonCollect->RemoveOnDemandReasonExtraData(extraDataId);
664 return;
665 }
666 if (eventId == SUB_COMMON_EVENT) {
667 if (!commonCollect->CreateCommonEventSubscriber()) {
668 HILOGE("OnAddSystemAbility CreateCommonEventSubscriber failed!");
669 }
670 return;
671 }
672 sptr<CommonEventListener> listener = new CommonEventListener(commonCollect);
673 SystemAbilityManager::GetInstance()->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, listener);
674 }
675
SendEvent(uint32_t eventId)676 bool CommonHandler::SendEvent(uint32_t eventId)
677 {
678 if (handler_ == nullptr) {
679 HILOGE("CommonEventCollect SendEvent handler is null!");
680 return false;
681 }
682 auto task = [this, eventId] {this->ProcessEvent(eventId, 0);};
683 return handler_->PostTask(task);
684 }
685
SendEvent(uint32_t eventId,int64_t extraDataId,uint64_t delayTime)686 bool CommonHandler::SendEvent(uint32_t eventId, int64_t extraDataId, uint64_t delayTime)
687 {
688 if (handler_ == nullptr) {
689 HILOGE("CommonEventCollect SendEvent handler is null!");
690 return false;
691 }
692 auto task = [this, eventId, extraDataId] {this->ProcessEvent(eventId, extraDataId);};
693 return handler_->PostTask(task, delayTime);
694 }
695
CommonEventSubscriber(const EventFwk::CommonEventSubscribeInfo & subscribeInfo,const sptr<CommonEventCollect> & collect)696 CommonEventSubscriber::CommonEventSubscriber(const EventFwk::CommonEventSubscribeInfo& subscribeInfo,
697 const sptr<CommonEventCollect>& collect)
698 :EventFwk::CommonEventSubscriber(subscribeInfo), collect_(collect) {}
699
OnReceiveEvent(const EventFwk::CommonEventData & data)700 void CommonEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData& data)
701 {
702 SamgrXCollie samgrXCollie("samgr--OnReceiveEvent");
703 std::string action = data.GetWant().GetAction();
704 int32_t code = data.GetCode();
705 auto collect = collect_.promote();
706 if (collect == nullptr) {
707 HILOGE("CommonEventCollect collect is nullptr");
708 return;
709 }
710 collect->SaveAction(action);
711 int64_t extraDataId = collect->SaveOnDemandReasonExtraData(data);
712 HILOGI("RecvEvent:%{public}s,%{public}d_%{public}d", action.c_str(), code, static_cast<int32_t>(extraDataId));
713 collect->SaveOnDemandConditionExtraData(data);
714 OnDemandEvent event = {COMMON_EVENT, action, std::to_string(code), extraDataId};
715 collect->ReportEvent(event);
716 collect->StartReclaimIpcThreadWork(data);
717 }
718
GetCpuTimes(const char * file,uint64_t & total,uint64_t & idle)719 bool CommonEventCollect::GetCpuTimes(const char* file, uint64_t& total, uint64_t& idle)
720 {
721 if (file == nullptr) {
722 HILOGE("Invalid file name");
723 return false;
724 }
725
726 std::ifstream cpuStatFile(file);
727 if (!cpuStatFile.is_open()) {
728 HILOGE("Failed to open %{public}s", file);
729 return false;
730 }
731
732 std::string line;
733 if (!std::getline(cpuStatFile, line)) {
734 HILOGE("Failed to read %{public}s", file);
735 return false;
736 }
737
738 uint64_t user;
739 uint64_t nice;
740 uint64_t system;
741 uint64_t iowait;
742 uint64_t irq;
743 uint64_t softirq;
744 uint64_t steal;
745 uint64_t guest = 0;
746 uint64_t guestNice = 0;
747
748 int num = sscanf_s(line.c_str(), "cpu %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64
749 " %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64,
750 &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest, &guestNice);
751
752 if (num < CPU_STAT_MIN_FIELDS) {
753 HILOGE("Failed to parse %{public}s (got %{public}d fields)", file, num);
754 return false;
755 }
756
757 total = user + nice + system + idle + iowait + irq + softirq + steal;
758 if (num > CPU_STAT_MIN_FIELDS) {
759 total += guest + guestNice;
760 }
761
762 return true;
763 }
764
GetCpuUsage(const char * file,uint32_t interval)765 float CommonEventCollect::GetCpuUsage(const char* file, uint32_t interval)
766 {
767 if (file == nullptr) {
768 HILOGE("Invalid file name");
769 return CPU_LOAD_INVALID;
770 }
771
772 if (interval <= 0) {
773 HILOGE("Invalid interval");
774 return CPU_LOAD_INVALID;
775 }
776
777 uint64_t totalPre = 0;
778 uint64_t idlePre = 0;
779 uint64_t total = 0;
780 uint64_t idle = 0;
781
782 if (!GetCpuTimes(file, totalPre, idlePre)) {
783 HILOGE("Failed to get pre CPU times");
784 return CPU_LOAD_INVALID;
785 }
786
787 std::this_thread::sleep_for(std::chrono::seconds(interval));
788 if (!GetCpuTimes(file, total, idle)) {
789 HILOGE("Failed to get CPU times");
790 return CPU_LOAD_INVALID;
791 }
792
793 constexpr uint64_t MAX = std::numeric_limits<uint64_t>::max();
794 uint64_t totalDelta = (total >= totalPre) ? (total - totalPre) : (MAX - totalPre + total);
795 uint64_t idleDelta = (idle >= idlePre) ? (idle - idlePre) : (MAX - idlePre + idle);
796 if (totalDelta == 0 || totalDelta < idleDelta) {
797 return CPU_LOAD_INVALID;
798 }
799
800 float usage = static_cast<float>(totalDelta - idleDelta) / totalDelta;
801 return usage * CPU_LOAD_PERCENT;
802 }
803
MonitorCpuUsageThread()804 void CommonEventCollect::MonitorCpuUsageThread()
805 {
806 struct sysinfo info;
807 uint64_t coreNum = static_cast<uint64_t>(sysconf(_SC_NPROCESSORS_ONLN));
808 uint64_t baseLoad = coreNum << CPU_LOAD_SHIFT;
809 pthread_setname_np(pthread_self(), "OS_CPU_MONITOR");
810
811 while (keepRunning_) {
812 std::this_thread::sleep_for(std::chrono::seconds(CPU_LOAD_CHECK_INTERVAL - CPU_STAT_CHECK_INTERVAL));
813 float usage = GetCpuUsage(CPU_STAT_INFO, CPU_STAT_CHECK_INTERVAL);
814 if (sysinfo(&info) == 0) {
815 HILOGI("cpu usage: %{public}f 1min %{public}lu 5min %{public}lu", usage, info.loads[0], info.loads[1]);
816 if (info.loads[0] - baseLoad < (1 << CPU_LOAD_SHIFT) && // 1min avg load <= (logic core num + 1)
817 info.loads[0] < info.loads[1] && // 1min avg load less than 5min avg load
818 usage > CPU_LOAD_INVALID && // cpu usage > 0% and <= 10%
819 usage <= CPU_LOAD_IDLE_THRESHOLD) {
820 HILOGI("cpu idle TriggerSystemIPCThreadReclaim");
821 IPCSkeleton::TriggerSystemIPCThreadReclaim();
822 }
823 }
824 }
825 }
826
StartMonitorThread()827 void CommonEventCollect::StartMonitorThread()
828 {
829 keepRunning_ = true;
830 monitorThread_ = std::thread(&CommonEventCollect::MonitorCpuUsageThread, this);
831 monitorThread_.detach();
832 }
833
StopMonitorThread()834 void CommonEventCollect::StopMonitorThread()
835 {
836 if (keepRunning_) {
837 keepRunning_ = false;
838 if (monitorThread_.joinable()) {
839 monitorThread_.join();
840 }
841 }
842 }
843 } // namespace OHOS