1 /*
2  * Copyright (c) 2022-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 "device_status_collect_manager.h"
17 
18 #include "datetime_ex.h"
19 #include "device_timed_collect.h"
20 #ifdef SUPPORT_DEVICE_MANAGER
21 #include "device_networking_collect.h"
22 #endif
23 #ifdef SUPPORT_COMMON_EVENT
24 #include "common_event_collect.h"
25 #endif
26 #ifdef SUPPORT_SWITCH_COLLECT
27 #include "device_switch_collect.h"
28 #endif
29 #include "device_param_collect.h"
30 #include "memory_guard.h"
31 #include "sam_log.h"
32 #include "system_ability_manager.h"
33 
34 namespace OHOS {
35 namespace {
36 constexpr int32_t TO_MILLISECOND = 1000;
37 }
Init(const std::list<SaProfile> & saProfiles)38 void DeviceStatusCollectManager::Init(const std::list<SaProfile>& saProfiles)
39 {
40     HILOGI("DeviceStaMgr Init begin");
41     FilterOnDemandSaProfiles(saProfiles);
42     collectHandler_ = std::make_shared<FFRTHandler>("collect");
43     sptr<ICollectPlugin> deviceParamCollect = new DeviceParamCollect(this);
44     deviceParamCollect->Init(saProfiles);
45     collectPluginMap_[PARAM] = deviceParamCollect;
46 #ifdef SUPPORT_DEVICE_MANAGER
47     sptr<ICollectPlugin> networkingCollect = new DeviceNetworkingCollect(this);
48     collectPluginMap_[DEVICE_ONLINE] = networkingCollect;
49 #endif
50 #ifdef SUPPORT_COMMON_EVENT
51     sptr<ICollectPlugin> eventStatuscollect = new CommonEventCollect(this);
52     eventStatuscollect->Init(onDemandSaProfiles_);
53     collectPluginMap_[COMMON_EVENT] = eventStatuscollect;
54 #endif
55 #ifdef SUPPORT_SWITCH_COLLECT
56     sptr<ICollectPlugin> deviceSwitchCollect = new DeviceSwitchCollect(this);
57     deviceSwitchCollect->Init(saProfiles);
58     collectPluginMap_[SETTING_SWITCH] = deviceSwitchCollect;
59 #endif
60     sptr<ICollectPlugin> timedCollect = new DeviceTimedCollect(this);
61     timedCollect->Init(onDemandSaProfiles_);
62     collectPluginMap_[TIMED_EVENT] = timedCollect;
63     StartCollect();
64     HILOGI("DeviceStaMgr Init end");
65 }
66 
RemoveWhiteCommonEvent()67 void DeviceStatusCollectManager::RemoveWhiteCommonEvent()
68 {
69     if (IsExistInPluginMap(COMMON_EVENT) == ERR_OK) {
70         collectPluginMap_[COMMON_EVENT]->RemoveWhiteCommonEvent();
71     }
72 }
73 
FilterOnDemandSaProfiles(const std::list<SaProfile> & saProfiles)74 void DeviceStatusCollectManager::FilterOnDemandSaProfiles(const std::list<SaProfile>& saProfiles)
75 {
76     std::unique_lock<std::shared_mutex> writeLock(saProfilesLock_);
77     for (auto& saProfile : saProfiles) {
78         if (saProfile.startOnDemand.onDemandEvents.empty() && saProfile.stopOnDemand.onDemandEvents.empty()) {
79             continue;
80         }
81         onDemandSaProfiles_.emplace_back(saProfile);
82     }
83 }
84 
GetSaControlListByPersistEvent(const OnDemandEvent & event,std::list<SaControlInfo> & saControlList)85 void DeviceStatusCollectManager::GetSaControlListByPersistEvent(const OnDemandEvent& event,
86     std::list<SaControlInfo>& saControlList)
87 {
88 #ifdef PREFERENCES_ENABLE
89     std::shared_ptr<PreferencesUtil> preferencesUtil = PreferencesUtil::GetInstance();
90     if (preferencesUtil == nullptr) {
91         HILOGW("GetSaControlListByPersistEvent preferencesUtil is nullptr");
92         return;
93     }
94     std::string value = preferencesUtil->ObtainString(event.ToString(), std::string());
95     if (value == std::string()) {
96         return;
97     }
98     std::vector<std::string> strVector;
99     SplitStr(value, "+", strVector);
100     size_t vectorSize = strVector.size();
101     for (size_t i = 0; i < vectorSize; i++) {
102         OnDemandPolicyType type = OnDemandPolicyType::START_POLICY;
103         int32_t systemAbilityId = -1;
104         HILOGD("vector is : %{public}s", strVector[i].c_str());
105         StringToTypeAndSaid(strVector[i], type, systemAbilityId);
106         SaControlInfo control;
107         if (type == OnDemandPolicyType::START_POLICY) {
108             control = {START_ON_DEMAND, systemAbilityId };
109         } else {
110             control = {STOP_ON_DEMAND, systemAbilityId };
111         }
112         saControlList.emplace_back(control);
113     }
114 #endif
115 }
116 
GetSaControlListByEvent(const OnDemandEvent & event,std::list<SaControlInfo> & saControlList)117 void DeviceStatusCollectManager::GetSaControlListByEvent(const OnDemandEvent& event,
118     std::list<SaControlInfo>& saControlList)
119 {
120     std::shared_lock<std::shared_mutex> readLock(saProfilesLock_);
121     for (auto& profile : onDemandSaProfiles_) {
122         // start on demand
123         for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
124             iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
125             if (IsSameEvent(event, *iterStart) && CheckConditions(*iterStart) &&
126                 CheckExtraMessages(event, *iterStart)) {
127                 // maybe the process is being killed, let samgr make decisions.
128                 SaControlInfo control = { START_ON_DEMAND, profile.saId, iterStart->enableOnce,
129                     iterStart->loadPriority, profile.cacheCommonEvent };
130                 saControlList.emplace_back(control);
131                 break;
132             }
133         }
134         // stop on demand
135         for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
136             iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
137             if (IsSameEvent(event, *iterStop) && CheckConditions(*iterStop) &&
138                 CheckExtraMessages(event, *iterStop)) {
139                 // maybe the process is starting, let samgr make decisions.
140                 SaControlInfo control = { STOP_ON_DEMAND, profile.saId, iterStop->enableOnce,
141                     iterStop->loadPriority, profile.cacheCommonEvent };
142                 saControlList.emplace_back(control);
143                 break;
144             }
145         }
146     }
147     HILOGD("DeviceStaMgr saControlList size %{public}zu", saControlList.size());
148 }
149 
SortSaControlListByLoadPriority(std::list<SaControlInfo> & saControlList)150 void DeviceStatusCollectManager::SortSaControlListByLoadPriority(std::list<SaControlInfo>& saControlList)
151 {
152     saControlList.sort([](const SaControlInfo& control1, const SaControlInfo& control2) {
153         return control1.loadPriority < control2.loadPriority;
154     });
155 }
156 
IsSameEvent(const OnDemandEvent & ev1,const OnDemandEvent & ev2)157 bool DeviceStatusCollectManager::IsSameEvent(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
158 {
159     return (ev1.eventId == ev2.eventId && ev1.name == ev2.name &&
160         ev1.persistence == ev2.persistence && (ev1.value == ev2.value || "" == ev2.value));
161 }
162 
IsSameEventName(const OnDemandEvent & ev1,const OnDemandEvent & ev2)163 bool DeviceStatusCollectManager::IsSameEventName(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
164 {
165     if (ev1.eventId != TIMED_EVENT) {
166         if (ev1.eventId == ev2.eventId && ev1.name == ev2.name) {
167             return true;
168         }
169     } else {
170         if (ev1.eventId == ev2.eventId && ev1.name == ev2.name && ev1.value == ev2.value &&
171             ev1.persistence == ev2.persistence) {
172             return true;
173         }
174     }
175     return false;
176 }
177 
CheckConditions(const OnDemandEvent & onDemandEvent)178 bool DeviceStatusCollectManager::CheckConditions(const OnDemandEvent& onDemandEvent)
179 {
180     if (onDemandEvent.conditions.empty()) {
181         return true;
182     }
183     for (auto& condition : onDemandEvent.conditions) {
184         if (collectPluginMap_.count(condition.eventId) == 0) {
185             HILOGE("not support condition: %{public}d", condition.eventId);
186             return false;
187         }
188         if (collectPluginMap_[condition.eventId] == nullptr) {
189             HILOGE("not support condition: %{public}d", condition.eventId);
190             return false;
191         }
192         bool ret = collectPluginMap_[condition.eventId]->CheckCondition(condition);
193         if (!ret) {
194             HILOGW("CheckCondition:%{public}s, value:%{public}s not pass",
195                 condition.name.c_str(), condition.value.c_str());
196             return false;
197         }
198     }
199     return true;
200 }
201 
CheckExtraMessages(const OnDemandEvent & ev1,const OnDemandEvent & ev2)202 bool DeviceStatusCollectManager::CheckExtraMessages(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
203 {
204     HILOGD("CheckExtraMessages begin evt1:%{public}d, evt2:%{public}d", ev1.eventId, ev2.eventId);
205     if (collectPluginMap_.count(ev1.eventId) == 0) {
206         HILOGE("not support CheckExtraMessages");
207         return false;
208     }
209     if (collectPluginMap_[ev1.eventId] == nullptr) {
210         HILOGE("CommonEventCollect is nullptr");
211         return false;
212     }
213     if (collectPluginMap_[ev1.eventId]->CheckExtraMessage(ev1.extraDataId, ev2)) {
214         return true;
215     }
216     return false;
217 }
218 
UnInit()219 void DeviceStatusCollectManager::UnInit()
220 {
221     for (auto& iter : collectPluginMap_) {
222         if (iter.second != nullptr) {
223             iter.second->OnStop();
224         }
225     }
226     collectPluginMap_.clear();
227 
228     if (collectHandler_ != nullptr) {
229         collectHandler_ = nullptr;
230     }
231 }
232 
CleanFfrt()233 void DeviceStatusCollectManager::CleanFfrt()
234 {
235     for (auto& iter : collectPluginMap_) {
236         if ((iter.first == DEVICE_ONLINE || iter.first == COMMON_EVENT) && (iter.second != nullptr)) {
237             iter.second->CleanFfrt();
238         }
239     }
240     if (collectHandler_ != nullptr) {
241         collectHandler_->CleanFfrt();
242     }
243 }
244 
SetFfrt()245 void DeviceStatusCollectManager::SetFfrt()
246 {
247     for (auto& iter : collectPluginMap_) {
248         if ((iter.first == DEVICE_ONLINE || iter.first == COMMON_EVENT) && (iter.second != nullptr)) {
249             iter.second->SetFfrt();
250         }
251     }
252     if (collectHandler_ != nullptr) {
253         collectHandler_->SetFfrt("collect");
254     }
255 }
256 
StartCollect()257 void DeviceStatusCollectManager::StartCollect()
258 {
259     HILOGI("DeviceStaMgr OnStart begin");
260     if (collectHandler_ == nullptr) {
261         return;
262     }
263     auto callback = [this] () {
264         for (auto& iter : collectPluginMap_) {
265             iter.second->OnStart();
266         }
267     };
268     collectHandler_->PostTask(callback);
269 }
270 
ReportEvent(const OnDemandEvent & event)271 void DeviceStatusCollectManager::ReportEvent(const OnDemandEvent& event)
272 {
273     if (collectHandler_ == nullptr) {
274         HILOGW("DeviceStaMgr collectHandler_ is nullptr");
275         return;
276     }
277     auto callback = [event, this] () {
278         std::list<SaControlInfo> saControlList;
279         GetSaControlListByEvent(event, saControlList);
280         GetSaControlListByPersistEvent(event, saControlList);
281         SortSaControlListByLoadPriority(saControlList);
282         if (saControlList.empty()) {
283             HILOGD("DeviceStaMgr no matched event");
284             if (event.eventId == DEVICE_ONLINE) {
285                 HILOGI("deviceOnline is empty");
286             }
287             return;
288         }
289         SystemAbilityManager::GetInstance()->ProcessOnDemandEvent(event, saControlList);
290     };
291     collectHandler_->PostTask(callback);
292 }
293 
PostDelayTask(std::function<void ()> callback,int32_t delayTime)294 void DeviceStatusCollectManager::PostDelayTask(std::function<void()> callback, int32_t delayTime)
295 {
296     HILOGI("DeviceStaMgr PostDelayTask begin");
297     if (delayTime < 0 || delayTime > std::numeric_limits<int32_t>::max() / TO_MILLISECOND) {
298         HILOGE("DeviceStaMgr PostDelayTask Failed : delayTime out of range %{public}d", delayTime);
299         return;
300     }
301     collectHandler_->PostTask(callback, delayTime * TO_MILLISECOND);
302 }
303 
IsExistInPluginMap(int32_t eventId)304 int32_t DeviceStatusCollectManager::IsExistInPluginMap(int32_t eventId)
305 {
306     if (collectPluginMap_.count(eventId) == 0) {
307         HILOGE("eventid:%{public}d collect not exist", eventId);
308         return ERR_INVALID_VALUE;
309     }
310     if (collectPluginMap_[eventId] == nullptr) {
311         HILOGE("eventid:%{public}d collect is null", eventId);
312         return ERR_INVALID_VALUE;
313     }
314     return ERR_OK;
315 }
316 
GetOnDemandReasonExtraData(int64_t extraDataId,OnDemandReasonExtraData & extraData)317 int32_t DeviceStatusCollectManager::GetOnDemandReasonExtraData(int64_t extraDataId, OnDemandReasonExtraData& extraData)
318 {
319     HILOGD("DeviceStaMgr GetOnDemandReasonExtraData begin, extraDataId:%{public}d",
320         static_cast<int32_t>(extraDataId));
321     if (IsExistInPluginMap(COMMON_EVENT) != ERR_OK) {
322         HILOGE("not support get extra data");
323         return ERR_INVALID_VALUE;
324     }
325     if (!collectPluginMap_[COMMON_EVENT]->GetOnDemandReasonExtraData(extraDataId, extraData)) {
326         HILOGE("get extra data failed");
327         return ERR_INVALID_VALUE;
328     }
329     return ERR_OK;
330 }
331 
SaveSaExtraDataId(int32_t saId,int64_t extraDataId)332 void DeviceStatusCollectManager::SaveSaExtraDataId(int32_t saId, int64_t extraDataId)
333 {
334     HILOGD("DeviceStaMgr SaveSaExtraDataId begin, SA:%{public}d, extraDataId:%{public}d",
335         saId, static_cast<int32_t>(extraDataId));
336     if (IsExistInPluginMap(COMMON_EVENT) != ERR_OK) {
337         HILOGE("CommonEventCollect is nullptr");
338         return;
339     }
340     collectPluginMap_[COMMON_EVENT]->SaveSaExtraDataId(saId, extraDataId);
341     return;
342 }
343 
ClearSaExtraDataId(int32_t saId)344 void DeviceStatusCollectManager::ClearSaExtraDataId(int32_t saId)
345 {
346     HILOGD("DeviceStaMgr ClearSaExtraDataId begin, SA:%{public}d", saId);
347     if (IsExistInPluginMap(COMMON_EVENT) != ERR_OK) {
348         HILOGE("CommonEventCollect is nullptr");
349         return;
350     }
351     collectPluginMap_[COMMON_EVENT]->ClearSaExtraDataId(saId);
352     return;
353 }
354 
SaveCacheCommonEventSaExtraId(const OnDemandEvent & event,const std::list<SaControlInfo> & saControlList)355 void DeviceStatusCollectManager::SaveCacheCommonEventSaExtraId(const OnDemandEvent& event,
356     const std::list<SaControlInfo>& saControlList)
357 {
358     HILOGD("DeviceStaMgr SaveCacheCommonEventSaExtraId begin");
359     if (IsExistInPluginMap(COMMON_EVENT) != ERR_OK) {
360         HILOGE("CommonEventCollect is nullptr");
361         return;
362     }
363     collectPluginMap_[COMMON_EVENT]->SaveCacheCommonEventSaExtraId(event, saControlList);
364     return;
365 }
366 
GetSaExtraDataIdList(int32_t saId,std::vector<int64_t> & extraDataIdList,const std::string & eventName)367 int32_t DeviceStatusCollectManager::GetSaExtraDataIdList(int32_t saId, std::vector<int64_t>& extraDataIdList,
368     const std::string& eventName)
369 {
370     HILOGD("DeviceStaMgr GetSaExtraDataIdList begin, SA:%{public}d, event:%{public}s",
371         saId, eventName.c_str());
372     if (IsExistInPluginMap(COMMON_EVENT) != ERR_OK) {
373         HILOGE("CommonEventCollect is nullptr");
374         return ERR_INVALID_VALUE;
375     }
376     return collectPluginMap_[COMMON_EVENT]->GetSaExtraDataIdList(saId, extraDataIdList, eventName);
377 }
378 
AddCollectEvents(const std::vector<OnDemandEvent> & events)379 int32_t DeviceStatusCollectManager::AddCollectEvents(const std::vector<OnDemandEvent>& events)
380 {
381     if (events.size() == 0) {
382         return ERR_OK;
383     }
384     for (auto& event : events) {
385         if (collectPluginMap_.count(event.eventId) == 0) {
386             HILOGE("not support eventId: %{public}d", event.eventId);
387             return ERR_INVALID_VALUE;
388         }
389         if (collectPluginMap_[event.eventId] == nullptr) {
390             HILOGE("not support eventId: %{public}d", event.eventId);
391             return ERR_INVALID_VALUE;
392         }
393         int32_t ret = collectPluginMap_[event.eventId]->AddCollectEvent(event);
394         if (ret != ERR_OK) {
395             HILOGE("add collect event failed, eventId: %{public}d", event.eventId);
396             return ret;
397         }
398     }
399     return ERR_OK;
400 }
401 
GetOnDemandEvents(int32_t systemAbilityId,OnDemandPolicyType type,std::vector<OnDemandEvent> & events)402 int32_t DeviceStatusCollectManager::GetOnDemandEvents(int32_t systemAbilityId, OnDemandPolicyType type,
403     std::vector<OnDemandEvent>& events)
404 {
405     HILOGI("GetOnDemandEvents begin");
406     std::shared_lock<std::shared_mutex> readLock(saProfilesLock_);
407     auto iter = std::find_if(onDemandSaProfiles_.begin(), onDemandSaProfiles_.end(), [systemAbilityId](auto saProfile) {
408         return saProfile.saId == systemAbilityId;
409     });
410     if (iter == onDemandSaProfiles_.end()) {
411         HILOGI("GetOnDemandEvents invalid saId:%{public}d", systemAbilityId);
412         return ERR_INVALID_VALUE;
413     }
414     if (type == OnDemandPolicyType::START_POLICY) {
415         events = (*iter).startOnDemand.onDemandEvents;
416     } else if (type == OnDemandPolicyType::STOP_POLICY) {
417         events = (*iter).stopOnDemand.onDemandEvents;
418     } else {
419         HILOGE("GetOnDemandEvents invalid policy types");
420         return ERR_INVALID_VALUE;
421     }
422     return ERR_OK;
423 }
424 
RemoveUnusedEventsLocked(const std::vector<OnDemandEvent> & events)425 int32_t DeviceStatusCollectManager::RemoveUnusedEventsLocked(const std::vector<OnDemandEvent>& events)
426 {
427     HILOGD("RemoveUnusedEventsLocked start");
428     if (events.size() == 0) {
429         return ERR_OK;
430     }
431     for (auto& event : events) {
432         if (collectPluginMap_.count(event.eventId) == 0) {
433             HILOGE("not support eventId: %{public}d", event.eventId);
434             continue;
435         }
436         if (collectPluginMap_[event.eventId] == nullptr) {
437             HILOGE("not support eventId: %{public}d", event.eventId);
438             continue;
439         }
440         bool eventUsed = CheckEventUsedLocked(event);
441         if (!eventUsed) {
442             HILOGI("CheckEventUsedLocked name:%{public}s,value:%{public}s", event.name.c_str(), event.value.c_str());
443             int32_t ret = collectPluginMap_[event.eventId]->RemoveUnusedEvent(event);
444             if (ret != ERR_OK) {
445                 HILOGE("Remove event failed, eventId: %{public}d", event.eventId);
446             }
447         }
448     }
449     return ERR_OK;
450 }
451 
CheckEventUsedLocked(const OnDemandEvent & event)452 bool DeviceStatusCollectManager::CheckEventUsedLocked(const OnDemandEvent& event)
453 {
454     for (auto& profile : onDemandSaProfiles_) {
455         // start on demand
456         for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
457             iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
458             if (IsSameEventName(event, *iterStart)) {
459                 return true;
460             }
461         }
462         // stop on demand
463         for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
464             iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
465             if (IsSameEventName(event, *iterStop)) {
466                 return true;
467             }
468         }
469     }
470     return false;
471 }
472 
NeedPersistOnDemandEvent(const OnDemandEvent & event)473 bool DeviceStatusCollectManager::NeedPersistOnDemandEvent(const OnDemandEvent& event)
474 {
475     if (event.eventId == TIMED_EVENT && event.name == "timedevent" && event.persistence) {
476         return true;
477     }
478     return false;
479 }
480 
PersistOnDemandEvent(int32_t systemAbilityId,OnDemandPolicyType type,const std::vector<OnDemandEvent> & events)481 void DeviceStatusCollectManager::PersistOnDemandEvent(int32_t systemAbilityId, OnDemandPolicyType type,
482     const std::vector<OnDemandEvent>& events)
483 {
484 #ifdef PREFERENCES_ENABLE
485     std::shared_ptr<PreferencesUtil> preferencesUtil = PreferencesUtil::GetInstance();
486     if (preferencesUtil == nullptr) {
487         return;
488     }
489     for (OnDemandEvent event : events) {
490         if (!NeedPersistOnDemandEvent(event)) {
491             continue;
492         }
493         std::string strEvent = event.ToString();
494         std::string strTypeAndSaid = TypeAndSaidToString(type, systemAbilityId);
495         if (preferencesUtil->IsExist(strEvent)) {
496             std::string orgStrTypeAndSaid = preferencesUtil->ObtainString(strEvent, "");
497             orgStrTypeAndSaid += "+";
498             orgStrTypeAndSaid += strTypeAndSaid;
499             HILOGI("PersistOnDemandEvent Save orgStrTypeAndSaid is : %{public}s", orgStrTypeAndSaid.c_str());
500             preferencesUtil->SaveString(strEvent, orgStrTypeAndSaid);
501         } else {
502             preferencesUtil->SaveString(strEvent, strTypeAndSaid);
503             HILOGI("PersistOnDemandEvent Save strTypeAndSaid is : %{public}s", strTypeAndSaid.c_str());
504         }
505     }
506 #endif
507 }
508 
TypeAndSaidToString(OnDemandPolicyType type,int32_t systemAbilityId)509 std::string DeviceStatusCollectManager::TypeAndSaidToString(OnDemandPolicyType type, int32_t systemAbilityId)
510 {
511     std::string strSaid = std::to_string(systemAbilityId);
512     if (type == OnDemandPolicyType::START_POLICY) {
513         return "start#" + strSaid + "#";
514     } else if (type == OnDemandPolicyType::STOP_POLICY) {
515         return "stop#" + strSaid + "#";
516     }
517     return "";
518 }
519 
StringToTypeAndSaid(const std::string & eventStr,OnDemandPolicyType & type,int32_t & systemAbilityId)520 void DeviceStatusCollectManager::StringToTypeAndSaid(const std::string& eventStr, OnDemandPolicyType& type,
521     int32_t& systemAbilityId)
522 {
523     std::size_t pos = eventStr.find("#");
524     std::string strType = eventStr.substr(0, pos);
525     if (strType == "start") {
526         type = OnDemandPolicyType::START_POLICY;
527     } else if (strType == "stop") {
528         type = OnDemandPolicyType::STOP_POLICY;
529     } else {
530         HILOGW("StringToTypeAndSaid failed");
531         return;
532     }
533     if (pos == string::npos) {
534         HILOGW("StringToSaid failed");
535         return;
536     }
537     systemAbilityId = atoi((eventStr.substr(pos + 1, eventStr.size() - pos - 1)).c_str());
538     HILOGD("systemAbilityId is : %{public}d", systemAbilityId);
539 }
540 
UpdateOnDemandEvents(int32_t systemAbilityId,OnDemandPolicyType type,const std::vector<OnDemandEvent> & events)541 int32_t DeviceStatusCollectManager::UpdateOnDemandEvents(int32_t systemAbilityId, OnDemandPolicyType type,
542     const std::vector<OnDemandEvent>& events)
543 {
544     HILOGI("UpdateOnDemandEvents begin saId:%{public}d, type:%{public}d", systemAbilityId, type);
545     std::vector<OnDemandEvent> oldEvents;
546     std::unique_lock<std::shared_mutex> writeLock(saProfilesLock_);
547     auto iter = std::find_if(onDemandSaProfiles_.begin(), onDemandSaProfiles_.end(),
548     [systemAbilityId](auto saProfile) {
549         return saProfile.saId == systemAbilityId;
550     });
551     if (iter == onDemandSaProfiles_.end()) {
552         HILOGI("UpdateOnDemandEvents invalid saId:%{public}d", systemAbilityId);
553         return ERR_INVALID_VALUE;
554     }
555     if (AddCollectEvents(events) != ERR_OK) {
556         HILOGI("AddCollectEvents failed saId:%{public}d", systemAbilityId);
557         return ERR_INVALID_VALUE;
558     }
559     if (type == OnDemandPolicyType::START_POLICY) {
560         oldEvents = (*iter).startOnDemand.onDemandEvents;
561         (*iter).startOnDemand.onDemandEvents = events;
562     } else if (type == OnDemandPolicyType::STOP_POLICY) {
563         oldEvents = (*iter).stopOnDemand.onDemandEvents;
564         (*iter).stopOnDemand.onDemandEvents = events;
565     } else {
566         HILOGE("UpdateOnDemandEvents policy types");
567         return ERR_INVALID_VALUE;
568     }
569     PersistOnDemandEvent(systemAbilityId, type, events);
570     if (RemoveUnusedEventsLocked(oldEvents) != ERR_OK) {
571         HILOGE("RemoveUnusedEventsLocked failed saId:%{public}d", systemAbilityId);
572     }
573     return ERR_OK;
574 }
575 }  // namespace OHOS
576