• 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 <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