• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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("DeviceStatusCollectManager 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("DeviceStatusCollectManager Init end");
65 }
66 
FilterOnDemandSaProfiles(const std::list<SaProfile> & saProfiles)67 void DeviceStatusCollectManager::FilterOnDemandSaProfiles(const std::list<SaProfile>& saProfiles)
68 {
69     std::unique_lock<std::shared_mutex> writeLock(saProfilesLock_);
70     for (auto& saProfile : saProfiles) {
71         if (saProfile.startOnDemand.onDemandEvents.empty() && saProfile.stopOnDemand.onDemandEvents.empty()) {
72             continue;
73         }
74         onDemandSaProfiles_.emplace_back(saProfile);
75     }
76 }
77 
GetSaControlListByPersistEvent(const OnDemandEvent & event,std::list<SaControlInfo> & saControlList)78 void DeviceStatusCollectManager::GetSaControlListByPersistEvent(const OnDemandEvent& event,
79     std::list<SaControlInfo>& saControlList)
80 {
81 #ifdef PREFERENCES_ENABLE
82     std::shared_ptr<PreferencesUtil> preferencesUtil = PreferencesUtil::GetInstance();
83     if (preferencesUtil == nullptr) {
84         HILOGW("GetSaControlListByPersistEvent preferencesUtil is nullptr");
85         return;
86     }
87     std::string value = preferencesUtil->ObtainString(event.ToString(), std::string());
88     if (value == std::string()) {
89         return;
90     }
91     std::vector<std::string> strVector;
92     SplitStr(value, "+", strVector);
93     size_t vectorSize = strVector.size();
94     for (size_t i = 0; i < vectorSize; i++) {
95         OnDemandPolicyType type;
96         int32_t systemAbilityId = -1;
97         HILOGD("vector is : %{public}s", strVector[i].c_str());
98         StringToTypeAndSaid(strVector[i], type, systemAbilityId);
99         SaControlInfo control;
100         if (type == OnDemandPolicyType::START_POLICY) {
101             control = {START_ON_DEMAND, systemAbilityId };
102         } else {
103             control = {STOP_ON_DEMAND, systemAbilityId };
104         }
105         saControlList.emplace_back(control);
106     }
107 #endif
108 }
109 
GetSaControlListByEvent(const OnDemandEvent & event,std::list<SaControlInfo> & saControlList)110 void DeviceStatusCollectManager::GetSaControlListByEvent(const OnDemandEvent& event,
111     std::list<SaControlInfo>& saControlList)
112 {
113     std::shared_lock<std::shared_mutex> readLock(saProfilesLock_);
114     for (auto& profile : onDemandSaProfiles_) {
115         // start on demand
116         for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
117             iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
118             if (IsSameEvent(event, *iterStart) && CheckConditions(*iterStart) &&
119                 CheckExtraMessages(event, *iterStart)) {
120                 // maybe the process is being killed, let samgr make decisions.
121                 SaControlInfo control = { START_ON_DEMAND, profile.saId, iterStart->enableOnce,
122                     iterStart->loadPriority };
123                 saControlList.emplace_back(control);
124                 break;
125             }
126         }
127         // stop on demand
128         for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
129             iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
130             if (IsSameEvent(event, *iterStop) && CheckConditions(*iterStop) &&
131                 CheckExtraMessages(event, *iterStop)) {
132                 // maybe the process is starting, let samgr make decisions.
133                 SaControlInfo control = { STOP_ON_DEMAND, profile.saId, iterStop->enableOnce,
134                     iterStop->loadPriority };
135                 saControlList.emplace_back(control);
136                 break;
137             }
138         }
139     }
140     HILOGD("DeviceStatusCollectManager saControlList size %{public}zu", saControlList.size());
141 }
142 
SortSaControlListByLoadPriority(std::list<SaControlInfo> & saControlList)143 void DeviceStatusCollectManager::SortSaControlListByLoadPriority(std::list<SaControlInfo>& saControlList)
144 {
145     saControlList.sort([](const SaControlInfo& control1, const SaControlInfo& control2) {
146         return control1.loadPriority < control2.loadPriority;
147     });
148 }
149 
IsSameEvent(const OnDemandEvent & ev1,const OnDemandEvent & ev2)150 bool DeviceStatusCollectManager::IsSameEvent(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
151 {
152     return (ev1.eventId == ev2.eventId && ev1.name == ev2.name &&
153         ev1.persistence == ev2.persistence && (ev1.value == ev2.value || "" == ev2.value));
154 }
155 
IsSameEventName(const OnDemandEvent & ev1,const OnDemandEvent & ev2)156 bool DeviceStatusCollectManager::IsSameEventName(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
157 {
158     if (ev1.eventId != TIMED_EVENT) {
159         if (ev1.eventId == ev2.eventId && ev1.name == ev2.name) {
160             return true;
161         }
162     } else {
163         if (ev1.eventId == ev2.eventId && ev1.name == ev2.name && ev1.value == ev2.value &&
164             ev1.persistence == ev2.persistence) {
165             return true;
166         }
167     }
168     return false;
169 }
170 
CheckConditions(const OnDemandEvent & onDemandEvent)171 bool DeviceStatusCollectManager::CheckConditions(const OnDemandEvent& onDemandEvent)
172 {
173     if (onDemandEvent.conditions.empty()) {
174         return true;
175     }
176     for (auto& condition : onDemandEvent.conditions) {
177         if (collectPluginMap_.count(condition.eventId) == 0) {
178             HILOGE("not support condition: %{public}d", condition.eventId);
179             return false;
180         }
181         if (collectPluginMap_[condition.eventId] == nullptr) {
182             HILOGE("not support condition: %{public}d", condition.eventId);
183             return false;
184         }
185         bool ret = collectPluginMap_[condition.eventId]->CheckCondition(condition);
186         if (!ret) {
187             HILOGW("CheckCondition condition: %{public}s, value: %{public}s not pass",
188                 condition.name.c_str(), condition.value.c_str());
189             return false;
190         }
191     }
192     return true;
193 }
194 
CheckExtraMessages(const OnDemandEvent & ev1,const OnDemandEvent & ev2)195 bool DeviceStatusCollectManager::CheckExtraMessages(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
196 {
197     HILOGD("CheckExtraMessages begin evt1:%{public}d, evt2:%{public}d", ev1.eventId, ev2.eventId);
198     if (collectPluginMap_.count(ev1.eventId) == 0) {
199         HILOGE("not support CheckExtraMessages");
200         return false;
201     }
202     if (collectPluginMap_[ev1.eventId] == nullptr) {
203         HILOGE("CommonEventCollect is nullptr");
204         return false;
205     }
206     if (collectPluginMap_[ev1.eventId]->CheckExtraMessage(ev1.extraDataId, ev2)) {
207         return true;
208     }
209     return false;
210 }
211 
UnInit()212 void DeviceStatusCollectManager::UnInit()
213 {
214     for (auto& iter : collectPluginMap_) {
215         if (iter.second != nullptr) {
216             iter.second->OnStop();
217         }
218     }
219     collectPluginMap_.clear();
220 
221     if (collectHandler_ != nullptr) {
222         collectHandler_ = nullptr;
223     }
224 }
225 
CleanFfrt()226 void DeviceStatusCollectManager::CleanFfrt()
227 {
228     for (auto& iter : collectPluginMap_) {
229         if (iter.first == DEVICE_ONLINE || iter.first == COMMON_EVENT) {
230             iter.second->CleanFfrt();
231         }
232     }
233     if (collectHandler_ != nullptr) {
234         collectHandler_->CleanFfrt();
235     }
236 }
237 
SetFfrt()238 void DeviceStatusCollectManager::SetFfrt()
239 {
240     for (auto& iter : collectPluginMap_) {
241         if (iter.first == DEVICE_ONLINE || iter.first == COMMON_EVENT) {
242             iter.second->SetFfrt();
243         }
244     }
245     if (collectHandler_ != nullptr) {
246         collectHandler_->SetFfrt("collect");
247     }
248 }
249 
StartCollect()250 void DeviceStatusCollectManager::StartCollect()
251 {
252     HILOGI("DeviceStatusCollectManager OnStart begin");
253     if (collectHandler_ == nullptr) {
254         return;
255     }
256     auto callback = [this] () {
257         for (auto& iter : collectPluginMap_) {
258             iter.second->OnStart();
259         }
260     };
261     collectHandler_->PostTask(callback);
262 }
263 
ReportEvent(const OnDemandEvent & event)264 void DeviceStatusCollectManager::ReportEvent(const OnDemandEvent& event)
265 {
266     if (collectHandler_ == nullptr) {
267         HILOGW("DeviceStatusCollectManager collectHandler_ is nullptr");
268         return;
269     }
270     std::list<SaControlInfo> saControlList;
271     GetSaControlListByEvent(event, saControlList);
272     GetSaControlListByPersistEvent(event, saControlList);
273     SortSaControlListByLoadPriority(saControlList);
274     if (saControlList.empty()) {
275         HILOGD("DeviceStatusCollectManager no matched event");
276         return;
277     }
278     auto callback = [event, saControlList = std::move(saControlList)] () {
279         SystemAbilityManager::GetInstance()->ProcessOnDemandEvent(event, saControlList);
280     };
281     collectHandler_->PostTask(callback);
282 }
283 
PostDelayTask(std::function<void ()> callback,int32_t delayTime)284 void DeviceStatusCollectManager::PostDelayTask(std::function<void()> callback, int32_t delayTime)
285 {
286     HILOGI("DeviceStatusCollectManager PostDelayTask begin");
287     if (delayTime < 0 || delayTime > std::numeric_limits<int32_t>::max() / TO_MILLISECOND) {
288         HILOGE("DeviceStatusCollectManager PostDelayTask Failed : delayTime out of range %{public}d", delayTime);
289         return;
290     }
291     collectHandler_->PostTask(callback, delayTime * TO_MILLISECOND);
292 }
293 
GetOnDemandReasonExtraData(int64_t extraDataId,OnDemandReasonExtraData & extraData)294 int32_t DeviceStatusCollectManager::GetOnDemandReasonExtraData(int64_t extraDataId, OnDemandReasonExtraData& extraData)
295 {
296     HILOGD("DeviceStatusCollectManager GetOnDemandReasonExtraData begin, extraDataId:%{public}d",
297         static_cast<int32_t>(extraDataId));
298     if (collectPluginMap_.count(COMMON_EVENT) == 0) {
299         HILOGE("not support get extra data");
300         return ERR_INVALID_VALUE;
301     }
302     if (collectPluginMap_[COMMON_EVENT] == nullptr) {
303         HILOGE("CommonEventCollect is nullptr");
304         return ERR_INVALID_VALUE;
305     }
306     if (!collectPluginMap_[COMMON_EVENT]->GetOnDemandReasonExtraData(extraDataId, extraData)) {
307         HILOGE("get extra data failed");
308         return ERR_INVALID_VALUE;
309     }
310     return ERR_OK;
311 }
312 
AddCollectEvents(const std::vector<OnDemandEvent> & events)313 int32_t DeviceStatusCollectManager::AddCollectEvents(const std::vector<OnDemandEvent>& events)
314 {
315     if (events.size() == 0) {
316         return ERR_OK;
317     }
318     for (auto& event : events) {
319         if (collectPluginMap_.count(event.eventId) == 0) {
320             HILOGE("not support eventId: %{public}d", event.eventId);
321             return ERR_INVALID_VALUE;
322         }
323         if (collectPluginMap_[event.eventId] == nullptr) {
324             HILOGE("not support eventId: %{public}d", event.eventId);
325             return ERR_INVALID_VALUE;
326         }
327         int32_t ret = collectPluginMap_[event.eventId]->AddCollectEvent(event);
328         if (ret != ERR_OK) {
329             HILOGE("add collect event failed, eventId: %{public}d", event.eventId);
330             return ret;
331         }
332     }
333     return ERR_OK;
334 }
335 
GetOnDemandEvents(int32_t systemAbilityId,OnDemandPolicyType type,std::vector<OnDemandEvent> & events)336 int32_t DeviceStatusCollectManager::GetOnDemandEvents(int32_t systemAbilityId, OnDemandPolicyType type,
337     std::vector<OnDemandEvent>& events)
338 {
339     HILOGI("DeviceStatusCollectManager GetOnDemandEvents begin");
340     std::shared_lock<std::shared_mutex> readLock(saProfilesLock_);
341     auto iter = std::find_if(onDemandSaProfiles_.begin(), onDemandSaProfiles_.end(), [systemAbilityId](auto saProfile) {
342         return saProfile.saId == systemAbilityId;
343     });
344     if (iter == onDemandSaProfiles_.end()) {
345         HILOGI("DeviceStatusCollectManager GetOnDemandEvents invalid saId:%{public}d", systemAbilityId);
346         return ERR_INVALID_VALUE;
347     }
348     if (type == OnDemandPolicyType::START_POLICY) {
349         events = (*iter).startOnDemand.onDemandEvents;
350     } else if (type == OnDemandPolicyType::STOP_POLICY) {
351         events = (*iter).stopOnDemand.onDemandEvents;
352     } else {
353         HILOGE("DeviceStatusCollectManager GetOnDemandEvents invalid policy types");
354         return ERR_INVALID_VALUE;
355     }
356     return ERR_OK;
357 }
358 
RemoveUnusedEventsLocked(const std::vector<OnDemandEvent> & events)359 int32_t DeviceStatusCollectManager::RemoveUnusedEventsLocked(const std::vector<OnDemandEvent>& events)
360 {
361     HILOGD("DeviceStatusCollectManager RemoveUnusedEventsLocked start");
362     if (events.size() == 0) {
363         return ERR_OK;
364     }
365     for (auto& event : events) {
366         if (collectPluginMap_.count(event.eventId) == 0) {
367             HILOGE("not support eventId: %{public}d", event.eventId);
368             continue;
369         }
370         if (collectPluginMap_[event.eventId] == nullptr) {
371             HILOGE("not support eventId: %{public}d", event.eventId);
372             continue;
373         }
374         bool eventUsed = CheckEventUsedLocked(event);
375         if (!eventUsed) {
376             HILOGI("DeviceStatusCollectManager CheckEventUsedLocked name: %{public}s", event.name.c_str());
377             int32_t ret = collectPluginMap_[event.eventId]->RemoveUnusedEvent(event);
378             if (ret != ERR_OK) {
379                 HILOGE("Remove event failed, eventId: %{public}d", event.eventId);
380             }
381         }
382     }
383     return ERR_OK;
384 }
385 
CheckEventUsedLocked(const OnDemandEvent & event)386 bool DeviceStatusCollectManager::CheckEventUsedLocked(const OnDemandEvent& event)
387 {
388     for (auto& profile : onDemandSaProfiles_) {
389         // start on demand
390         for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
391             iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
392             if (IsSameEventName(event, *iterStart)) {
393                 return true;
394             }
395         }
396         // stop on demand
397         for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
398             iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
399             if (IsSameEventName(event, *iterStop)) {
400                 return true;
401             }
402         }
403     }
404     return false;
405 }
406 
NeedPersistOnDemandEvent(const OnDemandEvent & event)407 bool DeviceStatusCollectManager::NeedPersistOnDemandEvent(const OnDemandEvent& event)
408 {
409     if (event.eventId == TIMED_EVENT && event.name == "timedevent" && event.persistence) {
410         return true;
411     }
412     return false;
413 }
414 
PersistOnDemandEvent(int32_t systemAbilityId,OnDemandPolicyType type,const std::vector<OnDemandEvent> & events)415 void DeviceStatusCollectManager::PersistOnDemandEvent(int32_t systemAbilityId, OnDemandPolicyType type,
416     const std::vector<OnDemandEvent>& events)
417 {
418 #ifdef PREFERENCES_ENABLE
419     std::shared_ptr<PreferencesUtil> preferencesUtil = PreferencesUtil::GetInstance();
420     if (preferencesUtil == nullptr) {
421         return;
422     }
423     for (OnDemandEvent event : events) {
424         if (!NeedPersistOnDemandEvent(event)) {
425             continue;
426         }
427         std::string strEvent = event.ToString();
428         std::string strTypeAndSaid = TypeAndSaidToString(type, systemAbilityId);
429         if (preferencesUtil->IsExist(strEvent)) {
430             std::string orgStrTypeAndSaid = preferencesUtil->ObtainString(strEvent, "");
431             orgStrTypeAndSaid += "+";
432             orgStrTypeAndSaid += strTypeAndSaid;
433             HILOGI("PersistOnDemandEvent Save orgStrTypeAndSaid is : %{public}s", orgStrTypeAndSaid.c_str());
434             preferencesUtil->SaveString(strEvent, orgStrTypeAndSaid);
435         } else {
436             preferencesUtil->SaveString(strEvent, strTypeAndSaid);
437             HILOGI("PersistOnDemandEvent Save strTypeAndSaid is : %{public}s", strTypeAndSaid.c_str());
438         }
439     }
440 #endif
441 }
442 
TypeAndSaidToString(OnDemandPolicyType type,int32_t systemAbilityId)443 std::string DeviceStatusCollectManager::TypeAndSaidToString(OnDemandPolicyType type, int32_t systemAbilityId)
444 {
445     std::string strSaid = std::to_string(systemAbilityId);
446     if (type == OnDemandPolicyType::START_POLICY) {
447         return "start#" + strSaid + "#";
448     } else if (type == OnDemandPolicyType::STOP_POLICY) {
449         return "stop#" + strSaid + "#";
450     }
451     return "";
452 }
453 
StringToTypeAndSaid(const std::string & eventStr,OnDemandPolicyType & type,int32_t & systemAbilityId)454 void DeviceStatusCollectManager::StringToTypeAndSaid(const std::string& eventStr, OnDemandPolicyType& type,
455     int32_t& systemAbilityId)
456 {
457     std::size_t pos = eventStr.find("#");
458     std::string strType = eventStr.substr(0, pos);
459     if (strType == "start") {
460         type = OnDemandPolicyType::START_POLICY;
461     } else if (strType == "stop") {
462         type = OnDemandPolicyType::STOP_POLICY;
463     } else {
464         HILOGW("DeviceStatusCollectManager StringToTypeAndSaid failed");
465         return;
466     }
467     systemAbilityId = atoi((eventStr.substr(pos + 1, eventStr.size() - pos - 1)).c_str());
468     HILOGD("systemAbilityId is : %{public}d", systemAbilityId);
469 }
470 
UpdateOnDemandEvents(int32_t systemAbilityId,OnDemandPolicyType type,const std::vector<OnDemandEvent> & events)471 int32_t DeviceStatusCollectManager::UpdateOnDemandEvents(int32_t systemAbilityId, OnDemandPolicyType type,
472     const std::vector<OnDemandEvent>& events)
473 {
474     HILOGI("DeviceStatusCollectManager UpdateOnDemandEvents begin");
475     std::unique_lock<std::shared_mutex> writeLock(saProfilesLock_);
476     auto iter = std::find_if(onDemandSaProfiles_.begin(), onDemandSaProfiles_.end(), [systemAbilityId](auto saProfile) {
477         return saProfile.saId == systemAbilityId;
478     });
479     if (iter == onDemandSaProfiles_.end()) {
480         HILOGI("DeviceStatusCollectManager UpdateOnDemandEvents invalid saId:%{public}d", systemAbilityId);
481         return ERR_INVALID_VALUE;
482     }
483     if (AddCollectEvents(events) != ERR_OK) {
484         HILOGI("DeviceStatusCollectManager AddCollectEvents failed saId:%{public}d", systemAbilityId);
485         return ERR_INVALID_VALUE;
486     }
487     std::vector<OnDemandEvent> oldEvents;
488     if (type == OnDemandPolicyType::START_POLICY) {
489         oldEvents = (*iter).startOnDemand.onDemandEvents;
490         (*iter).startOnDemand.onDemandEvents = events;
491     } else if (type == OnDemandPolicyType::STOP_POLICY) {
492         oldEvents = (*iter).stopOnDemand.onDemandEvents;
493         (*iter).stopOnDemand.onDemandEvents = events;
494     } else {
495         HILOGE("DeviceStatusCollectManager UpdateOnDemandEvents policy types");
496         return ERR_INVALID_VALUE;
497     }
498     PersistOnDemandEvent(systemAbilityId, type, events);
499     if (RemoveUnusedEventsLocked(oldEvents) != ERR_OK) {
500         HILOGE("DeviceStatusCollectManager RemoveUnusedEventsLocked failed saId:%{public}d", systemAbilityId);
501     }
502     return ERR_OK;
503 }
504 }  // namespace OHOS
505